use std::fs::File;
use std::path::Path;
use serde::Deserialize;
use tracing::debug;
use crate::error::Error;
#[derive(Debug, Deserialize)]
#[non_exhaustive]
pub(crate) struct CargoVcsInfo {
pub git: GitInfo,
pub path_in_vcs: Option<String>,
}
#[derive(Debug, Deserialize)]
#[non_exhaustive]
pub(crate) struct GitInfo {
pub sha1: String,
#[serde(default)]
pub dirty: bool,
}
pub(crate) fn vcs_info_from_root<P: AsRef<Path>>(root: P) -> Result<Option<CargoVcsInfo>, Error> {
let path = root.as_ref().join(".cargo_vcs_info.json");
debug!("Loading '.cargo_vcs_info.json' from path: {}", path.to_string_lossy());
let file = match File::open(path) {
Ok(file) => file,
Err(err) => {
if err.kind() == std::io::ErrorKind::NotFound {
return Ok(None);
}
return Err(Error::VcsInfo {
inner: format!("failed to open file ({err})"),
});
},
};
let info: CargoVcsInfo = serde_json::from_reader(file).map_err(|err| Error::VcsInfo {
inner: format!("failed to deserialize JSON ({err})"),
})?;
Ok(Some(info))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deserialize_vcs_info() {
let contents = std::fs::read_to_string("tests/cargo_vcs_info.json").unwrap();
let _data: CargoVcsInfo = serde_json::from_str(&contents).unwrap();
}
}