Skip to content

Commit

Permalink
Merge pull request #235 from axodotdev/deserialize-yaml
Browse files Browse the repository at this point in the history
Integrate deserialize_yaml() from dist.
  • Loading branch information
duckinator authored Dec 4, 2024
2 parents 857c67a + 89b1e13 commit d8e7594
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 24 deletions.
72 changes: 48 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ toml-serde = ["toml", "serde"]
json-serde = ["serde_json", "serde"]
# Enable SourceFile support for deserializing using the "toml_edit" crate
toml-edit = ["toml_edit"]
# Enable SourceFile support for deserializing using the "serde_yml" crate
yaml-serde = ["serde_yml", "serde"]
# Enable reqwest-based http file fetching
remote = ["reqwest", "image"]
# On the off-chance native tls roots cause a problem, they can be opted out of
Expand All @@ -37,6 +39,7 @@ miette = "7.0.0"
camino = "1.1.9"
toml = { version = "0.8.12", optional = true }
serde_json = { version = "1.0.132", optional = true }
serde_yml = { version = "0.0.10", optional = true }
serde = { version = "1.0.214", optional = true, features = ["derive"] }
tar = { version = "0.4.42", optional = true }
zip = { version = "0.6.4", optional = true }
Expand Down
16 changes: 16 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,4 +331,20 @@ pub enum AxoassetError {
#[source]
details: toml_edit::TomlError,
},

/// This error indicates we tried to deserialize some YAML with serde_yml
/// but failed.
#[cfg(feature = "yaml-serde")]
#[error("failed to parse YAML")]
Yaml {
/// The SourceFile we were try to parse
#[source_code]
source: crate::SourceFile,
/// The range the error was found on
#[label]
span: Option<miette::SourceSpan>,
/// Details of the error
#[source]
details: serde_yml::Error,
},
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub use remote::AxoClient;
pub use reqwest;
#[cfg(feature = "json-serde")]
pub use serde_json;
#[cfg(feature = "yaml-serde")]
pub use serde_yml;
pub use source::SourceFile;
pub use spanned::Spanned;
#[cfg(feature = "toml-serde")]
Expand Down
19 changes: 19 additions & 0 deletions src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use crate::toml_edit::DocumentMut;
#[cfg(feature = "json-serde")]
use crate::serde_json;

#[cfg(feature = "yaml-serde")]
use crate::serde_yml;

/// The inner contents of a [`SourceFile`][].
#[derive(Eq, PartialEq)]
struct SourceFileInner {
Expand Down Expand Up @@ -128,6 +131,22 @@ impl SourceFile {
Ok(toml)
}

/// Try to deserialize the contents of the SourceFile as yaml
#[cfg(feature = "yaml-serde")]
pub fn deserialize_yaml<'a, T: for<'de> serde::Deserialize<'de>>(&self) -> Result<T> {
let yaml = serde_yml::from_str(self.contents()).map_err(|details| {
let span = details
.location()
.and_then(|location| self.span_for_line_col(location.line(), location.column()));
AxoassetError::Yaml {
source: self.clone(),
span,
details,
}
})?;
Ok(yaml)
}

/// Get the filename of a SourceFile
pub fn filename(&self) -> &str {
&self.inner.filename
Expand Down
50 changes: 50 additions & 0 deletions tests/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,53 @@ goodbye =
panic!("span was invalid");
};
}

#[test]
#[cfg(feature = "yaml-serde")]
fn yaml_valid() {
#[derive(serde::Deserialize, PartialEq, Eq, Debug)]
struct MyType {
hello: String,
goodbye: bool,
}

// Make the file
let contents = String::from(
r##"
hello: "there"
goodbye: true
"##,
);
let source = axoasset::SourceFile::new("file.yaml", contents);

let res = source.deserialize_yaml::<MyType>().unwrap();
assert_eq!(res.hello, "there");
assert_eq!(res.goodbye, true);
}

#[test]
#[cfg(feature = "yaml-serde")]
fn yaml_invalid() {
use axoasset::AxoassetError;

#[derive(serde::Deserialize, PartialEq, Eq, Debug)]
struct MyType {
hello: String,
goodbye: bool,
}

// Make the file
let contents = String::from(
r##"
hello: "there"
goodbye: "this shouldn't be a string"
"##,
);
let source = axoasset::SourceFile::new("file.yml", contents);

let res = source.deserialize_yaml::<MyType>();
assert!(res.is_err());
let Err(AxoassetError::Yaml { span: Some(_), .. }) = res else {
panic!("span was invalid");
};
}

0 comments on commit d8e7594

Please sign in to comment.