automerge/columnar/encoding/
encodable_impls.rs

1use super::{Encodable, Sink};
2
3use std::borrow::Cow;
4
5use smol_str::SmolStr;
6
7/// Encodes bytes without a length prefix
8pub(crate) struct RawBytes<'a>(Cow<'a, [u8]>);
9
10impl<'a> From<&'a [u8]> for RawBytes<'a> {
11    fn from(r: &'a [u8]) -> Self {
12        RawBytes(r.into())
13    }
14}
15
16impl<'a> From<Cow<'a, [u8]>> for RawBytes<'a> {
17    fn from(c: Cow<'a, [u8]>) -> Self {
18        RawBytes(c)
19    }
20}
21
22impl Encodable for RawBytes<'_> {
23    fn encode<S: Sink>(&self, out: &mut S) -> usize {
24        out.append(&self.0);
25        self.0.len()
26    }
27}
28
29impl Encodable for SmolStr {
30    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
31        let bytes = self.as_bytes();
32        let len_encoded = bytes.len().encode(buf);
33        let data_len = bytes.encode(buf);
34        len_encoded + data_len
35    }
36}
37
38impl Encodable for Cow<'_, SmolStr> {
39    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
40        self.as_ref().encode(buf)
41    }
42}
43
44impl Encodable for String {
45    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
46        let bytes = self.as_bytes();
47        let len_encoded = bytes.len().encode(buf);
48        let data_len = bytes.encode(buf);
49        len_encoded + data_len
50    }
51}
52
53impl Encodable for Option<String> {
54    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
55        if let Some(s) = self {
56            s.encode(buf)
57        } else {
58            0.encode(buf)
59        }
60    }
61}
62
63impl Encodable for Option<Cow<'_, SmolStr>> {
64    fn encode<S: Sink>(&self, out: &mut S) -> usize {
65        if let Some(s) = self {
66            SmolStr::encode(s, out)
67        } else {
68            0.encode(out)
69        }
70    }
71}
72
73impl Encodable for f64 {
74    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
75        let bytes = self.to_le_bytes();
76        buf.append(&bytes);
77        bytes.len()
78    }
79}
80
81impl Encodable for f32 {
82    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
83        let bytes = self.to_le_bytes();
84        buf.append(&bytes);
85        bytes.len()
86    }
87}
88
89impl Encodable for usize {
90    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
91        (*self as u64).encode(buf)
92    }
93}
94
95impl Encodable for u32 {
96    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
97        u64::from(*self).encode(buf)
98    }
99}
100
101impl Encodable for i32 {
102    fn encode<S: Sink>(&self, buf: &mut S) -> usize {
103        i64::from(*self).encode(buf)
104    }
105}
106
107impl Encodable for [u8] {
108    fn encode<S: Sink>(&self, out: &mut S) -> usize {
109        out.append(self);
110        self.len()
111    }
112}
113
114impl Encodable for &[u8] {
115    fn encode<S: Sink>(&self, out: &mut S) -> usize {
116        out.append(self);
117        self.len()
118    }
119}
120
121impl Encodable for Cow<'_, [u8]> {
122    fn encode<S: Sink>(&self, out: &mut S) -> usize {
123        out.append(self);
124        self.len()
125    }
126}
127
128impl Encodable for Vec<u8> {
129    fn encode<S: Sink>(&self, out: &mut S) -> usize {
130        Encodable::encode(&self[..], out)
131    }
132}
133
134mod leb128_things {
135    use super::{Encodable, Sink};
136
137    impl Encodable for u64 {
138        fn encode<S: Sink>(&self, buf: &mut S) -> usize {
139            let mut val = *self;
140            let mut bytes_written = 0;
141            loop {
142                let mut byte = low_bits_of_u64(val);
143                val >>= 7;
144                if val != 0 {
145                    // More bytes to come, so set the continuation bit.
146                    byte |= CONTINUATION_BIT;
147                }
148
149                buf.append(&[byte]);
150                bytes_written += 1;
151
152                if val == 0 {
153                    return bytes_written;
154                }
155            }
156        }
157    }
158
159    impl Encodable for i64 {
160        fn encode<S: Sink>(&self, buf: &mut S) -> usize {
161            let mut val = *self;
162            let mut bytes_written = 0;
163            loop {
164                let mut byte = val as u8;
165                // Keep the sign bit for testing
166                val >>= 6;
167                let done = val == 0 || val == -1;
168                if done {
169                    byte &= !CONTINUATION_BIT;
170                } else {
171                    // Remove the sign bit
172                    val >>= 1;
173                    // More bytes to come, so set the continuation bit.
174                    byte |= CONTINUATION_BIT;
175                }
176
177                buf.append(&[byte]);
178                bytes_written += 1;
179
180                if done {
181                    return bytes_written;
182                }
183            }
184        }
185    }
186
187    #[doc(hidden)]
188    const CONTINUATION_BIT: u8 = 1 << 7;
189
190    #[inline]
191    fn low_bits_of_byte(byte: u8) -> u8 {
192        byte & !CONTINUATION_BIT
193    }
194
195    #[inline]
196    fn low_bits_of_u64(val: u64) -> u8 {
197        let byte = val & (u8::MAX as u64);
198        low_bits_of_byte(byte as u8)
199    }
200}