diff --git a/Cargo.lock b/Cargo.lock index 0aa6c2e4..0d604acd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,18 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy 0.7.35", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -498,10 +486,6 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] [[package]] name = "hashbrown" @@ -516,11 +500,11 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.4" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.15.2", ] [[package]] @@ -724,6 +708,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -736,6 +729,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2c1f9f56e534ac6a9b8a4600bdf0f530fb393b5f393e7b4d03489c3cf0c3f01" +dependencies = [ + "num-traits", +] + [[package]] name = "ordered-multimap" version = "0.7.3" @@ -846,7 +848,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", ] [[package]] @@ -1141,21 +1143,22 @@ checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "saphyr" -version = "0.0.3" +version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31513a748cdf8fb8d1b64dcc14fdd997fa02f2431671c7ce34efbea5e7eeea" +checksum = "9235237b78e93229dfceefd307ca041d6e1752ac7eaaf392531c3778fa4810a1" dependencies = [ "arraydeque", "encoding_rs", "hashlink", + "ordered-float", "saphyr-parser", ] [[package]] name = "saphyr-parser" -version = "0.0.3" +version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123f0a6da68f3072c7c761450276d1d444cb391c8be182a757cd26cf684cb77f" +checksum = "2f5c8d67f5937b6b8a42c0d6038d90571ca3d8a99cc4adae69e490ba0acc6bf1" dependencies = [ "arraydeque", "hashlink", @@ -1616,33 +1619,13 @@ dependencies = [ "bitflags", ] -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "zerocopy-derive 0.7.35", -] - [[package]] name = "zerocopy" version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ - "zerocopy-derive 0.8.24", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "zerocopy-derive", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7a754321..99d5de0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,8 @@ log = { version = "0.4.26", features = ["std"] } petgraph = "0.8.1" rayon = "1.10.0" rustc-hash = "2.1.1" -saphyr = "0.0.3" -saphyr-parser = "0.0.3" +saphyr = "0.0.4" +saphyr-parser = "0.0.4" unicase = "2.8.1" esplugin.workspace = true diff --git a/src/metadata/error.rs b/src/metadata/error.rs index d74cbfe8..e79a0f77 100644 --- a/src/metadata/error.rs +++ b/src/metadata/error.rs @@ -6,7 +6,7 @@ use saphyr::Marker; use crate::metadata::MessageContent; -use super::yaml::{YamlObjectType, to_yaml}; +use super::yaml::{YamlObjectType, to_unmarked_yaml}; /// Represents an error that occurred when validating a collection of /// [MessageContent] objects. @@ -328,43 +328,47 @@ impl From for MetadataDocumentParsingError { } } -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq)] pub(super) struct YamlMergeKeyError { - value: Box, + start: Marker, + yaml: String, } impl YamlMergeKeyError { pub(super) fn new(value: saphyr::MarkedYaml) -> Self { + let mut yaml = String::new(); + + let unmarked_yaml = to_unmarked_yaml(&value); + + if saphyr::YamlEmitter::new(&mut yaml) + .dump(&unmarked_yaml) + .is_ok() + { + // The emitter starts the dumped YAML with ---\n, so strip that. + let index = 4; + if yaml.is_char_boundary(index) { + yaml = yaml.split_off(index); + } + } else { + yaml = format!("{:?}", yaml); + } + YamlMergeKeyError { - value: Box::new(value), + start: value.span.start, + yaml, } } } impl std::fmt::Display for YamlMergeKeyError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut output = String::new(); - - let yaml = to_yaml(&self.value); - - if saphyr::YamlEmitter::new(&mut output).dump(&yaml).is_ok() { - // The emitter starts the dumped YAML with ---\n, so strip that. - write!( - f, - "invalid YAML merge key value at line {} column {}: {}", - self.value.span.start.line(), - self.value.span.start.col(), - output.get(4..).unwrap_or_default() - ) - } else { - write!( - f, - "invalid YAML merge key value at line {} column {}: {:?}", - self.value.span.start.line(), - self.value.span.start.col(), - self.value - ) - } + write!( + f, + "invalid YAML merge key value at line {} column {}: {}", + self.start.line(), + self.start.col(), + self.yaml + ) } } diff --git a/src/metadata/file.rs b/src/metadata/file.rs index 676b3701..06aa7137 100644 --- a/src/metadata/file.rs +++ b/src/metadata/file.rs @@ -1,4 +1,4 @@ -use saphyr::{MarkedYaml, YamlData}; +use saphyr::{MarkedYaml, Scalar, YamlData}; use unicase::UniCase; use super::{ @@ -167,13 +167,13 @@ impl std::fmt::Display for Filename { impl TryFromYaml for File { fn try_from_yaml(value: &MarkedYaml) -> Result { match &value.data { - YamlData::String(s) => Ok(File { - name: Filename::new(s.clone()), + YamlData::Value(Scalar::String(s)) => Ok(File { + name: Filename::new(s.to_string()), display_name: None, detail: Box::default(), condition: None, }), - YamlData::Hash(h) => { + YamlData::Mapping(h) => { let name = get_required_string_value(value.span.start, h, "name", YamlObjectType::File)?; diff --git a/src/metadata/group.rs b/src/metadata/group.rs index cbbb235c..89483b3f 100644 --- a/src/metadata/group.rs +++ b/src/metadata/group.rs @@ -3,7 +3,7 @@ use saphyr::MarkedYaml; use super::{ error::ParseMetadataError, yaml::{ - EmitYaml, TryFromYaml, YamlEmitter, YamlObjectType, get_as_hash, get_required_string_value, + EmitYaml, TryFromYaml, YamlEmitter, YamlObjectType, as_mapping, get_required_string_value, get_string_value, get_strings_vec_value, }, }; @@ -86,14 +86,14 @@ impl std::default::Default for Group { impl TryFromYaml for Group { fn try_from_yaml(value: &MarkedYaml) -> Result { - let hash = get_as_hash(value, YamlObjectType::Group)?; + let mapping = as_mapping(value, YamlObjectType::Group)?; let name = - get_required_string_value(value.span.start, hash, "name", YamlObjectType::Group)?; + get_required_string_value(value.span.start, mapping, "name", YamlObjectType::Group)?; - let description = get_string_value(hash, "description", YamlObjectType::Group)?; + let description = get_string_value(mapping, "description", YamlObjectType::Group)?; - let after = get_strings_vec_value(hash, "after", YamlObjectType::Group)?; + let after = get_strings_vec_value(mapping, "after", YamlObjectType::Group)?; Ok(Group { name: name.into(), diff --git a/src/metadata/location.rs b/src/metadata/location.rs index 67f0faf2..606f2eda 100644 --- a/src/metadata/location.rs +++ b/src/metadata/location.rs @@ -1,4 +1,4 @@ -use saphyr::{MarkedYaml, YamlData}; +use saphyr::{MarkedYaml, Scalar, YamlData}; use super::{ error::{ExpectedType, ParseMetadataError}, @@ -49,11 +49,11 @@ impl Location { impl TryFromYaml for Location { fn try_from_yaml(value: &MarkedYaml) -> Result { match &value.data { - YamlData::String(s) => Ok(Location { - url: s.clone().into_boxed_str(), + YamlData::Value(Scalar::String(s)) => Ok(Location { + url: s.to_string().into_boxed_str(), name: None, }), - YamlData::Hash(h) => { + YamlData::Mapping(h) => { let link = get_required_string_value( value.span.start, h, diff --git a/src/metadata/message.rs b/src/metadata/message.rs index fd4de675..8ed1d615 100644 --- a/src/metadata/message.rs +++ b/src/metadata/message.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, sync::LazyLock}; use fancy_regex::{Captures, Regex}; -use saphyr::{MarkedYaml, YamlData}; +use saphyr::{MarkedYaml, Scalar, YamlData}; use crate::logging; @@ -11,7 +11,7 @@ use super::{ ParseMetadataError, }, yaml::{ - EmitYaml, TryFromYaml, YamlEmitter, YamlObjectType, as_string_node, get_as_hash, + EmitYaml, TryFromYaml, YamlEmitter, YamlObjectType, as_mapping, as_string_node, get_required_string_value, get_strings_vec_value, parse_condition, }, }; @@ -240,13 +240,13 @@ pub(crate) fn validate_message_contents( impl TryFromYaml for MessageContent { fn try_from_yaml(value: &MarkedYaml) -> Result { - let hash = get_as_hash(value, YamlObjectType::MessageContent)?; + let mapping = as_mapping(value, YamlObjectType::MessageContent)?; let text = - get_required_string_value(value.span.start, hash, "text", YamlObjectType::Message)?; + get_required_string_value(value.span.start, mapping, "text", YamlObjectType::Message)?; let language = - get_required_string_value(value.span.start, hash, "lang", YamlObjectType::Message)?; + get_required_string_value(value.span.start, mapping, "lang", YamlObjectType::Message)?; Ok(MessageContent { text: text.into(), @@ -261,8 +261,8 @@ pub(crate) fn parse_message_contents_yaml( parent_yaml_type: YamlObjectType, ) -> Result, ParseMetadataError> { let contents = match &value.data { - YamlData::String(s) => Box::new([MessageContent::new(s.clone())]), - YamlData::Array(a) => a + YamlData::Value(Scalar::String(s)) => Box::new([MessageContent::new(s.to_string())]), + YamlData::Sequence(a) => a .iter() .map(MessageContent::try_from_yaml) .collect::, _>>()?, @@ -288,17 +288,17 @@ pub(crate) fn parse_message_contents_yaml( impl TryFromYaml for Message { fn try_from_yaml(value: &MarkedYaml) -> Result { - let hash = get_as_hash(value, YamlObjectType::Message)?; + let mapping = as_mapping(value, YamlObjectType::Message)?; let message_type = - get_required_string_value(value.span.start, hash, "type", YamlObjectType::Message)?; + get_required_string_value(value.span.start, mapping, "type", YamlObjectType::Message)?; let message_type = match message_type { "warn" => MessageType::Warn, "error" => MessageType::Error, _ => MessageType::Say, }; - let mut content = match hash.get(&as_string_node("content")) { + let mut content = match mapping.get(&as_string_node("content")) { Some(n) => parse_message_contents_yaml(n, "content", YamlObjectType::Message)?, None => { return Err(ParseMetadataError::missing_key( @@ -309,7 +309,7 @@ impl TryFromYaml for Message { } }; - let subs = get_strings_vec_value(hash, "subs", YamlObjectType::Message)?; + let subs = get_strings_vec_value(mapping, "subs", YamlObjectType::Message)?; if !subs.is_empty() { static FMT_REGEX: LazyLock = LazyLock::new(|| { @@ -364,7 +364,7 @@ impl TryFromYaml for Message { } } - let condition = parse_condition(hash, YamlObjectType::Message)?; + let condition = parse_condition(mapping, YamlObjectType::Message)?; Ok(Message { message_type, diff --git a/src/metadata/metadata_document.rs b/src/metadata/metadata_document.rs index d0aff4b9..d2c6b451 100644 --- a/src/metadata/metadata_document.rs +++ b/src/metadata/metadata_document.rs @@ -3,7 +3,7 @@ use std::{ path::Path, }; -use saphyr::{MarkedYaml, YamlData}; +use saphyr::{LoadableYamlNode, MarkedYaml, YamlData}; use crate::logging; @@ -105,7 +105,7 @@ impl MetadataDocument { let doc = process_merge_keys(doc)?; let doc = match doc.data { - YamlData::Hash(h) => h, + YamlData::Mapping(h) => h, _ => { return Err(ParseMetadataError::unexpected_type( doc.span.start, diff --git a/src/metadata/mod.rs b/src/metadata/mod.rs index 0bf39d25..4446cd66 100644 --- a/src/metadata/mod.rs +++ b/src/metadata/mod.rs @@ -28,6 +28,8 @@ fn emit(metadata: &T) -> String { #[cfg(test)] fn parse(yaml: &str) -> saphyr::MarkedYaml { + use saphyr::LoadableYamlNode; + saphyr::MarkedYaml::load_from_str(yaml) .unwrap() .pop() diff --git a/src/metadata/plugin_cleaning_data.rs b/src/metadata/plugin_cleaning_data.rs index 24392e4a..6c090189 100644 --- a/src/metadata/plugin_cleaning_data.rs +++ b/src/metadata/plugin_cleaning_data.rs @@ -7,7 +7,7 @@ use super::{ validate_message_contents, }, yaml::{ - EmitYaml, TryFromYaml, YamlEmitter, YamlObjectType, as_string_node, get_as_hash, + EmitYaml, TryFromYaml, YamlEmitter, YamlObjectType, as_mapping, as_string_node, get_required_string_value, get_u32_value, }, }; @@ -138,9 +138,9 @@ impl PluginCleaningData { impl TryFromYaml for PluginCleaningData { fn try_from_yaml(value: &MarkedYaml) -> Result { - let hash = get_as_hash(value, YamlObjectType::PluginCleaningData)?; + let mapping = as_mapping(value, YamlObjectType::PluginCleaningData)?; - let crc = match get_u32_value(hash, "crc", YamlObjectType::PluginCleaningData)? { + let crc = match get_u32_value(mapping, "crc", YamlObjectType::PluginCleaningData)? { Some(n) => n, None => { return Err(ParseMetadataError::missing_key( @@ -153,16 +153,16 @@ impl TryFromYaml for PluginCleaningData { let util = get_required_string_value( value.span.start, - hash, + mapping, "util", YamlObjectType::PluginCleaningData, )?; - let itm = get_u32_value(hash, "itm", YamlObjectType::PluginCleaningData)?.unwrap_or(0); - let udr = get_u32_value(hash, "udr", YamlObjectType::PluginCleaningData)?.unwrap_or(0); - let nav = get_u32_value(hash, "nav", YamlObjectType::PluginCleaningData)?.unwrap_or(0); + let itm = get_u32_value(mapping, "itm", YamlObjectType::PluginCleaningData)?.unwrap_or(0); + let udr = get_u32_value(mapping, "udr", YamlObjectType::PluginCleaningData)?.unwrap_or(0); + let nav = get_u32_value(mapping, "nav", YamlObjectType::PluginCleaningData)?.unwrap_or(0); - let detail = match hash.get(&as_string_node("detail")) { + let detail = match mapping.get(&as_string_node("detail")) { Some(n) => { parse_message_contents_yaml(n, "detail", YamlObjectType::PluginCleaningData)? } diff --git a/src/metadata/plugin_metadata.rs b/src/metadata/plugin_metadata.rs index 1368d583..7a991eb3 100644 --- a/src/metadata/plugin_metadata.rs +++ b/src/metadata/plugin_metadata.rs @@ -13,7 +13,7 @@ use super::{ plugin_cleaning_data::PluginCleaningData, tag::Tag, yaml::{ - EmitYaml, TryFromYaml, YamlEmitter, YamlObjectType, get_as_hash, get_as_slice, + EmitYaml, TryFromYaml, YamlEmitter, YamlObjectType, as_mapping, get_as_slice, get_required_string_value, get_string_value, }, }; @@ -364,11 +364,11 @@ fn replace_capturing_groups(regex_string: &str) -> Cow<'_, str> { impl TryFromYaml for PluginMetadata { fn try_from_yaml(value: &MarkedYaml) -> Result { - let hash = get_as_hash(value, YamlObjectType::PluginMetadata)?; + let mapping = as_mapping(value, YamlObjectType::PluginMetadata)?; let name = get_required_string_value( value.span.start, - hash, + mapping, "name", YamlObjectType::PluginMetadata, )?; @@ -382,16 +382,16 @@ impl TryFromYaml for PluginMetadata { } }; - let group = get_string_value(hash, "group", YamlObjectType::PluginMetadata)?; + let group = get_string_value(mapping, "group", YamlObjectType::PluginMetadata)?; - let load_after = get_boxed_slice(hash, "after")?; - let requirements = get_boxed_slice(hash, "req")?; - let incompatibilities = get_boxed_slice(hash, "inc")?; - let messages = get_boxed_slice(hash, "msg")?; - let tags = get_boxed_slice(hash, "tag")?; - let dirty_info = get_boxed_slice(hash, "dirty")?; - let clean_info = get_boxed_slice(hash, "clean")?; - let locations = get_boxed_slice(hash, "url")?; + let load_after = get_boxed_slice(mapping, "after")?; + let requirements = get_boxed_slice(mapping, "req")?; + let incompatibilities = get_boxed_slice(mapping, "inc")?; + let messages = get_boxed_slice(mapping, "msg")?; + let tags = get_boxed_slice(mapping, "tag")?; + let dirty_info = get_boxed_slice(mapping, "dirty")?; + let clean_info = get_boxed_slice(mapping, "clean")?; + let locations = get_boxed_slice(mapping, "url")?; Ok(PluginMetadata { name, @@ -409,10 +409,10 @@ impl TryFromYaml for PluginMetadata { } fn get_boxed_slice( - hash: &saphyr::AnnotatedHash, + mapping: &saphyr::AnnotatedMapping, key: &'static str, ) -> Result, ParseMetadataError> { - get_as_slice(hash, key, YamlObjectType::PluginMetadata)? + get_as_slice(mapping, key, YamlObjectType::PluginMetadata)? .iter() .map(|e| T::try_from_yaml(e)) .collect() diff --git a/src/metadata/tag.rs b/src/metadata/tag.rs index b3db1d13..92c8965b 100644 --- a/src/metadata/tag.rs +++ b/src/metadata/tag.rs @@ -1,4 +1,4 @@ -use saphyr::{MarkedYaml, YamlData}; +use saphyr::{MarkedYaml, Scalar, YamlData}; use super::{ error::{ExpectedType, ParseMetadataError}, @@ -67,7 +67,7 @@ impl Tag { impl TryFromYaml for Tag { fn try_from_yaml(value: &MarkedYaml) -> Result { match &value.data { - YamlData::String(s) => { + YamlData::Value(Scalar::String(s)) => { let (name, suggestion) = name_and_suggestion(s); Ok(Tag { name, @@ -75,7 +75,7 @@ impl TryFromYaml for Tag { condition: None, }) } - YamlData::Hash(h) => { + YamlData::Mapping(h) => { let name = get_required_string_value(value.span.start, h, "name", YamlObjectType::Tag)?; diff --git a/src/metadata/yaml/merge.rs b/src/metadata/yaml/merge.rs index 24b4dd02..cbfdca4e 100644 --- a/src/metadata/yaml/merge.rs +++ b/src/metadata/yaml/merge.rs @@ -10,12 +10,12 @@ static MERGE_KEY: LazyLock = LazyLock::new(|| as_string_node("<<")); pub fn process_merge_keys(mut yaml: MarkedYaml) -> Result { match yaml.data { - YamlData::Array(a) => { - yaml.data = merge_array_elements(a).map(YamlData::Array)?; + YamlData::Sequence(a) => { + yaml.data = merge_array_elements(a).map(YamlData::Sequence)?; Ok(yaml) } - YamlData::Hash(h) => { - yaml.data = merge_hash_keys(h).map(YamlData::Hash)?; + YamlData::Mapping(h) => { + yaml.data = merge_mapping_keys(h).map(YamlData::Mapping)?; Ok(yaml) } _ => Ok(yaml), @@ -23,15 +23,15 @@ pub fn process_merge_keys(mut yaml: MarkedYaml) -> Result, -) -> Result, YamlMergeKeyError> { + array: saphyr::AnnotatedSequence, +) -> Result, YamlMergeKeyError> { array.into_iter().map(process_merge_keys).collect() } -fn merge_hash_keys( - hash: saphyr::AnnotatedHash, -) -> Result, YamlMergeKeyError> { - let mut hash: saphyr::AnnotatedHash = hash +fn merge_mapping_keys<'a, 'b>( + mapping: saphyr::AnnotatedMapping<'a, MarkedYaml<'b>>, +) -> Result>, YamlMergeKeyError> { + let mut mapping: saphyr::AnnotatedMapping = mapping .into_iter() .map(|(key, value)| { process_merge_keys(key) @@ -39,38 +39,38 @@ fn merge_hash_keys( }) .collect::>()?; - if let Some(value) = hash.remove(&MERGE_KEY) { - merge_into_hash(hash, value) + if let Some(value) = mapping.remove(&MERGE_KEY) { + merge_into_mapping(mapping, value) } else { - Ok(hash) + Ok(mapping) } } -fn merge_into_hash( - hash: saphyr::AnnotatedHash, - value: MarkedYaml, -) -> Result, YamlMergeKeyError> { +fn merge_into_mapping<'a, 'b>( + mapping: saphyr::AnnotatedMapping<'a, MarkedYaml<'b>>, + value: MarkedYaml<'b>, +) -> Result>, YamlMergeKeyError> { match value.data { - YamlData::Array(a) => a.into_iter().try_fold(hash, |acc, e| { - if let YamlData::Hash(h) = e.data { - Ok(merge_hashes(acc, h)) + YamlData::Sequence(a) => a.into_iter().try_fold(mapping, |acc, e| { + if let YamlData::Mapping(h) = e.data { + Ok(merge_mappings(acc, h)) } else { Err(YamlMergeKeyError::new(e)) } }), - YamlData::Hash(h) => Ok(merge_hashes(hash, h)), + YamlData::Mapping(h) => Ok(merge_mappings(mapping, h)), _ => Err(YamlMergeKeyError::new(value)), } } -fn merge_hashes( - mut hash1: saphyr::AnnotatedHash, - hash2: saphyr::AnnotatedHash, -) -> saphyr::AnnotatedHash { - for (key, value) in hash2 { - hash1.entry(key).or_insert(value); +fn merge_mappings<'a, 'b>( + mut mapping1: saphyr::AnnotatedMapping<'a, MarkedYaml<'b>>, + mapping2: saphyr::AnnotatedMapping>, +) -> saphyr::AnnotatedMapping<'a, MarkedYaml<'b>> { + for (key, value) in mapping2 { + mapping1.entry(key).or_insert(value); } - hash1 + mapping1 } #[cfg(test)] diff --git a/src/metadata/yaml/mod.rs b/src/metadata/yaml/mod.rs index 90d1040e..14fc1db5 100644 --- a/src/metadata/yaml/mod.rs +++ b/src/metadata/yaml/mod.rs @@ -5,7 +5,7 @@ mod parse; pub use emit::{EmitYaml, YamlEmitter}; pub use merge::process_merge_keys; pub use parse::{ - TryFromYaml, YamlObjectType, as_string_node, get_as_hash, get_as_slice, + TryFromYaml, YamlObjectType, as_mapping, as_string_node, get_as_slice, get_required_string_value, get_string_value, get_strings_vec_value, get_u32_value, - parse_condition, to_yaml, + parse_condition, to_unmarked_yaml, }; diff --git a/src/metadata/yaml/parse.rs b/src/metadata/yaml/parse.rs index 9318cd15..e8e5b564 100644 --- a/src/metadata/yaml/parse.rs +++ b/src/metadata/yaml/parse.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use loot_condition_interpreter::Expression; -use saphyr::{AnnotatedHash, MarkedYaml, Marker, Yaml, YamlData}; +use saphyr::{AnnotatedMapping, MarkedYaml, Marker, Scalar, Yaml, YamlData}; use super::super::error::{ExpectedType, MetadataParsingErrorReason, ParseMetadataError}; @@ -36,37 +36,38 @@ impl std::fmt::Display for YamlObjectType { } } -pub fn to_yaml(yaml: &MarkedYaml) -> Yaml { +pub fn to_unmarked_yaml<'a>(yaml: &MarkedYaml<'a>) -> Yaml<'a> { match &yaml.data { - saphyr::YamlData::Real(v) => Yaml::Real(v.clone()), - saphyr::YamlData::Integer(v) => Yaml::Integer(*v), - saphyr::YamlData::String(v) => Yaml::String(v.clone()), - saphyr::YamlData::Boolean(v) => Yaml::Boolean(*v), - saphyr::YamlData::Array(v) => Yaml::Array(v.iter().map(to_yaml).collect()), - saphyr::YamlData::Hash(v) => Yaml::Hash( + YamlData::Value(Scalar::FloatingPoint(v)) => Yaml::Value(Scalar::FloatingPoint(*v)), + YamlData::Value(Scalar::Integer(v)) => Yaml::Value(Scalar::Integer(*v)), + YamlData::Value(Scalar::String(v)) => Yaml::Value(Scalar::String(v.clone())), + YamlData::Value(Scalar::Boolean(v)) => Yaml::Value(Scalar::Boolean(*v)), + YamlData::Value(Scalar::Null) => Yaml::Value(Scalar::Null), + YamlData::Sequence(v) => Yaml::Sequence(v.iter().map(to_unmarked_yaml).collect()), + YamlData::Mapping(v) => Yaml::Mapping( v.iter() - .map(|(key, value)| (to_yaml(key), to_yaml(value))) + .map(|(key, value)| (to_unmarked_yaml(key), to_unmarked_yaml(value))) .collect(), ), - saphyr::YamlData::Alias(v) => Yaml::Alias(*v), - saphyr::YamlData::Null => Yaml::Null, - saphyr::YamlData::BadValue => Yaml::BadValue, + YamlData::Alias(v) => Yaml::Alias(*v), + YamlData::BadValue => Yaml::BadValue, + YamlData::Representation(v, s, t) => Yaml::Representation(v.clone(), *s, t.clone()), } } pub fn as_string_node(value: &str) -> MarkedYaml { MarkedYaml { span: saphyr_parser::Span::default(), - data: YamlData::String(value.into()), + data: YamlData::Value(Scalar::String(value.into())), } } pub fn get_string_value<'a>( - hash: &'a AnnotatedHash, + mapping: &'a AnnotatedMapping, key: &'static str, yaml_type: YamlObjectType, ) -> Result, ParseMetadataError> { - match hash.get(&as_string_node(key)) { + match mapping.get(&as_string_node(key)) { Some(n) => match n.data.as_str() { Some(s) => Ok(Some((n.span.start, s))), None => Err(ParseMetadataError::unexpected_value_type( @@ -82,22 +83,22 @@ pub fn get_string_value<'a>( pub fn get_required_string_value<'a>( marker: Marker, - hash: &'a AnnotatedHash, + mapping: &'a AnnotatedMapping, key: &'static str, yaml_type: YamlObjectType, ) -> Result<&'a str, ParseMetadataError> { - match get_string_value(hash, key, yaml_type)? { + match get_string_value(mapping, key, yaml_type)? { Some(n) => Ok(n.1), None => Err(ParseMetadataError::missing_key(marker, key, yaml_type)), } } pub fn get_strings_vec_value<'a>( - hash: &'a AnnotatedHash, + mapping: &'a AnnotatedMapping, key: &'static str, yaml_type: YamlObjectType, ) -> Result, ParseMetadataError> { - match hash.get(&as_string_node(key)) { + match mapping.get(&as_string_node(key)) { Some(n) => match n.data.as_vec() { Some(n) => n .iter() @@ -122,11 +123,11 @@ pub fn get_strings_vec_value<'a>( } } -pub fn get_as_hash( - value: &MarkedYaml, +pub fn as_mapping<'a, 'b>( + value: &'a MarkedYaml<'b>, yaml_type: YamlObjectType, -) -> Result<&AnnotatedHash, ParseMetadataError> { - match value.data.as_hash() { +) -> Result<&'a AnnotatedMapping<'a, MarkedYaml<'b>>, ParseMetadataError> { + match value.data.as_mapping() { Some(h) => Ok(h), None => Err(ParseMetadataError::unexpected_type( value.span.start, @@ -137,12 +138,12 @@ pub fn get_as_hash( } pub fn get_u32_value( - hash: &AnnotatedHash, + mapping: &AnnotatedMapping, key: &'static str, yaml_type: YamlObjectType, ) -> Result, ParseMetadataError> { - match hash.get(&as_string_node(key)) { - Some(n) => match n.data.as_i64() { + match mapping.get(&as_string_node(key)) { + Some(n) => match n.data.as_integer() { Some(i) => i.try_into().map(Some).map_err(|_| { ParseMetadataError::new(n.span.start, MetadataParsingErrorReason::NonU32Number(i)) }), @@ -158,11 +159,11 @@ pub fn get_u32_value( } pub fn get_as_slice<'a>( - hash: &'a saphyr::AnnotatedHash, + mapping: &'a saphyr::AnnotatedMapping, key: &'static str, yaml_type: YamlObjectType, -) -> Result<&'a [MarkedYaml], ParseMetadataError> { - if let Some(value) = hash.get(&as_string_node(key)) { +) -> Result<&'a [MarkedYaml<'a>], ParseMetadataError> { + if let Some(value) = mapping.get(&as_string_node(key)) { match value.data.as_vec() { Some(n) => Ok(n.as_slice()), None => Err(ParseMetadataError::unexpected_value_type( @@ -178,10 +179,10 @@ pub fn get_as_slice<'a>( } pub fn parse_condition( - hash: &saphyr::AnnotatedHash, + mapping: &saphyr::AnnotatedMapping, yaml_type: YamlObjectType, ) -> Result>, ParseMetadataError> { - match get_string_value(hash, "condition", yaml_type)? { + match get_string_value(mapping, "condition", yaml_type)? { Some((marker, s)) => { let s = s.to_string(); if let Err(e) = Expression::from_str(&s) {