mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Refactor YAML code
This commit is contained in:
@@ -7,11 +7,11 @@ use super::{
|
||||
MessageContent, emit_message_contents, parse_message_contents_yaml,
|
||||
validate_message_contents,
|
||||
},
|
||||
yaml::{EmitYaml, YamlEmitter},
|
||||
yaml::{
|
||||
YamlObjectType, as_string_node, get_required_string_value, get_string_value,
|
||||
parse_condition,
|
||||
},
|
||||
yaml_emit::{EmitYaml, YamlEmitter},
|
||||
};
|
||||
|
||||
/// Represents a file in a game's Data folder, including files in
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use saphyr::MarkedYaml;
|
||||
|
||||
use super::error::ParseMetadataError;
|
||||
use super::yaml::{EmitYaml, YamlEmitter};
|
||||
use super::yaml::{
|
||||
YamlObjectType, get_as_hash, get_required_string_value, get_string_value, get_strings_vec_value,
|
||||
};
|
||||
use super::yaml_emit::{EmitYaml, YamlEmitter};
|
||||
|
||||
/// Represents a group to which plugin metadata objects can belong.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
@@ -104,10 +104,6 @@ impl TryFrom<&MarkedYaml> for Group {
|
||||
}
|
||||
|
||||
impl EmitYaml for Group {
|
||||
fn is_scalar(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn emit_yaml(&self, emitter: &mut YamlEmitter) {
|
||||
emitter.begin_map();
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ use saphyr::{MarkedYaml, YamlData};
|
||||
use super::error::ExpectedType;
|
||||
use super::error::ParseMetadataError;
|
||||
|
||||
use super::yaml::EmitYaml;
|
||||
use super::yaml::YamlEmitter;
|
||||
use super::yaml::{YamlObjectType, get_required_string_value};
|
||||
use super::yaml_emit::EmitYaml;
|
||||
use super::yaml_emit::YamlEmitter;
|
||||
|
||||
/// Represents a URL at which the parent plugin can be found.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
|
||||
@@ -10,11 +10,11 @@ use super::{
|
||||
ExpectedType, MetadataParsingErrorReason, MultilingualMessageContentsError,
|
||||
ParseMetadataError,
|
||||
},
|
||||
yaml::{EmitYaml, YamlEmitter},
|
||||
yaml::{
|
||||
YamlObjectType, as_string_node, get_as_hash, get_required_string_value,
|
||||
get_strings_vec_value, parse_condition,
|
||||
},
|
||||
yaml_emit::{EmitYaml, YamlEmitter},
|
||||
};
|
||||
|
||||
/// Codes used to indicate the type of a message.
|
||||
@@ -388,10 +388,6 @@ impl TryFrom<&MarkedYaml> for Message {
|
||||
}
|
||||
|
||||
impl EmitYaml for MessageContent {
|
||||
fn is_scalar(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn emit_yaml(&self, emitter: &mut YamlEmitter) {
|
||||
emitter.begin_map();
|
||||
|
||||
@@ -425,10 +421,6 @@ pub(super) fn emit_message_contents(
|
||||
}
|
||||
|
||||
impl EmitYaml for Message {
|
||||
fn is_scalar(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn emit_yaml(&self, emitter: &mut YamlEmitter) {
|
||||
emitter.begin_map();
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
path::Path,
|
||||
sync::LazyLock,
|
||||
};
|
||||
|
||||
use saphyr::{MarkedYaml, YamlData};
|
||||
@@ -11,18 +10,15 @@ use crate::logging;
|
||||
use super::{
|
||||
error::{
|
||||
ExpectedType, LoadMetadataError, MetadataDocumentParsingError, ParseMetadataError,
|
||||
RegexError, WriteMetadataError, YamlMergeKeyError,
|
||||
RegexError, WriteMetadataError,
|
||||
},
|
||||
file::Filename,
|
||||
group::Group,
|
||||
message::Message,
|
||||
plugin_metadata::PluginMetadata,
|
||||
yaml::{YamlObjectType, as_string_node, get_as_slice},
|
||||
yaml_emit::{EmitYaml, YamlEmitter},
|
||||
yaml::{EmitYaml, YamlEmitter, YamlObjectType, get_as_slice, process_merge_keys},
|
||||
};
|
||||
|
||||
static MERGE_KEY: LazyLock<MarkedYaml> = LazyLock::new(|| as_string_node("<<"));
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct MetadataDocument {
|
||||
bash_tags: Vec<String>,
|
||||
@@ -342,71 +338,6 @@ impl std::default::Default for MetadataDocument {
|
||||
}
|
||||
}
|
||||
|
||||
fn process_merge_keys(mut yaml: MarkedYaml) -> Result<MarkedYaml, YamlMergeKeyError> {
|
||||
match yaml.data {
|
||||
YamlData::Array(a) => {
|
||||
yaml.data = merge_array_elements(a).map(YamlData::Array)?;
|
||||
Ok(yaml)
|
||||
}
|
||||
YamlData::Hash(h) => {
|
||||
yaml.data = merge_hash_keys(h).map(YamlData::Hash)?;
|
||||
Ok(yaml)
|
||||
}
|
||||
_ => Ok(yaml),
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_array_elements(
|
||||
array: saphyr::AnnotatedArray<MarkedYaml>,
|
||||
) -> Result<saphyr::AnnotatedArray<MarkedYaml>, YamlMergeKeyError> {
|
||||
array.into_iter().map(process_merge_keys).collect()
|
||||
}
|
||||
|
||||
fn merge_hash_keys(
|
||||
hash: saphyr::AnnotatedHash<MarkedYaml>,
|
||||
) -> Result<saphyr::AnnotatedHash<MarkedYaml>, YamlMergeKeyError> {
|
||||
let mut hash: saphyr::AnnotatedHash<MarkedYaml> = hash
|
||||
.into_iter()
|
||||
.map(|(key, value)| {
|
||||
process_merge_keys(key)
|
||||
.and_then(|key| process_merge_keys(value).map(|value| (key, value)))
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
if let Some(value) = hash.remove(&MERGE_KEY) {
|
||||
merge_into_hash(hash, value)
|
||||
} else {
|
||||
Ok(hash)
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_into_hash(
|
||||
hash: saphyr::AnnotatedHash<MarkedYaml>,
|
||||
value: MarkedYaml,
|
||||
) -> Result<saphyr::AnnotatedHash<MarkedYaml>, YamlMergeKeyError> {
|
||||
match value.data {
|
||||
YamlData::<MarkedYaml>::Array(a) => a.into_iter().try_fold(hash, |acc, e| {
|
||||
if let YamlData::Hash(h) = e.data {
|
||||
Ok(merge_hashes(acc, h))
|
||||
} else {
|
||||
Err(YamlMergeKeyError::new(e))
|
||||
}
|
||||
}),
|
||||
YamlData::<MarkedYaml>::Hash(h) => Ok(merge_hashes(hash, h)),
|
||||
_ => Err(YamlMergeKeyError::new(value)),
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_hashes(
|
||||
mut hash1: saphyr::AnnotatedHash<MarkedYaml>,
|
||||
hash2: saphyr::AnnotatedHash<MarkedYaml>,
|
||||
) -> saphyr::AnnotatedHash<MarkedYaml> {
|
||||
for (key, value) in hash2 {
|
||||
hash1.entry(key).or_insert(value);
|
||||
}
|
||||
hash1
|
||||
}
|
||||
|
||||
fn replace_prelude(masterlist: String, prelude: String) -> String {
|
||||
let line_ending = detect_line_ending(&masterlist);
|
||||
if let Some((start, end)) = find_prelude_bounds(&masterlist) {
|
||||
|
||||
+2
-3
@@ -9,7 +9,6 @@ mod plugin_cleaning_data;
|
||||
pub(crate) mod plugin_metadata;
|
||||
mod tag;
|
||||
mod yaml;
|
||||
mod yaml_emit;
|
||||
|
||||
pub use file::{File, Filename};
|
||||
pub use group::Group;
|
||||
@@ -20,8 +19,8 @@ pub use plugin_metadata::PluginMetadata;
|
||||
pub use tag::{Tag, TagSuggestion};
|
||||
|
||||
#[cfg(test)]
|
||||
fn emit<T: yaml_emit::EmitYaml>(metadata: &T) -> String {
|
||||
let mut emitter = yaml_emit::YamlEmitter::new();
|
||||
fn emit<T: yaml::EmitYaml>(metadata: &T) -> String {
|
||||
let mut emitter = yaml::YamlEmitter::new();
|
||||
metadata.emit_yaml(&mut emitter);
|
||||
|
||||
emitter.into_string()
|
||||
|
||||
@@ -6,8 +6,8 @@ use super::{
|
||||
MessageContent, emit_message_contents, parse_message_contents_yaml,
|
||||
validate_message_contents,
|
||||
},
|
||||
yaml::{EmitYaml, YamlEmitter},
|
||||
yaml::{YamlObjectType, as_string_node, get_as_hash, get_required_string_value, get_u32_value},
|
||||
yaml_emit::{EmitYaml, YamlEmitter},
|
||||
};
|
||||
|
||||
/// Represents data identifying the plugin under which it is stored as dirty or
|
||||
@@ -181,10 +181,6 @@ impl TryFrom<&MarkedYaml> for PluginCleaningData {
|
||||
}
|
||||
|
||||
impl EmitYaml for PluginCleaningData {
|
||||
fn is_scalar(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn emit_yaml(&self, emitter: &mut YamlEmitter) {
|
||||
emitter.begin_map();
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ use super::{
|
||||
message::Message,
|
||||
plugin_cleaning_data::PluginCleaningData,
|
||||
tag::Tag,
|
||||
yaml::{EmitYaml, YamlEmitter},
|
||||
yaml::{
|
||||
YamlObjectType, get_as_hash, get_as_slice, get_required_string_value, get_string_value,
|
||||
},
|
||||
yaml_emit::{EmitYaml, YamlEmitter},
|
||||
};
|
||||
|
||||
pub(crate) const GHOST_FILE_EXTENSION: &str = ".ghost";
|
||||
@@ -376,10 +376,6 @@ fn get_vec<'a, T: TryFrom<&'a MarkedYaml, Error = impl Into<ParseMetadataError>>
|
||||
}
|
||||
|
||||
impl EmitYaml for PluginMetadata {
|
||||
fn is_scalar(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn emit_yaml(&self, emitter: &mut YamlEmitter) {
|
||||
emitter.begin_map();
|
||||
|
||||
|
||||
+2
-2
@@ -2,9 +2,9 @@ use saphyr::YamlData;
|
||||
|
||||
use super::error::ExpectedType;
|
||||
use super::error::ParseMetadataError;
|
||||
use super::yaml::EmitYaml;
|
||||
use super::yaml::YamlEmitter;
|
||||
use super::yaml::{YamlObjectType, get_required_string_value, parse_condition};
|
||||
use super::yaml_emit::EmitYaml;
|
||||
use super::yaml_emit::YamlEmitter;
|
||||
|
||||
/// Represents whether a Bash Tag suggestion is for addition or removal.
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
pub trait EmitYaml {
|
||||
fn is_scalar(&self) -> bool;
|
||||
fn is_scalar(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn emit_yaml(&self, emitter: &mut YamlEmitter);
|
||||
}
|
||||
@@ -277,10 +279,6 @@ fn double_quote(value: &str) -> String {
|
||||
}
|
||||
|
||||
impl<T: EmitYaml> EmitYaml for &[T] {
|
||||
fn is_scalar(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn emit_yaml(&self, emitter: &mut YamlEmitter) {
|
||||
match self {
|
||||
[] => {}
|
||||
@@ -305,10 +303,6 @@ impl<T: EmitYaml> EmitYaml for &[T] {
|
||||
}
|
||||
|
||||
impl<T: EmitYaml> EmitYaml for Vec<T> {
|
||||
fn is_scalar(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn emit_yaml(&self, emitter: &mut YamlEmitter) {
|
||||
self.as_slice().emit_yaml(emitter);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use saphyr::{MarkedYaml, YamlData};
|
||||
|
||||
use crate::metadata::error::YamlMergeKeyError;
|
||||
|
||||
use super::as_string_node;
|
||||
|
||||
static MERGE_KEY: LazyLock<MarkedYaml> = LazyLock::new(|| as_string_node("<<"));
|
||||
|
||||
pub fn process_merge_keys(mut yaml: MarkedYaml) -> Result<MarkedYaml, YamlMergeKeyError> {
|
||||
match yaml.data {
|
||||
YamlData::Array(a) => {
|
||||
yaml.data = merge_array_elements(a).map(YamlData::Array)?;
|
||||
Ok(yaml)
|
||||
}
|
||||
YamlData::Hash(h) => {
|
||||
yaml.data = merge_hash_keys(h).map(YamlData::Hash)?;
|
||||
Ok(yaml)
|
||||
}
|
||||
_ => Ok(yaml),
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_array_elements(
|
||||
array: saphyr::AnnotatedArray<MarkedYaml>,
|
||||
) -> Result<saphyr::AnnotatedArray<MarkedYaml>, YamlMergeKeyError> {
|
||||
array.into_iter().map(process_merge_keys).collect()
|
||||
}
|
||||
|
||||
fn merge_hash_keys(
|
||||
hash: saphyr::AnnotatedHash<MarkedYaml>,
|
||||
) -> Result<saphyr::AnnotatedHash<MarkedYaml>, YamlMergeKeyError> {
|
||||
let mut hash: saphyr::AnnotatedHash<MarkedYaml> = hash
|
||||
.into_iter()
|
||||
.map(|(key, value)| {
|
||||
process_merge_keys(key)
|
||||
.and_then(|key| process_merge_keys(value).map(|value| (key, value)))
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
if let Some(value) = hash.remove(&MERGE_KEY) {
|
||||
merge_into_hash(hash, value)
|
||||
} else {
|
||||
Ok(hash)
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_into_hash(
|
||||
hash: saphyr::AnnotatedHash<MarkedYaml>,
|
||||
value: MarkedYaml,
|
||||
) -> Result<saphyr::AnnotatedHash<MarkedYaml>, YamlMergeKeyError> {
|
||||
match value.data {
|
||||
YamlData::<MarkedYaml>::Array(a) => a.into_iter().try_fold(hash, |acc, e| {
|
||||
if let YamlData::Hash(h) = e.data {
|
||||
Ok(merge_hashes(acc, h))
|
||||
} else {
|
||||
Err(YamlMergeKeyError::new(e))
|
||||
}
|
||||
}),
|
||||
YamlData::<MarkedYaml>::Hash(h) => Ok(merge_hashes(hash, h)),
|
||||
_ => Err(YamlMergeKeyError::new(value)),
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_hashes(
|
||||
mut hash1: saphyr::AnnotatedHash<MarkedYaml>,
|
||||
hash2: saphyr::AnnotatedHash<MarkedYaml>,
|
||||
) -> saphyr::AnnotatedHash<MarkedYaml> {
|
||||
for (key, value) in hash2 {
|
||||
hash1.entry(key).or_insert(value);
|
||||
}
|
||||
hash1
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
mod emit;
|
||||
mod merge;
|
||||
mod parse;
|
||||
|
||||
pub use emit::{EmitYaml, YamlEmitter};
|
||||
pub use merge::process_merge_keys;
|
||||
pub use parse::{
|
||||
YamlObjectType, as_string_node, get_as_hash, get_as_slice, get_required_string_value,
|
||||
get_string_value, get_strings_vec_value, get_u32_value, parse_condition, to_yaml,
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use loot_condition_interpreter::Expression;
|
||||
use saphyr::{AnnotatedArray, AnnotatedHash, MarkedYaml, Marker, Yaml, YamlData};
|
||||
use saphyr::{AnnotatedHash, MarkedYaml, Marker, Yaml, YamlData};
|
||||
|
||||
use super::error::{ExpectedType, MetadataParsingErrorReason, ParseMetadataError};
|
||||
use super::super::error::{ExpectedType, MetadataParsingErrorReason, ParseMetadataError};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum YamlObjectType {
|
||||
@@ -42,24 +42,18 @@ pub fn to_yaml(yaml: &MarkedYaml) -> Yaml {
|
||||
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(to_array(v)),
|
||||
saphyr::YamlData::Hash(v) => Yaml::Hash(to_hash(v)),
|
||||
saphyr::YamlData::Array(v) => Yaml::Array(v.iter().map(to_yaml).collect()),
|
||||
saphyr::YamlData::Hash(v) => Yaml::Hash(
|
||||
v.iter()
|
||||
.map(|(key, value)| (to_yaml(key), to_yaml(value)))
|
||||
.collect(),
|
||||
),
|
||||
saphyr::YamlData::Alias(v) => Yaml::Alias(*v),
|
||||
saphyr::YamlData::Null => Yaml::Null,
|
||||
saphyr::YamlData::BadValue => Yaml::BadValue,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_array(array: &AnnotatedArray<MarkedYaml>) -> saphyr::Array {
|
||||
array.iter().map(to_yaml).collect()
|
||||
}
|
||||
|
||||
fn to_hash(hash: &AnnotatedHash<MarkedYaml>) -> saphyr::Hash {
|
||||
hash.iter()
|
||||
.map(|(key, value)| (to_yaml(key), to_yaml(value)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn as_string_node(value: &str) -> MarkedYaml {
|
||||
MarkedYaml {
|
||||
span: saphyr_parser::Span::default(),
|
||||
Reference in New Issue
Block a user