Skip to content

Commit

Permalink
Merge pull request #26 from NREL/serde-api-improvements
Browse files Browse the repository at this point in the history
copied better `SerdeAPI` from altrios
  • Loading branch information
kylecarow authored Jun 13, 2023
2 parents 26edd86 + 70e9f00 commit e0eb6a4
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 22 deletions.
59 changes: 39 additions & 20 deletions rust/fastsim-core/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,23 @@ use std::collections::HashMap;

pub trait SerdeAPI: Serialize + for<'a> Deserialize<'a> {
/// runs any initialization steps that might be needed
fn init(&mut self) {}
fn init(&mut self) -> anyhow::Result<()> {
Ok(())
}

fn to_file(&self, filename: &str) -> anyhow::Result<()> {
#[allow(clippy::wrong_self_convention)]
/// Save current data structure to file. Method adaptively calls serialization methods
/// dependent on the suffix of the file given as str.
///
/// # Argument:
///
/// * `filename`: a `str` storing the targeted file name. Currently `.json` and `.yaml` suffixes are
/// supported
///
/// # Returns:
///
/// A Rust Result
fn to_file(&self, filename: &str) -> Result<(), anyhow::Error> {
let file = PathBuf::from(filename);
match file.extension().unwrap().to_str().unwrap() {
"json" => serde_json::to_writer(&File::create(file)?, self)?,
Expand All @@ -15,6 +29,19 @@ pub trait SerdeAPI: Serialize + for<'a> Deserialize<'a> {
Ok(())
}

/// Read from file and return instantiated struct. Method adaptively calls deserialization
/// methods dependent on the suffix of the file name given as str.
/// Function returns a dynamic Error Result if it fails.
///
/// # Argument:
///
/// * `filename`: a `str` storing the targeted file name. Currently `.json` and `.yaml` suffixes are
/// supported
///
/// # Returns:
///
/// A Rust Result wrapping data structure if method is called successfully; otherwise a dynamic
/// Error.
fn from_file(filename: &str) -> Result<Self, anyhow::Error>
where
Self: std::marker::Sized,
Expand All @@ -26,13 +53,14 @@ pub trait SerdeAPI: Serialize + for<'a> Deserialize<'a> {
.unwrap_or("");

let file = File::open(filename)?;
let mut res = match extension {
"yaml" => Ok(serde_yaml::from_reader::<std::fs::File, Self>(file)?),
"json" => Ok(serde_json::from_reader::<std::fs::File, Self>(file)?),
_ => Err(anyhow!("Unsupported file extension {}", extension)),
// deserialized file
let mut file_de: Self = match extension {
"yaml" => serde_yaml::from_reader(file)?,
"json" => serde_json::from_reader(file)?,
_ => bail!("Unsupported file extension {}", extension),
};
res.as_mut().unwrap().init();
res
file_de.init()?;
Ok(file_de)
}

/// json serialization method.
Expand All @@ -41,10 +69,7 @@ pub trait SerdeAPI: Serialize + for<'a> Deserialize<'a> {
}

/// json deserialization method.
fn from_json(json_str: &str) -> Result<Self, anyhow::Error>
where
Self: Sized,
{
fn from_json(json_str: &str) -> Result<Self, anyhow::Error> {
Ok(serde_json::from_str(json_str)?)
}

Expand All @@ -54,10 +79,7 @@ pub trait SerdeAPI: Serialize + for<'a> Deserialize<'a> {
}

/// yaml deserialization method.
fn from_yaml(yaml_str: &str) -> Result<Self, anyhow::Error>
where
Self: Sized,
{
fn from_yaml(yaml_str: &str) -> Result<Self, anyhow::Error> {
Ok(serde_yaml::from_str(yaml_str)?)
}

Expand All @@ -67,10 +89,7 @@ pub trait SerdeAPI: Serialize + for<'a> Deserialize<'a> {
}

/// bincode deserialization method.
fn from_bincode(encoded: &[u8]) -> Result<Self, anyhow::Error>
where
Self: Sized,
{
fn from_bincode(encoded: &[u8]) -> Result<Self, anyhow::Error> {
Ok(deserialize(encoded)?)
}
}
Expand Down
5 changes: 3 additions & 2 deletions rust/fastsim-core/src/vehicle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,8 +916,9 @@ impl RustVehicle {
}

impl SerdeAPI for RustVehicle {
fn init(&mut self) {
self.set_derived().unwrap();
fn init(&mut self) -> anyhow::Result<()> {
self.set_derived()?;
Ok(())
}
}

Expand Down

0 comments on commit e0eb6a4

Please sign in to comment.