| 273 | |
| 274 | #[cfg(feature = "std")] |
| 275 | pub fn save_project_config( |
| 276 | config: &ProjectConfig, |
| 277 | info: &ProjectConfigInfo, |
| 278 | ) -> Result<ProjectConfigInfo> { |
| 279 | if let Some(last_ts) = info.timestamp { |
| 280 | // Check if the file has changed since we last read it |
| 281 | if let Ok(metadata) = std::fs::metadata(&info.path) { |
| 282 | let ts = filetime::FileTime::from_last_modification_time(&metadata); |
| 283 | if ts != last_ts { |
| 284 | return Err(anyhow!("Config file has changed since last read")); |
| 285 | } |
| 286 | } |
| 287 | } |
| 288 | let mut writer = std::io::BufWriter::new( |
| 289 | std::fs::File::create(&info.path).context("Failed to create config file")?, |
| 290 | ); |
| 291 | let ext = info.path.extension().and_then(|ext| ext.to_str()).unwrap_or("json"); |
| 292 | match ext { |
| 293 | "json" => serde_json::to_writer_pretty(&mut writer, config).context("Failed to write JSON"), |
| 294 | _ => Err(anyhow!("Unknown config file extension: {ext}")), |
| 295 | }?; |
| 296 | let file = writer.into_inner().context("Failed to flush file")?; |
| 297 | let metadata = file.metadata().context("Failed to get file metadata")?; |
| 298 | let ts = filetime::FileTime::from_last_modification_time(&metadata); |
| 299 | Ok(ProjectConfigInfo { path: info.path.clone(), timestamp: Some(ts) }) |
| 300 | } |
| 301 | |
| 302 | fn validate_min_version(config: &ProjectConfig) -> Result<()> { |
| 303 | let Some(min_version) = &config.min_version else { return Ok(()) }; |