| 103 | } |
| 104 | |
| 105 | fn migrate( |
| 106 | &self, |
| 107 | content: &str, |
| 108 | from: &ConfigVersion, |
| 109 | to: &ConfigVersion, |
| 110 | resolver: &mut dyn AmbiguityResolver, |
| 111 | ) -> Result<TargetMigrationOutput, TargetError> { |
| 112 | if from > to { |
| 113 | let issue = MigrationIssue { |
| 114 | target: self.name().to_string(), |
| 115 | step_id: "future-version".to_string(), |
| 116 | message: format!( |
| 117 | "source version {} is newer than target {} (downgrade is unsupported)", |
| 118 | from, to |
| 119 | ), |
| 120 | recommended: AmbiguousChoice::Abort, |
| 121 | }; |
| 122 | return match resolver.resolve(&issue)? { |
| 123 | AmbiguousChoice::ApplyRecommended | AmbiguousChoice::Abort => { |
| 124 | Err(TargetError::DowngradeAborted { |
| 125 | from: from.clone(), |
| 126 | to: to.clone(), |
| 127 | }) |
| 128 | } |
| 129 | AmbiguousChoice::Skip => Ok(TargetMigrationOutput { |
| 130 | content: content.to_string(), |
| 131 | applied_steps: vec!["skip-future-version".to_string()], |
| 132 | warnings: vec![format!( |
| 133 | "skipped migration because source version {} is newer than target {}", |
| 134 | from, to |
| 135 | )], |
| 136 | }), |
| 137 | }; |
| 138 | } |
| 139 | |
| 140 | let detected = detect_version_from_content(content)?; |
| 141 | let mut value: toml::Value = toml::from_str(content)?; |
| 142 | let table = value |
| 143 | .as_table_mut() |
| 144 | .ok_or(TargetError::TopLevelTableExpected)?; |
| 145 | let version_step_output = |
| 146 | versions::apply_versioned_steps(self.name(), table, from, to, resolver)?; |
| 147 | let mut applied_steps = version_step_output.applied_steps; |
| 148 | let warnings = version_step_output.warnings; |
| 149 | |
| 150 | if detected.as_ref() != Some(to) { |
| 151 | table.insert("version".to_string(), toml::Value::String(to.to_string())); |
| 152 | let step = match detected { |
| 153 | Some(found) => format!("set-version:{}->{}", found, to), |
| 154 | None => format!("set-version:missing->{}", to), |
| 155 | }; |
| 156 | applied_steps.push(step); |
| 157 | } |
| 158 | |
| 159 | let migrated = toml::to_string_pretty(&value)?; |
| 160 | |
| 161 | Ok(TargetMigrationOutput { |
| 162 | content: migrated, |