config.rs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. use anyhow::{anyhow, bail, Context, Result};
  2. use serde::{de::DeserializeOwned, Serialize};
  3. use serde_yaml::{Mapping, Value};
  4. use std::{fs, path::PathBuf};
  5. /// read data from yaml as struct T
  6. pub fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
  7. if !path.exists() {
  8. bail!("file not found \"{}\"", path.display());
  9. }
  10. let yaml_str = fs::read_to_string(&path)
  11. .context(format!("failed to read the file \"{}\"", path.display()))?;
  12. serde_yaml::from_str::<T>(&yaml_str).context(format!(
  13. "failed to read the file with yaml format \"{}\"",
  14. path.display()
  15. ))
  16. }
  17. /// read mapping from yaml fix #165
  18. pub fn read_merge_mapping(path: &PathBuf) -> Result<Mapping> {
  19. let mut val: Value = read_yaml(path)?;
  20. val.apply_merge()
  21. .context(format!("failed to apply merge \"{}\"", path.display()))?;
  22. Ok(val
  23. .as_mapping()
  24. .ok_or(anyhow!(
  25. "failed to transform to yaml mapping \"{}\"",
  26. path.display()
  27. ))?
  28. .to_owned())
  29. }
  30. /// save the data to the file
  31. /// can set `prefix` string to add some comments
  32. pub fn save_yaml<T: Serialize>(path: PathBuf, data: &T, prefix: Option<&str>) -> Result<()> {
  33. let data_str = serde_yaml::to_string(data)?;
  34. let yaml_str = match prefix {
  35. Some(prefix) => format!("{prefix}\n{data_str}"),
  36. None => data_str,
  37. };
  38. let path_str = path.as_os_str().to_string_lossy().to_string();
  39. fs::write(path, yaml_str.as_bytes()).context(format!("failed to save file \"{path_str}\""))
  40. }