-
Notifications
You must be signed in to change notification settings - Fork 16
/
codec.rs
103 lines (83 loc) · 2.46 KB
/
codec.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use serde::{de::DeserializeOwned, Serialize};
use std::marker::PhantomData;
/// A trait that defines how types are decoded/encoded.
pub trait Codec {
type Value;
type Encoded: AsRef<[u8]>;
fn encode(d: &Self::Value) -> Option<Self::Encoded>;
fn decode(bytes: &[u8]) -> Option<Self::Value>;
}
/// A JSON codec that uses `serde_json` to encode/decode as a JSON string
#[derive(Clone, Debug)]
pub struct JsonCodec<T>(PhantomData<T>);
impl<T> Codec for JsonCodec<T>
where
T: Serialize + DeserializeOwned,
{
type Value = T;
type Encoded = String;
fn encode(d: &Self::Value) -> Option<Self::Encoded> {
serde_json::to_string(d).ok()
}
fn decode(bytes: &[u8]) -> Option<Self::Value> {
let json_string = String::from_utf8(bytes.to_vec()).ok()?;
serde_json::from_str(&json_string).ok()
}
}
/// A Null codec that can be used for paths that are only meant to be set/reset and do not hold any
/// typed value.
#[derive(Clone, Debug)]
pub struct NullCodec;
impl Codec for NullCodec {
type Value = ();
type Encoded = Vec<u8>;
fn encode(_d: &Self::Value) -> Option<Self::Encoded> {
// using [0x00] to represent null
Some(vec![0x00])
}
fn decode(bytes: &[u8]) -> Option<Self::Value> {
match bytes {
// the encoded bytes must be [0x00]
[0x00] => Some(()),
_ => None,
}
}
}
/// A Protobuf codec that uses `prost` to encode/decode
#[derive(Clone, Debug)]
pub struct ProtobufCodec<T, R> {
domain_type: PhantomData<T>,
raw_type: PhantomData<R>,
}
impl<T, R> Codec for ProtobufCodec<T, R>
where
T: Into<R> + Clone,
R: TryInto<T> + Default + prost::Message,
{
type Value = T;
type Encoded = Vec<u8>;
fn encode(d: &Self::Value) -> Option<Self::Encoded> {
let r = d.clone().into();
Some(r.encode_to_vec())
}
fn decode(bytes: &[u8]) -> Option<Self::Value> {
let r = R::decode(bytes).ok()?;
r.try_into().ok()
}
}
/// A binary codec that uses `AsRef<[u8]>` and `From<Vec<u8>>` to encode and decode respectively.
#[derive(Clone, Debug)]
pub struct BinCodec<T>(PhantomData<T>);
impl<T> Codec for BinCodec<T>
where
T: AsRef<[u8]> + From<Vec<u8>>,
{
type Value = T;
type Encoded = Vec<u8>;
fn encode(d: &Self::Value) -> Option<Self::Encoded> {
Some(d.as_ref().to_vec())
}
fn decode(bytes: &[u8]) -> Option<Self::Value> {
Some(bytes.to_vec().into())
}
}