1#[cfg(feature = "serde")]
2pub mod de;
3pub mod error;
4pub mod fmt;
5pub mod from;
6pub mod index;
7pub mod mapping;
8pub mod number;
9pub mod partial_eq;
10#[cfg(feature = "serde")]
11pub mod ser;
12pub mod spanned;
13pub mod tag;
14pub mod value;
15
16pub use error::{Error, ParseError};
17pub use mapping::Mapping;
18pub use number::Number;
19#[cfg(feature = "serde")]
20pub use ser::value::Serializer;
21pub use spanned::Spanned;
22pub use tag::{Tag, TaggedValue};
23pub use value::{Builder, Sequence, Value};
24
25pub type SpannedValue = Spanned<Value>;
26
27pub struct LossyDocumentDeserializer<R> {
28 builder: Builder,
29 parser: libyaml_safer::Parser<R>,
30}
31
32impl<'b, 'r> LossyDocumentDeserializer<&'b mut &'r [u8]>
33where
34 'b: 'r,
35{
36 pub fn new(value: &'b mut &'r [u8]) -> Self {
37 let mut parser = libyaml_safer::Parser::new();
38 parser.set_input_string(value);
39
40 let builder = Builder::default();
41 Self { builder, parser }
42 }
43}
44
45impl<R> std::iter::Iterator for LossyDocumentDeserializer<R>
46where
47 R: std::io::BufRead,
48{
49 type Item = Result<(Spanned<Value>, Vec<ParseError>), Error>;
50
51 fn next(&mut self) -> Option<Self::Item> {
52 let mut errors = vec![];
53
54 match libyaml_safer::Document::load(&mut self.parser) {
55 Ok(document) if document.nodes.is_empty() => None,
56 Ok(mut document) => Some(
57 self.builder
58 .from_document(&mut document, &mut errors)
59 .map(|value| (value, errors))
60 .map_err(Error::from),
61 ),
62 Err(err) => Some(Err(err.into())),
63 }
64 }
65}
66
67pub fn from_str_lossy_iter<'b, 'r>(
68 value: &'b mut &'r [u8],
69) -> LossyDocumentDeserializer<&'b mut &'r [u8]>
70where
71 'b: 'r,
72{
73 LossyDocumentDeserializer::new(value)
74}
75
76pub fn from_str_lossy_all(value: &str) -> Result<Vec<(Spanned<Value>, Vec<ParseError>)>, Error> {
77 let mut parser = libyaml_safer::Parser::new();
78 let mut bytes = value.as_bytes();
79
80 parser.set_input_string(&mut bytes);
81
82 let builder = Builder::default();
83 let mut documents = vec![];
84 loop {
85 let mut errors = vec![];
86
87 let mut document = match libyaml_safer::Document::load(&mut parser) {
88 Ok(document) if document.nodes.is_empty() => break,
89 Ok(document) => document,
90 Err(err) => return Err(err.into()),
91 };
92 let value: Spanned<Value> = builder.from_document(&mut document, &mut errors)?;
93 documents.push((value, errors));
94 }
95
96 Ok(documents)
97}
98
99pub fn from_str_lossy(value: &str) -> Result<(Spanned<Value>, Vec<ParseError>), Error> {
100 let mut parser = libyaml_safer::Parser::new();
101 let mut bytes = value.as_bytes();
102 parser.set_input_string(&mut bytes);
103
104 let mut document = libyaml_safer::Document::load(&mut parser)?;
105 let mut errors = vec![];
106 let builder = Builder::default();
107 let value: Spanned<Value> = builder.from_document(&mut document, &mut errors)?;
108
109 Ok((value, errors))
110}
111
112pub fn from_str(value: &str) -> Result<Spanned<Value>, Error> {
113 let (value, errors) = from_str_lossy(value)?;
114 if errors.is_empty() {
115 Ok(value)
116 } else {
117 Err(Error::Parse(errors))
118 }
119}
120
121pub fn from_str_all(value: &str) -> Result<Vec<Spanned<Value>>, Error> {
122 let documents = from_str_lossy_all(value)?;
123 let (values, errors): (Vec<_>, Vec<_>) = documents.into_iter().unzip();
124 let errors: Vec<_> = errors.into_iter().flatten().collect();
125 if errors.is_empty() {
126 Ok(values)
127 } else {
128 Err(Error::Parse(errors))
129 }
130}
131
132#[cfg(feature = "serde")]
149pub fn from_value<T>(value: &Value) -> Result<T, error::SerdeError>
150where
151 T: serde::de::DeserializeOwned,
152{
153 serde::Deserialize::deserialize(value)
154}
155
156#[cfg(feature = "serde")]
168pub fn to_value<T>(value: T) -> Result<Value, error::SerdeError>
169where
170 T: serde::Serialize,
171{
172 value.serialize(Serializer)
173}
174
175mod private {
181 pub trait Sealed {}
182 impl Sealed for usize {}
183 impl Sealed for str {}
184 impl Sealed for String {}
185 impl Sealed for crate::value::Value {}
186 impl Sealed for crate::spanned::Spanned<crate::value::Value> {}
187 impl<T> Sealed for &T where T: ?Sized + Sealed {}
188}
189
190#[cfg(test)]
191mod tests {
192 static INIT: std::sync::Once = std::sync::Once::new();
193
194 pub fn init() {
198 INIT.call_once(|| {
199 color_eyre::install().ok();
200 });
201 }
202}