Inner runner that takes the slug-verification step as a parameter. Splitting this out lets tests inject a deterministic verifier (succeed / fail) without making a real network call, so we can assert the load-bearing invariant: **when verification fails, the config file is not modified**.
(&self, verify: F)
| 89 | /// assert the load-bearing invariant: **when verification fails, the |
| 90 | /// config file is not modified**. |
| 91 | fn run_with_verifier<F>(&self, verify: F) -> CliResult<()> |
| 92 | where |
| 93 | F: FnOnce(&str) -> CliResult<()>, |
| 94 | { |
| 95 | if self.slug.is_empty() { |
| 96 | return Err(CliError::InvalidArgument { |
| 97 | message: "Organization slug cannot be empty.".to_string(), |
| 98 | }); |
| 99 | } |
| 100 | |
| 101 | // Validate against the server first so a bad slug fails fast |
| 102 | // rather than self-locking subsequent commands. The `?` here is |
| 103 | // load-bearing: if it returns Err, config is not touched. |
| 104 | if !self.no_verify { |
| 105 | verify(&self.slug)?; |
| 106 | } |
| 107 | |
| 108 | let mut config = GlobalConfig::load().map_err(|e| { |
| 109 | CliError::Internal(anyhow::anyhow!("Failed to load global config: {e}")) |
| 110 | })?; |
| 111 | |
| 112 | let previous = config.server.default_org.clone(); |
| 113 | config.server.default_org = Some(self.slug.clone()); |
| 114 | config.save().map_err(|e| { |
| 115 | CliError::Internal(anyhow::anyhow!("Failed to save global config: {e}")) |
| 116 | })?; |
| 117 | |
| 118 | print_success(&format!("Default organization set to: {}", self.slug)); |
| 119 | |
| 120 | if let Some(prev) = &previous { |
| 121 | if prev != &self.slug { |
| 122 | print_hint(&format!("Previous default was: {prev}")); |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | Ok(()) |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | /// Confirm the slug resolves to an org on the server. |
no test coverage detected