diff --git a/saphyr/README.md b/saphyr/README.md index c1df782..498edc9 100644 --- a/saphyr/README.md +++ b/saphyr/README.md @@ -28,7 +28,7 @@ cargo add saphyr Use `saphyr::YamlLoader` to load YAML documents and access them as `Yaml` objects: ```rust -use saphyr::{YamlLoader, YamlEmitter}; +use saphyr::{Yaml, YamlEmitter}; fn main() { let s = @@ -40,7 +40,7 @@ bar: - 1 - 2.0 "; - let docs = YamlLoader::load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); // Multi document support, doc is a yaml::Yaml let doc = &docs[0]; diff --git a/saphyr/examples/dump_yaml.rs b/saphyr/examples/dump_yaml.rs index 34e41ee..8641732 100644 --- a/saphyr/examples/dump_yaml.rs +++ b/saphyr/examples/dump_yaml.rs @@ -1,4 +1,4 @@ -use saphyr::{load_from_str, Yaml}; +use saphyr::Yaml; use std::env; use std::fs::File; use std::io::prelude::*; @@ -36,7 +36,7 @@ fn main() { let mut s = String::new(); f.read_to_string(&mut s).unwrap(); - let docs = load_from_str(&s).unwrap(); + let docs = Yaml::load_from_str(&s).unwrap(); for doc in &docs { println!("---"); dump_node(doc, 0); diff --git a/saphyr/src/annotated/marked_yaml.rs b/saphyr/src/annotated/marked_yaml.rs index 1c86072..dcc73dc 100644 --- a/saphyr/src/annotated/marked_yaml.rs +++ b/saphyr/src/annotated/marked_yaml.rs @@ -30,19 +30,19 @@ impl MarkedYaml { /// # Errors /// Returns `ScanError` when loading fails. /// - /// [`load_from_str`]: `crate::load_from_str` + /// [`load_from_str`]: `Yaml::load_from_str` pub fn load_from_str(source: &str) -> Result, ScanError> { Self::load_from_iter(source.chars()) } /// Load the contents of the given iterator as an array of YAML documents. /// - /// See the function [`load_from_iter`] for more details. + /// See the function [`load_from_str`] for more details. /// /// # Errors /// Returns `ScanError` when loading fails. /// - /// [`load_from_iter`]: `crate::load_from_iter` + /// [`load_from_str`]: `Yaml::load_from_str` pub fn load_from_iter>(source: I) -> Result, ScanError> { let mut parser = Parser::new(source); Self::load_from_parser(&mut parser) @@ -50,12 +50,12 @@ impl MarkedYaml { /// Load the contents from the specified [`Parser`] as an array of YAML documents. /// - /// See the function [`load_from_parser`] for more details. + /// See the function [`load_from_str`] for more details. /// /// # Errors /// Returns `ScanError` when loading fails. /// - /// [`load_from_parser`]: `crate::load_from_parser` + /// [`load_from_str`]: `Yaml::load_from_str` pub fn load_from_parser>( parser: &mut Parser, ) -> Result, ScanError> { diff --git a/saphyr/src/emitter.rs b/saphyr/src/emitter.rs index 8a7be40..3653f56 100644 --- a/saphyr/src/emitter.rs +++ b/saphyr/src/emitter.rs @@ -36,9 +36,9 @@ impl From for EmitError { /// The YAML serializer. /// /// ``` -/// # use saphyr::{load_from_str, YamlEmitter}; +/// # use saphyr::{Yaml, YamlEmitter}; /// let input_string = "a: b\nc: d"; -/// let yaml = load_from_str(input_string).unwrap(); +/// let yaml = Yaml::load_from_str(input_string).unwrap(); /// /// let mut output = String::new(); /// YamlEmitter::new(&mut output).dump(&yaml[0]).unwrap(); @@ -159,10 +159,10 @@ impl<'a> YamlEmitter<'a> { /// # Examples /// /// ```rust - /// use saphyr::{Yaml, YamlEmitter, load_from_str}; + /// use saphyr::{Yaml, YamlEmitter}; /// /// let input = r#"{foo: "bar!\nbar!", baz: 42}"#; - /// let parsed = load_from_str(input).unwrap(); + /// let parsed = Yaml::load_from_str(input).unwrap(); /// eprintln!("{:?}", parsed); /// /// let mut output = String::new(); @@ -409,12 +409,14 @@ fn need_quotes(string: &str) -> bool { #[cfg(test)] mod test { + use crate::Yaml; + use super::YamlEmitter; #[test] fn test_multiline_string() { let input = r#"{foo: "bar!\nbar!", baz: 42}"#; - let parsed = crate::load_from_str(input).unwrap(); + let parsed = Yaml::load_from_str(input).unwrap(); let mut output = String::new(); let mut emitter = YamlEmitter::new(&mut output); emitter.multiline_strings(true); diff --git a/saphyr/src/encoding.rs b/saphyr/src/encoding.rs index 17dcb69..b5e3cd3 100644 --- a/saphyr/src/encoding.rs +++ b/saphyr/src/encoding.rs @@ -102,7 +102,7 @@ impl YamlDecoder { // Decode the input buffer. decode_loop(&buffer, &mut output, &mut decoder, self.trap)?; - crate::load_from_str(&output).map_err(LoadError::Scan) + Yaml::load_from_str(&output).map_err(LoadError::Scan) } } diff --git a/saphyr/src/lib.rs b/saphyr/src/lib.rs index 1f431f3..5309312 100644 --- a/saphyr/src/lib.rs +++ b/saphyr/src/lib.rs @@ -21,9 +21,9 @@ //! Parse a string into `Vec` and then serialize it as a YAML string. //! //! ``` -//! use saphyr::{load_from_str, YamlEmitter}; +//! use saphyr::{Yaml, YamlEmitter}; //! -//! let docs = load_from_str("[1, 2, 3]").unwrap(); +//! let docs = Yaml::load_from_str("[1, 2, 3]").unwrap(); //! let doc = &docs[0]; // select the first YAML document //! assert_eq!(doc[0].as_i64().unwrap(), 1); // access elements by index //! @@ -56,9 +56,7 @@ pub use crate::annotated::{ marked_yaml::MarkedYaml, AnnotatedArray, AnnotatedHash, AnnotatedYamlIter, YamlData, }; pub use crate::emitter::YamlEmitter; -pub use crate::loader::{ - load_from_iter, load_from_parser, load_from_str, LoadableYamlNode, YamlLoader, -}; +pub use crate::loader::{LoadableYamlNode, YamlLoader}; pub use crate::yaml::{Array, Hash, Yaml, YamlIter}; #[cfg(feature = "encoding")] diff --git a/saphyr/src/loader.rs b/saphyr/src/loader.rs index d6ececd..188512a 100644 --- a/saphyr/src/loader.rs +++ b/saphyr/src/loader.rs @@ -3,67 +3,10 @@ use std::collections::BTreeMap; use hashlink::LinkedHashMap; -use saphyr_parser::{Event, MarkedEventReceiver, Marker, Parser, ScanError, TScalarStyle, Tag}; +use saphyr_parser::{Event, MarkedEventReceiver, Marker, ScanError, TScalarStyle, Tag}; use crate::{Hash, Yaml}; -/// Load the given string as an array of YAML documents. -/// -/// The `source` is interpreted as YAML documents and is parsed. Parsing succeeds if and only -/// if all documents are parsed successfully. An error in a latter document prevents the former -/// from being returned. -/// -/// Most often, only one document is loaded in a YAML string. In this case, only the first element -/// of the returned `Vec` will be used. Otherwise, each element in the `Vec` is a document: -/// -/// ``` -/// use saphyr::{load_from_str, Yaml}; -/// -/// let docs = load_from_str(r#" -/// First document -/// --- -/// - Second document -/// "#).unwrap(); -/// let first_document = &docs[0]; // Select the first YAML document -/// // The document is a string containing "First document". -/// assert_eq!(*first_document, Yaml::String("First document".to_owned())); -/// -/// let second_document = &docs[1]; // Select the second YAML document -/// // The document is an array containing a single string, "Second document". -/// assert_eq!(second_document[0], Yaml::String("Second document".to_owned())); -/// ``` -/// -/// # Errors -/// Returns `ScanError` when loading fails. -pub fn load_from_str(source: &str) -> Result, ScanError> { - load_from_iter(source.chars()) -} - -/// Load the contents of the given iterator as an array of YAML documents. -/// -/// See [`load_from_str`] for details. -/// -/// # Errors -/// Returns `ScanError` when loading fails. -pub fn load_from_iter>(source: I) -> Result, ScanError> { - let mut parser = Parser::new(source); - load_from_parser(&mut parser) -} - -/// Load the contents from the specified [`Parser`] as an array of YAML documents. -/// -/// See [`load_from_str`] for details. -/// -/// # Errors -/// Returns `ScanError` when loading fails. -pub fn load_from_parser>( - parser: &mut Parser, -) -> Result, ScanError> { - let mut loader = YamlLoader::default(); - parser.load(&mut loader, true)?; - Ok(loader.docs) -} - /// Main structure for parsing YAML. /// /// The `YamlLoader` may load raw YAML documents or add metadata if needed. The type of the `Node` diff --git a/saphyr/src/yaml.rs b/saphyr/src/yaml.rs index f15ba00..581d5d7 100644 --- a/saphyr/src/yaml.rs +++ b/saphyr/src/yaml.rs @@ -5,8 +5,9 @@ use std::{convert::TryFrom, ops::Index, ops::IndexMut}; use hashlink::LinkedHashMap; +use saphyr_parser::{Parser, ScanError}; -use crate::loader::parse_f64; +use crate::{loader::parse_f64, YamlLoader}; /// A YAML node is stored as this `Yaml` enumeration, which provides an easy way to /// access your YAML document. @@ -57,6 +58,63 @@ pub type Array = Vec; pub type Hash = LinkedHashMap; impl Yaml { + /// Load the given string as an array of YAML documents. + /// + /// The `source` is interpreted as YAML documents and is parsed. Parsing succeeds if and only + /// if all documents are parsed successfully. An error in a latter document prevents the former + /// from being returned. + /// + /// Most often, only one document is loaded in a YAML string. In this case, only the first element + /// of the returned `Vec` will be used. Otherwise, each element in the `Vec` is a document: + /// + /// ``` + /// use saphyr::Yaml; + /// + /// let docs = Yaml::load_from_str(r#" + /// First document + /// --- + /// - Second document + /// "#).unwrap(); + /// let first_document = &docs[0]; // Select the first YAML document + /// // The document is a string containing "First document". + /// assert_eq!(*first_document, Yaml::String("First document".to_owned())); + /// + /// let second_document = &docs[1]; // Select the second YAML document + /// // The document is an array containing a single string, "Second document". + /// assert_eq!(second_document[0], Yaml::String("Second document".to_owned())); + /// ``` + /// + /// # Errors + /// Returns `ScanError` when loading fails. + pub fn load_from_str(source: &str) -> Result, ScanError> { + Self::load_from_iter(source.chars()) + } + + /// Load the contents of the given iterator as an array of YAML documents. + /// + /// See [`Self::load_from_str`] for details. + /// + /// # Errors + /// Returns `ScanError` when loading fails. + pub fn load_from_iter>(source: I) -> Result, ScanError> { + let mut parser = Parser::new(source); + Self::load_from_parser(&mut parser) + } + + /// Load the contents from the specified [`Parser`] as an array of YAML documents. + /// + /// See [`Self::load_from_str`] for details. + /// + /// # Errors + /// Returns `ScanError` when loading fails. + pub fn load_from_parser>( + parser: &mut Parser, + ) -> Result, ScanError> { + let mut loader = YamlLoader::default(); + parser.load(&mut loader, true)?; + Ok(loader.into_documents()) + } + define_as!(as_bool, bool, Boolean); define_as!(as_i64, i64, Integer); diff --git a/saphyr/tests/basic.rs b/saphyr/tests/basic.rs index 6a20c4d..7a97c77 100644 --- a/saphyr/tests/basic.rs +++ b/saphyr/tests/basic.rs @@ -1,7 +1,7 @@ #![allow(clippy::bool_assert_comparison)] #![allow(clippy::float_cmp)] -use saphyr::{load_from_str, Yaml, YamlEmitter}; +use saphyr::{Yaml, YamlEmitter}; #[test] fn test_api() { @@ -29,7 +29,7 @@ fn test_api() { - name: Staff damage: 3 "; - let docs = load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); let doc = &docs[0]; assert_eq!(doc[0]["name"].as_str().unwrap(), "Ogre"); @@ -50,7 +50,7 @@ a: 1 b: 2.2 c: [1, 2] "; - let out = load_from_str(s).unwrap(); + let out = Yaml::load_from_str(s).unwrap(); let doc = &out[0]; assert_eq!(doc["a"].as_i64().unwrap(), 1i64); assert_eq!(doc["b"].as_f64().unwrap(), 2.2f64); @@ -66,7 +66,7 @@ a1: &DEFAULT b2: d a2: *DEFAULT "; - let out = load_from_str(s).unwrap(); + let out = Yaml::load_from_str(s).unwrap(); let doc = &out[0]; assert_eq!(doc["a2"]["b1"].as_i64().unwrap(), 4); } @@ -78,7 +78,7 @@ a1: &DEFAULT b1: 4 b2: *DEFAULT "; - let out = load_from_str(s).unwrap(); + let out = Yaml::load_from_str(s).unwrap(); let doc = &out[0]; assert_eq!(doc["a1"]["b2"], Yaml::BadValue); } @@ -114,7 +114,7 @@ fn test_plain_datatype() { - +12345 - [ true, false ] "; - let out = load_from_str(s).unwrap(); + let out = Yaml::load_from_str(s).unwrap(); let doc = &out[0]; assert_eq!(doc[0].as_str().unwrap(), "string"); @@ -171,7 +171,7 @@ fn test_plain_datatype_with_into_methods() { - .NAN - !!float .INF "; - let mut out = load_from_str(s).unwrap().into_iter(); + let mut out = Yaml::load_from_str(s).unwrap().into_iter(); let mut doc = out.next().unwrap().into_iter(); assert_eq!(doc.next().unwrap().into_string().unwrap(), "string"); @@ -203,7 +203,7 @@ b: ~ a: ~ c: ~ "; - let out = load_from_str(s).unwrap(); + let out = Yaml::load_from_str(s).unwrap(); let first = out.into_iter().next().unwrap(); let mut iter = first.into_hash().unwrap().into_iter(); assert_eq!( @@ -229,7 +229,7 @@ fn test_integer_key() { 1: important: false "; - let out = load_from_str(s).unwrap(); + let out = Yaml::load_from_str(s).unwrap(); let first = out.into_iter().next().unwrap(); assert_eq!(first[0]["important"].as_bool().unwrap(), true); } diff --git a/saphyr/tests/emitter.rs b/saphyr/tests/emitter.rs index 142713e..fdf1acb 100644 --- a/saphyr/tests/emitter.rs +++ b/saphyr/tests/emitter.rs @@ -1,4 +1,4 @@ -use saphyr::{load_from_str, YamlEmitter}; +use saphyr::{Yaml, YamlEmitter}; #[allow(clippy::similar_names)] #[test] @@ -16,7 +16,7 @@ a4: - 2 "; - let docs = load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); let doc = &docs[0]; let mut writer = String::new(); { @@ -25,7 +25,7 @@ a4: } println!("original:\n{s}"); println!("emitted:\n{writer}"); - let docs_new = match load_from_str(&writer) { + let docs_new = match Yaml::load_from_str(&writer) { Ok(y) => y, Err(e) => panic!("{}", e), }; @@ -55,14 +55,14 @@ products: {}: empty hash key "; - let docs = load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); let doc = &docs[0]; let mut writer = String::new(); { let mut emitter = YamlEmitter::new(&mut writer); emitter.dump(doc).unwrap(); } - let docs_new = match load_from_str(&writer) { + let docs_new = match Yaml::load_from_str(&writer) { Ok(y) => y, Err(e) => panic!("{}", e), }; @@ -106,7 +106,7 @@ x: test y: avoid quoting here z: string with spaces"#; - let docs = load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); let doc = &docs[0]; let mut writer = String::new(); { @@ -164,7 +164,7 @@ null0: ~ bool0: true bool1: false"#; - let docs = load_from_str(input).unwrap(); + let docs = Yaml::load_from_str(input).unwrap(); let doc = &docs[0]; let mut writer = String::new(); { @@ -212,7 +212,7 @@ e: h: []" }; - let docs = load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); let doc = &docs[0]; let mut writer = String::new(); { @@ -234,7 +234,7 @@ a: - - e - f"; - let docs = load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); let doc = &docs[0]; let mut writer = String::new(); { @@ -258,7 +258,7 @@ a: - - f - - e"; - let docs = load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); let doc = &docs[0]; let mut writer = String::new(); { @@ -280,7 +280,7 @@ a: d: e: f"; - let docs = load_from_str(s).unwrap(); + let docs = Yaml::load_from_str(s).unwrap(); let doc = &docs[0]; let mut writer = String::new(); { diff --git a/saphyr/tests/quickcheck.rs b/saphyr/tests/quickcheck.rs index 7c91601..666739c 100644 --- a/saphyr/tests/quickcheck.rs +++ b/saphyr/tests/quickcheck.rs @@ -3,7 +3,7 @@ extern crate quickcheck; use quickcheck::TestResult; -use saphyr::{load_from_str, Yaml, YamlEmitter}; +use saphyr::{Yaml, YamlEmitter}; quickcheck! { fn test_check_weird_keys(xs: Vec) -> TestResult { @@ -13,7 +13,7 @@ quickcheck! { let mut emitter = YamlEmitter::new(&mut out_str); emitter.dump(&input).unwrap(); } - match load_from_str(&out_str) { + match Yaml::load_from_str(&out_str) { Ok(output) => TestResult::from_bool(output.len() == 1 && input == output[0]), Err(err) => TestResult::error(err.to_string()), } diff --git a/saphyr/tests/spec_test.rs b/saphyr/tests/spec_test.rs index 52a0551..1cf98e5 100644 --- a/saphyr/tests/spec_test.rs +++ b/saphyr/tests/spec_test.rs @@ -1,4 +1,4 @@ -use saphyr::{load_from_str, Hash, Yaml, YamlEmitter}; +use saphyr::{Hash, Yaml, YamlEmitter}; #[test] fn test_mapvec_legal() { @@ -53,5 +53,5 @@ fn test_mapvec_legal() { // - 6 // ``` - load_from_str(&out_str).unwrap(); + Yaml::load_from_str(&out_str).unwrap(); } diff --git a/saphyr/tests/test_round_trip.rs b/saphyr/tests/test_round_trip.rs index f1b2838..e4ada73 100644 --- a/saphyr/tests/test_round_trip.rs +++ b/saphyr/tests/test_round_trip.rs @@ -1,10 +1,10 @@ -use saphyr::{load_from_str, Yaml, YamlEmitter}; +use saphyr::{Yaml, YamlEmitter}; fn roundtrip(original: &Yaml) { let mut emitted = String::new(); YamlEmitter::new(&mut emitted).dump(original).unwrap(); - let documents = load_from_str(&emitted).unwrap(); + let documents = Yaml::load_from_str(&emitted).unwrap(); println!("emitted {emitted}"); assert_eq!(documents.len(), 1); @@ -12,12 +12,12 @@ fn roundtrip(original: &Yaml) { } fn double_roundtrip(original: &str) { - let parsed = load_from_str(original).unwrap(); + let parsed = Yaml::load_from_str(original).unwrap(); let mut serialized = String::new(); YamlEmitter::new(&mut serialized).dump(&parsed[0]).unwrap(); - let reparsed = load_from_str(&serialized).unwrap(); + let reparsed = Yaml::load_from_str(&serialized).unwrap(); assert_eq!(parsed, reparsed); } @@ -55,12 +55,12 @@ fn test_numberlike_strings() { /// Example from #[test] fn test_issue133() { - let doc = load_from_str("\"0x123\"").unwrap().pop().unwrap(); + let doc = Yaml::load_from_str("\"0x123\"").unwrap().pop().unwrap(); assert_eq!(doc, Yaml::String("0x123".to_string())); let mut out_str = String::new(); YamlEmitter::new(&mut out_str).dump(&doc).unwrap(); - let doc2 = load_from_str(&out_str).unwrap().pop().unwrap(); + let doc2 = Yaml::load_from_str(&out_str).unwrap().pop().unwrap(); assert_eq!(doc, doc2); // This failed because the type has changed to a number now }