mysql_common/misc/raw/
mod.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
9//! Various parsing/serialization primitives.
10
11use std::io;
12
13use ::bytes::BufMut;
14
15use crate::{
16    io::ParseBuf,
17    proto::{MyDeserialize, MySerialize},
18};
19
20pub use self::{
21    _const::{Const, RawConst},
22    bytes::RawBytes,
23    flags::RawFlags,
24    int::RawInt,
25    seq::RawSeq,
26};
27
28use super::unexpected_buf_eof;
29
30pub mod _const;
31pub mod bytes;
32pub mod flags;
33pub mod int;
34pub mod seq;
35
36impl<'de> MyDeserialize<'de> for &'de [u8] {
37    const SIZE: Option<usize> = None;
38    type Ctx = usize;
39
40    fn deserialize(len: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
41        buf.checked_eat(len).ok_or_else(unexpected_buf_eof)
42    }
43}
44
45impl MySerialize for [u8] {
46    fn serialize(&self, buf: &mut Vec<u8>) {
47        buf.put_slice(self);
48    }
49}
50
51impl<'de, const LEN: usize> MyDeserialize<'de> for [u8; LEN] {
52    const SIZE: Option<usize> = Some(LEN);
53    type Ctx = ();
54
55    fn deserialize((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
56        let value = buf.eat(LEN);
57        let mut this = [0_u8; LEN];
58        this.copy_from_slice(value);
59        Ok(this)
60    }
61}
62
63impl<const LEN: usize> MySerialize for [u8; LEN] {
64    fn serialize(&self, buf: &mut Vec<u8>) {
65        buf.put_slice(&self[..]);
66    }
67}
68
69#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
70pub struct Skip<const LEN: usize>;
71
72impl<'de, const LEN: usize> MyDeserialize<'de> for Skip<LEN> {
73    const SIZE: Option<usize> = Some(LEN);
74    type Ctx = ();
75
76    fn deserialize((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
77        buf.skip(LEN);
78        Ok(Self)
79    }
80}
81
82impl<const LEN: usize> MySerialize for Skip<LEN> {
83    fn serialize(&self, buf: &mut Vec<u8>) {
84        buf.put_slice(&[0_u8; LEN]);
85    }
86}
87
88impl<'de> MyDeserialize<'de> for ParseBuf<'de> {
89    const SIZE: Option<usize> = None;
90    type Ctx = usize;
91
92    fn deserialize(len: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
93        buf.checked_eat_buf(len).ok_or_else(unexpected_buf_eof)
94    }
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
98pub enum Either<T, U> {
99    Left(T),
100    Right(U),
101}
102
103impl<T, U> Either<T, U> {
104    pub fn unwrap_left(self) -> T {
105        match self {
106            Either::Left(x) => x,
107            Either::Right(_) => panic!("called unwrap_left on Either::Right value"),
108        }
109    }
110
111    pub fn unwrap_right(self) -> U {
112        match self {
113            Either::Right(x) => x,
114            Either::Left(_) => panic!("called unwrap_right on Either::Left value"),
115        }
116    }
117}
118
119impl<'de, T, U> MyDeserialize<'de> for Either<T, U>
120where
121    T: MyDeserialize<'de>,
122    U: MyDeserialize<'de>,
123{
124    const SIZE: Option<usize> = None; // TODO: maybe later
125    /// Which one to deserialize.
126    type Ctx = Either<T::Ctx, U::Ctx>;
127
128    fn deserialize(ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
129        match ctx {
130            Either::Left(ctx) => T::deserialize(ctx, buf).map(Either::Left),
131            Either::Right(ctx) => U::deserialize(ctx, buf).map(Either::Right),
132        }
133    }
134}
135
136impl<T, U> MySerialize for Either<T, U>
137where
138    T: MySerialize,
139    U: MySerialize,
140{
141    fn serialize(&self, buf: &mut Vec<u8>) {
142        match self {
143            Either::Left(x) => x.serialize(buf),
144            Either::Right(x) => x.serialize(buf),
145        }
146    }
147}
148
149impl<'de> MyDeserialize<'de> for f64 {
150    const SIZE: Option<usize> = Some(8);
151    type Ctx = ();
152
153    fn deserialize((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
154        Ok(buf.eat_f64_le())
155    }
156}
157
158impl MySerialize for f64 {
159    fn serialize(&self, buf: &mut Vec<u8>) {
160        buf.put_f64_le(*self);
161    }
162}