yog_data/binary/
writer.rs1use super::interner::Interner;
4use super::{MAGIC, NEW_STRING, VERSION, tag, varint, zigzag};
5use crate::value::Value;
6
7pub(crate) const START_BYTES: usize = 256;
9
10pub struct Writer {
21 out: Vec<u8>,
22 strings: Interner,
24}
25
26impl Default for Writer {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl Writer {
33 pub fn new() -> Self {
34 let mut out = Vec::with_capacity(START_BYTES);
35 out.extend_from_slice(MAGIC);
36 out.push(VERSION);
37 Writer {
38 out,
39 strings: Interner::new(),
40 }
41 }
42
43 pub fn null(&mut self) -> &mut Self {
44 self.out.push(tag::NULL);
45 self
46 }
47
48 pub fn bool(&mut self, b: bool) -> &mut Self {
49 self.out.push(if b { tag::TRUE } else { tag::FALSE });
50 self
51 }
52
53 pub fn int(&mut self, n: i64) -> &mut Self {
54 self.out.push(tag::INT);
55 varint(&mut self.out, zigzag(n));
56 self
57 }
58
59 pub fn float(&mut self, f: f64) -> &mut Self {
60 self.out.push(tag::FLOAT);
61 self.out.extend_from_slice(&f.to_le_bytes());
62 self
63 }
64
65 pub fn float32(&mut self, f: f32) -> &mut Self {
67 self.out.push(tag::FLOAT32);
68 self.out.extend_from_slice(&f.to_le_bytes());
69 self
70 }
71
72 pub fn floats(&mut self, items: &[f64]) -> &mut Self {
75 let narrow = crate::frame::floats::fits_f32(items);
76 self.out
77 .push(if narrow { tag::FLOATS32 } else { tag::FLOATS });
78 varint(&mut self.out, items.len() as u64);
79 if narrow {
80 crate::frame::floats::put_narrow(&mut self.out, items);
81 } else {
82 crate::frame::floats::put_wide(&mut self.out, items);
83 }
84 self
85 }
86
87 pub fn floats32(&mut self, items: &[f32]) -> &mut Self {
89 self.out.push(tag::FLOATS32);
90 varint(&mut self.out, items.len() as u64);
91 crate::frame::floats::put_f32s(&mut self.out, items);
92 self
93 }
94
95 pub fn str(&mut self, s: &str) -> &mut Self {
96 self.out.push(tag::STR);
97 self.string(s);
98 self
99 }
100
101 pub fn bytes(&mut self, b: &[u8]) -> &mut Self {
103 self.out.push(tag::BYTES);
104 varint(&mut self.out, b.len() as u64);
105 self.out.extend_from_slice(b);
106 self
107 }
108
109 pub fn list(&mut self, len: usize) -> &mut Self {
111 self.out.push(tag::LIST);
112 varint(&mut self.out, len as u64);
113 self
114 }
115
116 pub fn ints(&mut self, items: impl ExactSizeIterator<Item = i64>) -> &mut Self {
118 self.out.push(tag::INTS);
119 varint(&mut self.out, items.len() as u64);
120 for n in items {
121 varint(&mut self.out, zigzag(n));
122 }
123 self
124 }
125
126 pub(crate) fn stream_body(&mut self, len: usize, items: &[u8]) -> &mut Self {
128 let mut count = Vec::new();
129 varint(&mut count, len as u64);
130 self.out.push(tag::STREAM);
131 let body = u32::try_from(count.len() + items.len()).unwrap_or(u32::MAX);
132 self.out.extend_from_slice(&body.to_le_bytes());
133 self.out.extend_from_slice(&count);
134 self.out.extend_from_slice(items);
135 self
136 }
137
138 pub(crate) fn body() -> Self {
140 Writer {
141 out: Vec::with_capacity(START_BYTES),
142 strings: Interner::new(),
143 }
144 }
145
146 pub fn map(&mut self, len: usize) -> &mut Self {
148 self.out.push(tag::MAP);
149 varint(&mut self.out, len as u64);
150 self
151 }
152
153 pub fn key(&mut self, k: &str) -> &mut Self {
154 self.string(k);
155 self
156 }
157
158 pub fn value(&mut self, v: &Value) -> &mut Self {
159 match v {
160 Value::Null => self.null(),
161 Value::Bool(b) => self.bool(*b),
162 Value::Int(n) => self.int(*n),
163 Value::Float(f) => self.float(*f),
164 Value::Str(s) => self.str(s),
165 Value::List(items) => {
166 self.list(items.len());
167 for item in items {
168 self.value(item);
169 }
170 self
171 }
172 Value::Map(map) => {
173 self.map(map.len());
174 for (k, v) in map.iter() {
175 self.string(k);
176 self.value(v);
177 }
178 self
179 }
180 Value::Ref(r) | Value::Tag(r) => {
181 self.out.push(if matches!(v, Value::Ref(_)) {
182 tag::REF
183 } else {
184 tag::TAG
185 });
186 self.string(&r.kind);
187 self.string(&r.id);
188 self
189 }
190 Value::Res(r) => {
191 self.out.push(tag::RES);
192 self.string(&r.set);
193 self.string(&r.key);
194 self
195 }
196 Value::Text(s) => self.tagged(tag::TEXT, s),
197 Value::Image(s) => self.tagged(tag::IMAGE, s),
198 Value::Lang(s) => self.tagged(tag::LANG, s),
199 Value::Color(c) => {
200 self.out.push(tag::COLOR);
201 self.out.extend_from_slice(&c.to_le_bytes());
202 self
203 }
204 Value::Bytes(b) => self.bytes(b),
205 }
206 }
207
208 fn tagged(&mut self, t: u8, s: &str) -> &mut Self {
209 self.out.push(t);
210 self.string(s);
211 self
212 }
213
214 pub fn finish(self) -> Vec<u8> {
216 self.out
217 }
218
219 fn string(&mut self, s: &str) {
221 if let Some(i) = self.strings.find(&self.out, s) {
222 varint(&mut self.out, (i as u64) << 1);
223 return;
224 }
225 varint(&mut self.out, ((s.len() as u64) << 1) | NEW_STRING);
226 let at = self.out.len();
227 self.out.extend_from_slice(s.as_bytes());
228 self.strings.add(&self.out, s, at);
229 }
230}