1use std::io;
2use std::io::BufReader;
3use std::io::BufWriter;
4use std::io::Read;
5use std::io::Write;
6
7use ciborium::ser::Error as SerErr;
8use ciborium::Value;
9
10use crate::col::Col;
11use crate::hdr::Header;
12
13#[derive(Default)]
14pub struct Row {
15 pub cols: Vec<Col>,
16}
17
18impl Row {
19 pub fn from_rdr<R>(rdr: &mut R) -> Result<Option<Self>, io::Error>
20 where
21 R: Read,
22 {
23 let mut buf: [u8; 2] = [0; 2];
24 rdr.read_exact(&mut buf)?;
25 let fcnt: i16 = i16::from_be_bytes(buf);
26 match fcnt {
27 -1 => Ok(None),
28 _ => {
29 let mut row: Row = Row {
30 cols: Vec::with_capacity(fcnt as usize),
31 };
32 for _ in 0..fcnt {
33 let col: Col = Col::from_rdr(rdr)?;
34 row.cols.push(col);
35 }
36 Ok(Some(row))
37 }
38 }
39 }
40}
41
42impl Row {
43 pub fn into_cbor_values(self) -> Vec<Value> {
44 self.cols
45 .into_iter()
46 .map(|c: Col| c.into_cbor_value())
47 .collect()
48 }
49
50 pub fn into_cbor_value(self) -> Value {
51 let vals: Vec<Value> = self.into_cbor_values();
52 Value::Array(vals)
53 }
54}
55
56impl Row {
57 pub fn into_writer<W>(self, wtr: &mut W) -> Result<(), io::Error>
58 where
59 W: Write,
60 {
61 let val: Value = self.into_cbor_value();
62 ciborium::into_writer(&val, wtr).map_err(|e| match e {
63 SerErr::Io(ie) => ie,
64 SerErr::Value(s) => io::Error::other(s),
65 })
66 }
67}
68
69pub fn rdr2wtr<R, W>(rdr: &mut R, wtr: &mut W) -> Result<(), io::Error>
70where
71 R: Read,
72 W: Write,
73{
74 Header::from_rdr_no_validation(rdr)?;
75 loop {
76 let orow: Option<Row> = Row::from_rdr(rdr)?;
77 match orow {
78 None => {
79 wtr.flush()?;
80 return Ok(());
81 }
82 Some(row) => {
83 row.into_writer(wtr)?;
84 }
85 }
86 }
87}
88
89pub fn stdin2stdout() -> Result<(), io::Error> {
90 let i = io::stdin();
91 let il = i.lock();
92 let mut br = BufReader::new(il);
93
94 let o = io::stdout();
95 let mut ol = o.lock();
96 {
97 let mut bw = BufWriter::new(ol.by_ref());
98 rdr2wtr(&mut br, &mut bw)?;
99 bw.flush()?;
100 }
101 ol.flush()?;
102 Ok(())
103}