rust_strings/
strings_writer.rs

1use std::io::Write;
2use std::mem::take;
3
4use crate::ErrorResult;
5
6pub trait StringWriter {
7    fn start_string_consume(&mut self, string: Vec<u8>, offset: u64) -> ErrorResult;
8    fn write_char(&mut self, c: char) -> ErrorResult;
9    fn finish_string_consume(&mut self) -> ErrorResult;
10}
11
12pub struct VectorWriter {
13    vec: Vec<(String, u64)>,
14    current_string: String,
15    current_offset: u64,
16}
17
18impl VectorWriter {
19    pub fn new() -> Self {
20        VectorWriter {
21            vec: vec![],
22            current_offset: 0,
23            current_string: String::new(),
24        }
25    }
26}
27
28impl StringWriter for VectorWriter {
29    fn start_string_consume(&mut self, string: Vec<u8>, offset: u64) -> ErrorResult {
30        self.current_offset = offset;
31        self.current_string = String::with_capacity(string.len());
32        string
33            .into_iter()
34            .for_each(|c| self.current_string.push(c as char));
35        Ok(())
36    }
37
38    fn write_char(&mut self, c: char) -> ErrorResult {
39        self.current_string.push(c);
40        Ok(())
41    }
42
43    fn finish_string_consume(&mut self) -> ErrorResult {
44        if self.current_string.is_empty() {
45            return Ok(());
46        }
47        let string = take(&mut self.current_string);
48        self.vec.push((string, self.current_offset));
49        Ok(())
50    }
51}
52
53impl VectorWriter {
54    pub fn get_strings(&mut self) -> Vec<(String, u64)> {
55        take(&mut self.vec)
56    }
57}
58
59pub struct JsonWriter<T> {
60    writer: T,
61    current_offset: u64,
62    is_start_writing: bool,
63    is_first_element: bool,
64}
65
66impl<T> StringWriter for JsonWriter<T>
67where
68    T: Write,
69{
70    fn start_string_consume(&mut self, string: Vec<u8>, offset: u64) -> ErrorResult {
71        self.current_offset = offset;
72        for ch in string.into_iter() {
73            self.write_chars_to_writer(ch)?;
74        }
75        Ok(())
76    }
77
78    fn write_char(&mut self, c: char) -> ErrorResult {
79        self.write_chars_to_writer(c as u8)
80    }
81
82    fn finish_string_consume(&mut self) -> ErrorResult {
83        self.writer.write_all(b"\",")?;
84        self.writer
85            .write_all(format!("{}", self.current_offset).as_bytes())?;
86        self.writer.write_all(b"]")?;
87        self.is_start_writing = false;
88        Ok(())
89    }
90}
91
92impl<T> JsonWriter<T>
93where
94    T: Write,
95{
96    pub fn new(writer: T) -> Self {
97        JsonWriter {
98            writer,
99            current_offset: 0,
100            is_start_writing: false,
101            is_first_element: true,
102        }
103    }
104
105    pub fn finish(&mut self) -> ErrorResult {
106        self.writer.write_all(b"]")?;
107        Ok(())
108    }
109
110    fn write_chars_to_writer(&mut self, c: u8) -> ErrorResult {
111        if !self.is_start_writing {
112            self.is_start_writing = true;
113            if self.is_first_element {
114                // Start writing the first element, needs to write `[["`
115                self.writer.write_all(b"[[\"")?;
116                self.is_first_element = false;
117            } else {
118                // Start writing current string, needs to write `,["`
119                self.writer.write_all(b",[\"")?;
120            }
121        }
122        let v = self.escape_json_character(c);
123        self.writer.write_all(&v)?;
124        Ok(())
125    }
126
127    fn escape_json_character(&self, c: u8) -> Vec<u8> {
128        match c as char {
129            '\n' => b"\\n".to_vec(),
130            '\t' => b"\\t".to_vec(),
131            '\r' => b"\\r".to_vec(),
132            '"' => b"\\\"".to_vec(),
133            '\\' => b"\\\\".to_vec(),
134            _ => vec![c],
135        }
136    }
137}