Load a TOML file as a document. Returns an empty table when the file does not exist. When the file exists but cannot be parsed as a TOML document, returns a [`TraceDecayError::Config`] so callers do not silently overwrite the user's data (see issue #63).
(path: &Path)
| 1405 | /// but cannot be parsed as a TOML document, returns a [`TraceDecayError::Config`] |
| 1406 | /// so callers do not silently overwrite the user's data (see issue #63). |
| 1407 | pub fn load_toml_file(path: &Path) -> Result<toml::Value> { |
| 1408 | if !path.exists() { |
| 1409 | return Ok(toml::Value::Table(toml::map::Map::new())); |
| 1410 | } |
| 1411 | let contents = std::fs::read_to_string(path).map_err(|e| TraceDecayError::Config { |
| 1412 | message: format!("failed to read {}: {e}", path.display()), |
| 1413 | })?; |
| 1414 | if contents.trim().is_empty() { |
| 1415 | return Ok(toml::Value::Table(toml::map::Map::new())); |
| 1416 | } |
| 1417 | // NOTE: `str.parse::<toml::Value>()` parses a single TOML value in toml v1, |
| 1418 | // not a document — using it here would treat any well-formed config.toml as |
| 1419 | // unparseable and silently drop its contents. Use `toml::from_str` instead. |
| 1420 | let table: toml::Table = toml::from_str(&contents).map_err(|e| TraceDecayError::Config { |
| 1421 | message: format!( |
| 1422 | "failed to parse {} as TOML: {e}. Refusing to overwrite — fix the file or remove it manually.", |
| 1423 | path.display() |
| 1424 | ), |
| 1425 | })?; |
| 1426 | Ok(toml::Value::Table(table)) |
| 1427 | } |
| 1428 | |
| 1429 | /// Copy `path` to `<path>.bak` if it exists. Used before overwriting a user |
| 1430 | /// config so an unexpected change is recoverable (issue #63). |