rs_pgcopy2cbor/
row.rs

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}