1use std::io;
2
3use cbor2::de::Deserializer;
4use cbor2::value::Value as CborValue;
5
6pub fn import_from_reader<R: io::Read, W: io::Write>(
32 input_format: &str,
33 mut reader: R,
34 writer: &mut W,
35) -> anyhow::Result<()> {
36 match input_format {
37 "json" => {
38 for v in serde_json::de::Deserializer::from_reader(reader).into_iter::<serde_json::Value>() {
39 let v = v?;
40 cbor2::to_writer(&v, &mut *writer)?;
41 }
42 }
43 "yaml" => {
44 let result: serde_yaml::Value = serde_yaml::from_reader(reader)?;
45 cbor2::to_writer(&result, writer)?;
46 }
47 "toml" => {
48 let mut s = String::new();
49 reader.read_to_string(&mut s)?;
50 let result: toml::Value = toml::de::from_str(&s)?;
51 cbor2::to_writer(&result, writer)?;
52 }
53 _ => {
54 for v in Deserializer::from_reader(reader).into_iter::<CborValue>() {
56 let v = v?;
57 cbor2::to_writer(&v, &mut *writer)?;
58 }
59 }
60 }
61 Ok(())
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn test_import_array() {
70 let cases = [
71 ("json", &b"[1,2]"[..], vec![0x82, 0x01, 0x02]),
72 ("yaml", &b"- 1\n- 2\n"[..], vec![0x82, 0x01, 0x02]),
73 ("cbor", &b"\x82\x01\x02"[..], vec![0x82, 0x01, 0x02]),
74 ];
75 for (format, input, expected) in cases {
76 let mut output = Vec::new();
77 import_from_reader(format, input, &mut output).unwrap();
78 assert_eq!(output, expected, "format: {format}");
79 }
80 }
81
82 #[test]
83 fn test_import_map_from_toml() {
84 let input = b"foo = 1\nbar = 2\n";
85 let mut output = Vec::new();
86 import_from_reader("toml", &input[..], &mut output).unwrap();
87 assert_eq!(output, vec![0xa2, 0x63, 0x66, 0x6f, 0x6f, 0x01, 0x63, 0x62, 0x61, 0x72, 0x02]);
89 }
90
91 #[test]
92 fn test_import_invalid_json() {
93 let input = b"not json";
94 let mut output = Vec::new();
95 let err = import_from_reader("json", &input[..], &mut output).unwrap_err();
96 assert!(!err.to_string().is_empty(), "error should be non-empty: {err}");
97 }
98}