Skip to content

Commit 7a19865

Browse files
committed
Use a YamlDecoder builder to implement optional encoding_trap parameter.
1 parent b2d648e commit 7a19865

1 file changed

Lines changed: 54 additions & 18 deletions

File tree

src/yaml.rs

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -210,22 +210,42 @@ impl YamlLoader {
210210
parser.load(&mut loader, true)?;
211211
Ok(loader.docs)
212212
}
213+
}
213214

214-
pub fn load_from_bytes(mut source: impl std::io::Read) -> Result<Vec<Yaml>, LoadError> {
215-
let mut buffer = Vec::new();
216-
source.read_to_end(&mut buffer)?;
217-
218-
// Decodes the input buffer using either UTF-8, UTF-16LE or UTF-16BE depending on the BOM codepoint.
219-
// If the buffer doesn't start with a BOM codepoint, it will use a fallback encoding obtained by
220-
// detect_utf16_endianness.
221-
let (res, _) = encoding::types::decode(
222-
&buffer,
223-
encoding::DecoderTrap::Strict,
224-
detect_utf16_endianness(&buffer),
225-
);
226-
let s = res.map_err(LoadError::Decode)?;
227-
YamlLoader::load_from_str(&s).map_err(LoadError::Scan)
215+
pub struct YamlDecoder<T: std::io::Read> {
216+
source: T,
217+
trap: encoding::types::DecoderTrap,
218+
}
219+
220+
221+
impl<T: std::io::Read> YamlDecoder<T> {
222+
pub fn read(source: T) -> YamlDecoder<T> {
223+
YamlDecoder{
224+
source: source,
225+
trap: encoding::DecoderTrap::Strict,
228226
}
227+
}
228+
229+
pub fn encoding_trap(mut self, trap: encoding::types::DecoderTrap) -> YamlDecoder<T> {
230+
self.trap = trap;
231+
self
232+
}
233+
234+
pub fn decode(mut self) -> Result<Vec<Yaml>, LoadError> {
235+
let mut buffer = Vec::new();
236+
self.source.read_to_end(&mut buffer)?;
237+
238+
// Decodes the input buffer using either UTF-8, UTF-16LE or UTF-16BE depending on the BOM codepoint.
239+
// If the buffer doesn't start with a BOM codepoint, it will use a fallback encoding obtained by
240+
// detect_utf16_endianness.
241+
let (res, _) = encoding::types::decode(
242+
&buffer,
243+
self.trap,
244+
detect_utf16_endianness(&buffer),
245+
);
246+
let s = res.map_err(LoadError::Decode)?;
247+
YamlLoader::load_from_str(&s).map_err(LoadError::Scan)
248+
}
229249
}
230250

231251
/// The encoding crate knows how to tell apart UTF-8 from UTF-16LE and utf-16BE, when the
@@ -793,7 +813,7 @@ a: 1
793813
b: 2.2
794814
c: [1, 2]
795815
";
796-
let out = YamlLoader::load_from_bytes(s as &[u8]).unwrap();
816+
let out = YamlDecoder::read(s as &[u8]).decode().unwrap();
797817
let doc = &out[0];
798818
assert_eq!(doc["a"].as_i64().unwrap(), 1i64);
799819
assert_eq!(doc["b"].as_f64().unwrap(), 2.2f64);
@@ -808,7 +828,7 @@ c: [1, 2]
808828
\x00b\x00:\x00 \x002\x00.\x002\x00
809829
\x00c\x00:\x00 \x00[\x001\x00,\x00 \x002\x00]\x00
810830
\x00";
811-
let out = YamlLoader::load_from_bytes(s as &[u8]).unwrap();
831+
let out = YamlDecoder::read(s as &[u8]).decode().unwrap();
812832
let doc = &out[0];
813833
println!("GOT: {:?}", doc);
814834
assert_eq!(doc["a"].as_i64().unwrap(), 1i64);
@@ -824,7 +844,7 @@ c: [1, 2]
824844
\x00b\x00:\x00 \x002\x00.\x002\x00
825845
\x00c\x00:\x00 \x00[\x001\x00,\x00 \x002\x00]\x00
826846
";
827-
let out = YamlLoader::load_from_bytes(s as &[u8]).unwrap();
847+
let out = YamlDecoder::read(s as &[u8]).decode().unwrap();
828848
let doc = &out[0];
829849
println!("GOT: {:?}", doc);
830850
assert_eq!(doc["a"].as_i64().unwrap(), 1i64);
@@ -840,7 +860,23 @@ c: [1, 2]
840860
\x00b\x00:\x00 \x002\x00.\x002\x00
841861
\x00c\x00:\x00 \x00[\x001\x00,\x00 \x002\x00]\x00
842862
\x00";
843-
let out = YamlLoader::load_from_bytes(s as &[u8]).unwrap();
863+
let out = YamlDecoder::read(s as &[u8]).decode().unwrap();
864+
let doc = &out[0];
865+
println!("GOT: {:?}", doc);
866+
assert_eq!(doc["a"].as_i64().unwrap(), 1i64);
867+
assert_eq!(doc["b"].as_f64().unwrap(), 2.2f64);
868+
assert_eq!(doc["c"][1].as_i64().unwrap(), 2i64);
869+
assert!(doc["d"][0].is_badvalue());
870+
}
871+
872+
#[test]
873+
fn test_read_trap() {
874+
let s = b"---
875+
a\xa9: 1
876+
b: 2.2
877+
c: [1, 2]
878+
";
879+
let out = YamlDecoder::read(s as &[u8]).encoding_trap(encoding::DecoderTrap::Ignore).decode().unwrap();
844880
let doc = &out[0];
845881
println!("GOT: {:?}", doc);
846882
assert_eq!(doc["a"].as_i64().unwrap(), 1i64);

0 commit comments

Comments
 (0)