1use reliakit_csv::{
6 from_csv_str, read_str, to_csv_string, CsvDecode, CsvDecodeError, CsvEncode, CsvField,
7 CsvWriter,
8};
9
10#[derive(Debug, PartialEq)]
11struct Service {
12 name: String,
13 port: u16,
14 enabled: bool,
15}
16
17impl CsvEncode for Service {
18 fn header() -> Vec<&'static str> {
19 vec!["name", "port", "enabled"]
20 }
21
22 fn encode_fields(&self, out: &mut Vec<String>) {
23 out.push(self.name.encode_field());
24 out.push(self.port.encode_field());
25 out.push(self.enabled.encode_field());
26 }
27}
28
29impl CsvDecode for Service {
30 fn decode_fields(fields: &[&str]) -> Result<Self, CsvDecodeError> {
31 if fields.len() != 3 {
32 return Err(CsvDecodeError::field_count());
33 }
34 Ok(Service {
35 name: String::decode_field(fields[0]).map_err(|e| e.at_field(0))?,
36 port: u16::decode_field(fields[1]).map_err(|e| e.at_field(1))?,
37 enabled: bool::decode_field(fields[2]).map_err(|e| e.at_field(2))?,
38 })
39 }
40}
41
42fn main() {
43 let rows = read_str("a,b\n1,2\n").unwrap();
45 println!("rows: {rows:?}");
46
47 let mut writer = CsvWriter::new();
49 writer.write_record(["plain", "needs,quote"]);
50 print!("written: {}", writer.into_string());
51
52 let services = vec![
54 Service {
55 name: "api".into(),
56 port: 8080,
57 enabled: true,
58 },
59 Service {
60 name: "worker, west".into(),
61 port: 9000,
62 enabled: false,
63 },
64 ];
65 let text = to_csv_string(&services);
66 print!("encoded:\n{text}");
67
68 let decoded: Vec<Service> = from_csv_str(&text).unwrap();
69 assert_eq!(decoded, services);
70 println!("round-trip ok: {} record(s)", decoded.len());
71}