Skip to main content

mysql_common/misc/raw/
seq.rs

1// Copyright (c) 2021 Anatoly Ikorsky
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9use std::{borrow::Cow, convert::TryFrom, fmt, io, marker::PhantomData, ops::Deref};
10
11use bytes::BufMut;
12
13use crate::{
14    io::ParseBuf,
15    proto::{MyDeserialize, MySerialize},
16};
17
18use super::{
19    RawConst, RawInt,
20    int::{IntRepr, LeU32, LeU64},
21};
22
23/// Sequence of serialized values (length serialized as `U`).
24#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
25#[repr(transparent)]
26pub struct Seq<'a, T: Clone, U>(pub Cow<'a, [T]>, PhantomData<U>);
27
28impl<T: Clone, U> Deref for Seq<'_, T, U> {
29    type Target = [T];
30
31    fn deref(&self) -> &Self::Target {
32        self.0.as_ref()
33    }
34}
35
36impl<T: Clone, U> Seq<'static, T, U> {
37    pub fn empty() -> Seq<'static, T, U> {
38        Self(Cow::Borrowed(&[]), PhantomData)
39    }
40}
41
42impl<'a, T: Clone, U> Seq<'a, T, U> {
43    pub fn new(s: impl Into<Cow<'a, [T]>>) -> Self {
44        Self(s.into(), PhantomData)
45    }
46
47    /// Returns true if this sequence is empty.
48    pub fn is_empty(&self) -> bool {
49        self.0.is_empty()
50    }
51
52    /// Returns a length of this sequence.
53    pub fn len(&self) -> usize {
54        self.0.len()
55    }
56
57    /// Appends an element to this sequence.
58    pub fn push(&mut self, element: T) {
59        match self.0 {
60            Cow::Borrowed(seq) => {
61                let mut seq = seq.to_vec();
62                seq.push(element);
63                self.0 = Cow::Owned(seq);
64            }
65            Cow::Owned(ref mut seq) => {
66                seq.push(element);
67            }
68        };
69    }
70
71    /// Returns a `'static` version of `self`.
72    pub fn into_owned(self) -> Seq<'static, T, U> {
73        Seq(Cow::Owned(self.0.into_owned()), self.1)
74    }
75}
76
77impl<T: Clone, U> Default for Seq<'_, T, U> {
78    fn default() -> Self {
79        Seq::new(Vec::new())
80    }
81}
82
83impl<T, U> MySerialize for Seq<'_, T, U>
84where
85    T: Clone + MySerialize,
86    U: SeqRepr,
87{
88    fn serialize(&self, buf: &mut Vec<u8>) {
89        U::serialize(&self.0, buf);
90    }
91}
92
93impl<'de, T, U> MyDeserialize<'de> for Seq<'de, T, U>
94where
95    T: Clone + MyDeserialize<'de, Ctx = ()>,
96    U: SeqRepr,
97{
98    const SIZE: Option<usize> = None;
99    type Ctx = U::Ctx;
100
101    fn deserialize(ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
102        U::deserialize(ctx, &mut *buf).map(Self::new)
103    }
104}
105
106/// Representation of a serialized bytes.
107pub trait SeqRepr {
108    /// Maximum number of items in a sequence (depends on how lenght is stored).
109    const MAX_LEN: usize;
110    const SIZE: Option<usize>;
111    type Ctx;
112
113    fn serialize<T: MySerialize>(seq: &[T], buf: &mut Vec<u8>);
114    fn deserialize<'de, T>(ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [T]>>
115    where
116        T: Clone,
117        T: MyDeserialize<'de, Ctx = ()>;
118}
119
120#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
121pub struct Unknown;
122
123/// Unknown number of elements.
124impl SeqRepr for Unknown {
125    const MAX_LEN: usize = usize::MAX;
126    const SIZE: Option<usize> = None;
127    type Ctx = usize;
128
129    fn serialize<T: MySerialize>(seq: &[T], buf: &mut Vec<u8>) {
130        for x in seq.iter() {
131            x.serialize(&mut *buf);
132        }
133    }
134
135    fn deserialize<'de, T>(len: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [T]>>
136    where
137        T: Clone,
138        T: MyDeserialize<'de, Ctx = ()>,
139    {
140        let mut seq = Vec::with_capacity(len);
141        match T::SIZE {
142            Some(count) => {
143                let mut buf: ParseBuf<'_> = buf.parse(count * len)?;
144                for _ in 0..len {
145                    seq.push(buf.parse(())?);
146                }
147            }
148            None => {
149                for _ in 0..len {
150                    seq.push(buf.parse(())?);
151                }
152            }
153        }
154        Ok(Cow::Owned(seq))
155    }
156}
157
158macro_rules! impl_seq_repr {
159    ($t:ty, $name:ident) => {
160        impl SeqRepr for $name {
161            const MAX_LEN: usize = <$t>::MAX as usize;
162            const SIZE: Option<usize> = None;
163            type Ctx = ();
164
165            fn serialize<T: MySerialize>(seq: &[T], buf: &mut Vec<u8>) {
166                let len = std::cmp::min(Self::MAX_LEN, seq.len());
167                <$name as IntRepr>::serialize(len as $t, &mut *buf);
168                for x in seq.iter().take(len) {
169                    x.serialize(&mut *buf);
170                }
171            }
172
173            fn deserialize<'de, T>(
174                (): Self::Ctx,
175                buf: &mut ParseBuf<'de>,
176            ) -> io::Result<Cow<'de, [T]>>
177            where
178                T: Clone,
179                T: MyDeserialize<'de, Ctx = ()>,
180            {
181                let len = *buf.parse::<RawInt<$name>>(())? as usize;
182                let mut seq = Vec::with_capacity(len);
183                match T::SIZE {
184                    Some(count) => {
185                        let mut buf: ParseBuf<'_> = buf.parse(count * len)?;
186                        for _ in 0..len {
187                            seq.push(buf.parse(())?);
188                        }
189                    }
190                    None => {
191                        for _ in 0..len {
192                            seq.push(buf.parse(())?);
193                        }
194                    }
195                }
196                Ok(Cow::Owned(seq))
197            }
198        }
199    };
200}
201
202impl_seq_repr!(u64, LeU64);
203impl_seq_repr!(u32, LeU32);
204
205/// Same as `RawCons` but for a sequence of values.
206#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
207#[repr(transparent)]
208pub struct RawSeq<'a, T: IntRepr, U>(pub Cow<'a, [T::Primitive]>, PhantomData<U>);
209
210impl<'a, T: IntRepr, U> RawSeq<'a, T, U> {
211    /// Creates a new wrapper.
212    pub fn new(t: impl Into<Cow<'a, [T::Primitive]>>) -> Self {
213        Self(t.into(), PhantomData)
214    }
215
216    /// Returns a length of this sequence.
217    pub fn len(&self) -> usize {
218        self.0.len()
219    }
220
221    /// Returns `true` if the sequence has a length of 0.
222    pub fn is_empty(&self) -> bool {
223        self.0.is_empty()
224    }
225
226    /// Returns a `'static` version of `self`.
227    pub fn into_owned(self) -> RawSeq<'static, T, U> {
228        RawSeq(Cow::Owned(self.0.into_owned()), self.1)
229    }
230}
231
232impl<T: IntRepr, U> RawSeq<'_, T, U>
233where
234    T: Copy,
235    U: TryFrom<T::Primitive>,
236{
237    /// Returns raw value at the given position.
238    pub fn get(&self, index: usize) -> Option<RawConst<T, U>> {
239        self.0.get(index).copied().map(RawConst::new)
240    }
241}
242
243impl<'de, T: IntRepr<Primitive = u8>, U> MyDeserialize<'de> for RawSeq<'de, T, U> {
244    const SIZE: Option<usize> = None;
245    type Ctx = usize;
246
247    fn deserialize(length: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
248        let bytes: &[u8] = buf.parse(length)?;
249        Ok(Self::new(bytes))
250    }
251}
252
253impl<T: IntRepr<Primitive = u8>, U> MySerialize for RawSeq<'_, T, U> {
254    fn serialize(&self, buf: &mut Vec<u8>) {
255        buf.put_slice(self.0.as_ref());
256    }
257}
258
259impl<T: IntRepr, U: fmt::Debug> fmt::Debug for RawSeq<'_, T, U>
260where
261    T: fmt::Debug,
262    U: TryFrom<T::Primitive>,
263    U::Error: fmt::Debug,
264{
265    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266        self.0
267            .iter()
268            .copied()
269            .map(RawConst::<T, U>::new)
270            .collect::<Vec<_>>()
271            .fmt(f)
272    }
273}