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    int::{IntRepr, LeU32, LeU64},
20    RawConst, RawInt,
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<'a, T: Clone, U> Seq<'a, T, U> {
37    pub fn new(s: impl Into<Cow<'a, [T]>>) -> Self {
38        Self(s.into(), PhantomData)
39    }
40
41    /// Returns true if this sequence is empty.
42    pub fn is_empty(&self) -> bool {
43        self.0.is_empty()
44    }
45
46    /// Returns a length of this sequence.
47    pub fn len(&self) -> usize {
48        self.0.len()
49    }
50
51    /// Appends an element to this sequence.
52    pub fn push(&mut self, element: T) {
53        match self.0 {
54            Cow::Borrowed(seq) => {
55                let mut seq = seq.to_vec();
56                seq.push(element);
57                self.0 = Cow::Owned(seq);
58            }
59            Cow::Owned(ref mut seq) => {
60                seq.push(element);
61            }
62        };
63    }
64
65    /// Returns a `'static` version of `self`.
66    pub fn into_owned(self) -> Seq<'static, T, U> {
67        Seq(Cow::Owned(self.0.into_owned()), self.1)
68    }
69}
70
71impl<T: Clone, U> Default for Seq<'_, T, U> {
72    fn default() -> Self {
73        Seq::new(Vec::new())
74    }
75}
76
77impl<T, U> MySerialize for Seq<'_, T, U>
78where
79    T: Clone + MySerialize,
80    U: SeqRepr,
81{
82    fn serialize(&self, buf: &mut Vec<u8>) {
83        U::serialize(&self.0, buf);
84    }
85}
86
87impl<'de, T, U> MyDeserialize<'de> for Seq<'de, T, U>
88where
89    T: Clone + MyDeserialize<'de, Ctx = ()>,
90    U: SeqRepr,
91{
92    const SIZE: Option<usize> = None;
93    type Ctx = U::Ctx;
94
95    fn deserialize(ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
96        U::deserialize(ctx, &mut *buf).map(Self::new)
97    }
98}
99
100/// Representation of a serialized bytes.
101pub trait SeqRepr {
102    /// Maximum number of items in a sequence (depends on how lenght is stored).
103    const MAX_LEN: usize;
104    const SIZE: Option<usize>;
105    type Ctx;
106
107    fn serialize<T: MySerialize>(seq: &[T], buf: &mut Vec<u8>);
108    fn deserialize<'de, T>(ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [T]>>
109    where
110        T: Clone,
111        T: MyDeserialize<'de, Ctx = ()>;
112}
113
114macro_rules! impl_seq_repr {
115    ($t:ty, $name:ident) => {
116        impl SeqRepr for $name {
117            const MAX_LEN: usize = <$t>::MAX as usize;
118            const SIZE: Option<usize> = None;
119            type Ctx = ();
120
121            fn serialize<T: MySerialize>(seq: &[T], buf: &mut Vec<u8>) {
122                let len = std::cmp::min(Self::MAX_LEN, seq.len());
123                <$name as IntRepr>::serialize(len as $t, &mut *buf);
124                for x in seq.iter().take(len) {
125                    x.serialize(&mut *buf);
126                }
127            }
128
129            fn deserialize<'de, T>(
130                (): Self::Ctx,
131                buf: &mut ParseBuf<'de>,
132            ) -> io::Result<Cow<'de, [T]>>
133            where
134                T: Clone,
135                T: MyDeserialize<'de, Ctx = ()>,
136            {
137                let len = *buf.parse::<RawInt<$name>>(())? as usize;
138                let mut seq = Vec::with_capacity(len);
139                match T::SIZE {
140                    Some(count) => {
141                        let mut buf: ParseBuf = buf.parse(count * len)?;
142                        for _ in 0..len {
143                            seq.push(buf.parse(())?);
144                        }
145                    }
146                    None => {
147                        for _ in 0..len {
148                            seq.push(buf.parse(())?);
149                        }
150                    }
151                }
152                Ok(Cow::Owned(seq))
153            }
154        }
155    };
156}
157
158impl_seq_repr!(u64, LeU64);
159impl_seq_repr!(u32, LeU32);
160
161/// Same as `RawCons` but for a sequence of values.
162#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
163#[repr(transparent)]
164pub struct RawSeq<'a, T: IntRepr, U>(pub Cow<'a, [T::Primitive]>, PhantomData<U>);
165
166impl<'a, T: IntRepr, U> RawSeq<'a, T, U> {
167    /// Creates a new wrapper.
168    pub fn new(t: impl Into<Cow<'a, [T::Primitive]>>) -> Self {
169        Self(t.into(), PhantomData)
170    }
171
172    /// Returns a length of this sequence.
173    pub fn len(&self) -> usize {
174        self.0.len()
175    }
176
177    /// Returns `true` if the sequence has a length of 0.
178    pub fn is_empty(&self) -> bool {
179        self.0.is_empty()
180    }
181
182    /// Returns a `'static` version of `self`.
183    pub fn into_owned(self) -> RawSeq<'static, T, U> {
184        RawSeq(Cow::Owned(self.0.into_owned()), self.1)
185    }
186}
187
188impl<T: IntRepr, U> RawSeq<'_, T, U>
189where
190    T: Copy,
191    U: TryFrom<T::Primitive>,
192{
193    /// Returns raw value at the given position.
194    pub fn get(&self, index: usize) -> Option<RawConst<T, U>> {
195        self.0.get(index).copied().map(RawConst::new)
196    }
197}
198
199impl<'de, T: IntRepr<Primitive = u8>, U> MyDeserialize<'de> for RawSeq<'de, T, U> {
200    const SIZE: Option<usize> = None;
201    type Ctx = usize;
202
203    fn deserialize(length: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
204        let bytes: &[u8] = buf.parse(length)?;
205        Ok(Self::new(bytes))
206    }
207}
208
209impl<T: IntRepr<Primitive = u8>, U> MySerialize for RawSeq<'_, T, U> {
210    fn serialize(&self, buf: &mut Vec<u8>) {
211        buf.put_slice(self.0.as_ref());
212    }
213}
214
215impl<T: IntRepr, U: fmt::Debug> fmt::Debug for RawSeq<'_, T, U>
216where
217    T: fmt::Debug,
218    U: TryFrom<T::Primitive>,
219    U::Error: fmt::Debug,
220{
221    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222        self.0
223            .iter()
224            .copied()
225            .map(RawConst::<T, U>::new)
226            .collect::<Vec<_>>()
227            .fmt(f)
228    }
229}