tesseract_one/
serialize.rs

1//===------------ serialize.rs --------------------------------------------===//
2//  Copyright 2021, Tesseract Systems, Inc.
3//
4//  Licensed under the Apache License, Version 2.0 (the "License");
5//  you may not use this file except in compliance with the License.
6//  You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10//  Unless required by applicable law or agreed to in writing, software
11//  distributed under the License is distributed on an "AS IS" BASIS,
12//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13//  See the License for the specific language governing permissions and
14//  limitations under the License.
15//===----------------------------------------------------------------------===//
16
17use serde::{Deserialize, Serialize};
18
19use super::error::{Error, ErrorKind, Result};
20
21#[derive(Debug, Copy, Clone)]
22pub enum Serializer {
23    Json,
24    Cbor,
25}
26
27impl Default for Serializer {
28    #[cfg(debug_assertions)]
29    fn default() -> Self {
30        Self::Json
31    }
32
33    #[cfg(not(debug_assertions))]
34    fn default() -> Self {
35        Self::Cbor
36    }
37}
38
39impl Serializer {
40    pub fn from_marker(marker: &[u8]) -> Result<Self> {
41        if marker.len() != Self::marker_len() {
42            Err(Error::described(
43                ErrorKind::Serialization,
44                &format!("invalid marker length: {}", marker.len()),
45            ))
46        } else {
47            let marker = std::str::from_utf8(marker)
48                .map_err(|e| Error::new(ErrorKind::Serialization, "can't read marker", e))?;
49
50            if marker.eq(Self::Json.marker()) {
51                Ok(Self::Json)
52            } else if marker.eq(Self::Cbor.marker()) {
53                Ok(Self::Cbor)
54            } else {
55                Err(Error::described(
56                    ErrorKind::Serialization,
57                    &format!("unrecognized marker: {}", marker),
58                ))
59            }
60        }
61    }
62
63    #[inline]
64    pub fn marker(&self) -> &'static str {
65        match self {
66            Self::Json => "json",
67            Self::Cbor => "cbor",
68        }
69    }
70
71    #[inline]
72    pub fn marker_len() -> usize {
73        4
74    }
75
76    pub fn read_marker<'a>(from: &'a [u8]) -> Result<(Self, &'a [u8])> {
77        let marker = &from[0..Self::marker_len()];
78
79        Self::from_marker(marker).map(|s| (s, &from[Self::marker_len()..]))
80    }
81
82    //could be optimized (probably) with Write, though good enough for now
83    pub fn serialize<T: Serialize>(&self, object: &T, mark: bool) -> Result<Vec<u8>> {
84        let mut serialized = match self {
85            Self::Json => serde_json::to_vec(object)
86                .map_err(|e| Error::new(ErrorKind::Serialization, "can't serialize to JSON", e)),
87            Self::Cbor => serde_cbor::to_vec(object)
88                .map_err(|e| Error::new(ErrorKind::Serialization, "can't serialize to CBOR", e)),
89        }?;
90
91        if mark {
92            let marker = self.marker().as_bytes();
93            let mut result = Vec::with_capacity(serialized.len() + Self::marker_len());
94            result.extend_from_slice(marker);
95            result.append(&mut serialized);
96            Ok(result)
97        } else {
98            Ok(serialized)
99        }
100    }
101
102    pub fn deserialize<'de, T: Deserialize<'de>>(&self, from: &'de [u8]) -> Result<T> {
103        match self {
104            Self::Json => serde_json::from_slice(from).map_err(|e| {
105                Error::new(ErrorKind::Serialization, "can't deserialize from JSON", e)
106            }),
107            Self::Cbor => serde_cbor::from_slice(from).map_err(|e| {
108                Error::new(ErrorKind::Serialization, "can't deserialize from CBOR", e)
109            }),
110        }
111    }
112
113    pub fn deserialize_marked<'de, T: Deserialize<'de>>(from: &'de [u8]) -> Result<(T, Self)> {
114        let (serializer, data) = Self::read_marker(from)?;
115
116        serializer.deserialize(data).map(|t| (t, serializer))
117    }
118}