-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathserde.rs
More file actions
146 lines (123 loc) · 5.34 KB
/
serde.rs
File metadata and controls
146 lines (123 loc) · 5.34 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use std::fmt;
use std::fmt::Formatter;
use std::io::Cursor;
use std::marker::PhantomData;
use serde::{Deserialize, Serialize};
use crate::{BitBlock, BitSet};
use crate::bitset::level::IBlock;
use crate::config::Config;
impl<Conf: Config> Serialize for BitSet<Conf>{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer
{
use arrayvec::ArrayVec;
// SBO
const STACK_BUFFER_LEN: usize = 4096;
let mut on_stack: ArrayVec<u8, STACK_BUFFER_LEN>;
let mut on_heap : Vec<u8>;
// real_len <= approx_len
let approx_len =
Conf::DataBitBlock::size() // root block
+ (1 + self.level0.mask().count_ones()) * Conf::Level1BitBlock::size() // lvl1 blocks
+ (1 + self.data.blocks().len()) * Conf::DataBitBlock::size(); // approx data blocks
// There should be no errors at all.
let array = if approx_len <= STACK_BUFFER_LEN {
on_stack = ArrayVec::new();
unsafe{ self.serialize(&mut on_stack).unwrap_unchecked(); }
on_stack.as_slice()
} else {
on_heap = Vec::with_capacity(approx_len);
unsafe{ self.serialize(&mut on_heap).unwrap_unchecked(); }
on_heap.as_slice()
};
if serializer.is_human_readable() {
// collect_str instead of serialize_str allow to omit constructing
// intermediate base64 encoded String.
use base64::{display::Base64Display, engine::general_purpose::STANDARD};
serializer.collect_str(&Base64Display::new(array, &STANDARD))
} else {
// we assume there is an efficient byte encoder in serializer.
serializer.serialize_bytes(array)
}
}
}
impl<'de, Conf: Config> Deserialize<'de> for BitSet<Conf>{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>
{
use serde::de::Error;
if deserializer.is_human_readable() {
struct Visitor<Conf>(PhantomData<Conf>);
impl<'de, Conf: Config> serde::de::Visitor<'de> for Visitor<Conf> {
type Value = BitSet<Conf>;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("a string")
}
fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
use base64::{read::DecoderReader, engine::general_purpose::STANDARD};
let mut decoder = DecoderReader::new(Cursor::new(v), &STANDARD);
BitSet::deserialize(&mut decoder).map_err(Error::custom)
}
}
deserializer.deserialize_str(Visitor(PhantomData))
} else {
struct Visitor<Conf>(PhantomData<Conf>);
impl<'de, Conf: Config> serde::de::Visitor<'de> for Visitor<Conf> {
type Value = BitSet<Conf>;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("a byte slice")
}
fn visit_bytes<E: Error>(self, v: &[u8]) -> Result<Self::Value, E> {
BitSet::deserialize(&mut Cursor::new(v)).map_err(Error::custom)
}
}
deserializer.deserialize_bytes(Visitor(PhantomData))
}
}
}
#[cfg(test)]
mod tests {
use std::io::Seek;
use itertools::assert_equal;
use crate::config;
use super::*;
#[test]
fn simple_serde_json_test(){
let mut bitset: BitSet<config::_64bit> = Default::default();
bitset.insert(100);
bitset.insert(5720);
bitset.insert(219347);
let serialized = serde_json::to_string(&bitset).unwrap();
println!("Serialized {:?}", serialized);
let deserialized_bitset: BitSet<config::_64bit> = serde_json::from_str(&serialized).unwrap();
println!("Deserialized {:?}", deserialized_bitset);
assert_eq!(bitset, deserialized_bitset);
assert_equal(bitset.iter(), deserialized_bitset.iter()); // check by iter too.
}
#[test]
fn simple_serde_bincode_test(){
let mut bitset: BitSet<config::_64bit> = Default::default();
bitset.insert(100);
bitset.insert(5720);
bitset.insert(219347);
let config = bincode::config::standard();
let serialized = bincode::serde::encode_to_vec(&bitset, config).unwrap();
println!("Serialized {:?}", serialized);
let deserialized_bitset: BitSet<config::_64bit> = bincode::serde::decode_from_slice(&serialized, config).unwrap().0;
println!("Deserialized {:?}", deserialized_bitset);
assert_eq!(bitset, deserialized_bitset);
assert_equal(bitset.iter(), deserialized_bitset.iter()); // check by iter too.
}
#[test]
fn serde_json_w_file() -> anyhow::Result<()> {
type BitSet = crate::BitSet<config::_64bit>;
let set = BitSet::from_iter(0..260_000usize);
let mut file = tempfile::tempfile()?;
serde_json::to_writer(&mut file, &set)?;
file.rewind()?;
let _s: BitSet = serde_json::from_reader(file)?;
Ok(())
}
}