1use std::io::{self, BufRead, BufReader, Write};
4use std::str;
5
6use serde::{de, ser};
7
8use crate::input::{self, Input, Ref};
9use crate::transcode;
10
11mod chunker;
12mod encoding;
13
14use self::chunker::Chunker;
15use self::encoding::{Encoder, Encoding};
16
17pub(crate) fn input_matches(mut input: Ref) -> io::Result<bool> {
18 let encoding = Encoding::detect(input.prefix(Encoding::DETECT_LEN)?);
24 let chunk = match &mut input {
25 Ref::Slice(b) => Chunker::new(Encoder::new(b, encoding)).next(),
26 Ref::Reader(r) => Chunker::new(Encoder::new(BufReader::new(r), encoding)).next(),
27 };
28 match chunk {
29 Some(Ok(doc)) => Ok(doc.is_collection()),
30 Some(Err(err)) if err.kind() == io::ErrorKind::InvalidData => Ok(false),
31 Some(Err(err)) => Err(err),
32 None => Ok(false),
33 }
34}
35
36pub(crate) fn transcode<O>(input: input::Handle, mut output: O) -> crate::Result<()>
37where
38 O: crate::Output,
39{
40 match input.into() {
41 Input::Reader(r) => transcode_reader(BufReader::new(r), output),
42 Input::Slice(b) => match str::from_utf8(&b) {
43 Ok(s) => {
44 for de in serde_yaml::Deserializer::from_str(s) {
45 output.transcode_from(de)?;
46 }
47 Ok(())
48 }
49 Err(_) => {
50 transcode_reader(&*b, output)
53 }
54 },
55 }
56}
57
58fn transcode_reader<R, O>(input: R, mut output: O) -> crate::Result<()>
59where
60 R: BufRead,
61 O: crate::Output,
62{
63 for doc in Chunker::new(Encoder::from_reader(input)?) {
84 let doc = doc?;
85 let de = serde_yaml::Deserializer::from_str(doc.content());
86 output.transcode_from(de)?;
87 }
88 Ok(())
89}
90
91pub(crate) struct Output<W: Write>(W);
92
93impl<W: Write> Output<W> {
94 pub(crate) fn new(w: W) -> Output<W> {
95 Output(w)
96 }
97}
98
99impl<W: Write> crate::Output for Output<W> {
100 fn transcode_from<'de, D, E>(&mut self, de: D) -> crate::Result<()>
101 where
102 D: de::Deserializer<'de, Error = E>,
103 E: de::Error + Send + Sync + 'static,
104 {
105 writeln!(&mut self.0, "---")?;
106 let mut ser = serde_yaml::Serializer::new(&mut self.0);
107 transcode::transcode(&mut ser, de)?;
108 Ok(())
109 }
110
111 fn transcode_value<S>(&mut self, value: S) -> crate::Result<()>
112 where
113 S: ser::Serialize,
114 {
115 writeln!(&mut self.0, "---")?;
116 serde_yaml::to_writer(&mut self.0, &value)?;
117 Ok(())
118 }
119
120 fn flush(&mut self) -> io::Result<()> {
121 self.0.flush()
122 }
123}