binserde/
ser.rs

1use std::io;
2use std::io::Write;
3
4use crate::dedup::DedupContext;
5use crate::serde::Mode;
6use crate::Result;
7
8pub trait BinSerialize {
9    fn serialize<S: BinSerializer>(&self, serializer: S) -> Result<()>;
10}
11
12pub trait BinSerializer: Sized {
13    type Pipe: Write;
14
15    fn pipe(&mut self) -> &mut Self::Pipe;
16
17    fn dedup(&mut self) -> &mut DedupContext;
18
19    fn mode(&self) -> Mode;
20
21    fn with_mode(self, mode: Mode) -> WithMode<Self> {
22        WithMode {
23            serializer: self,
24            mode,
25        }
26    }
27
28    fn change_mode<F>(self, op: F) -> WithMode<Self>
29    where
30        F: FnOnce(&mut Mode),
31    {
32        let mut new_mode = self.mode();
33        op(&mut new_mode);
34        self.with_mode(new_mode)
35    }
36
37    fn disable_dedup(self) -> WithMode<Self> {
38        self.change_mode(|mode| mode.use_dedup = false)
39    }
40}
41
42impl<T> BinSerializer for &mut T
43where
44    T: BinSerializer,
45{
46    type Pipe = T::Pipe;
47
48    fn pipe(&mut self) -> &mut Self::Pipe {
49        (**self).pipe()
50    }
51
52    fn dedup(&mut self) -> &mut DedupContext {
53        (**self).dedup()
54    }
55
56    fn mode(&self) -> Mode {
57        (**self).mode()
58    }
59}
60
61pub struct BinSerializerBase<W> {
62    pipe: W,
63    dedup: DedupContext,
64}
65
66impl<W> BinSerializerBase<W> {
67    pub fn new(pipe: W) -> Self {
68        BinSerializerBase {
69            pipe,
70            dedup: DedupContext::new(),
71        }
72    }
73
74    pub fn into_pipe(self) -> W {
75        self.pipe
76    }
77}
78
79impl<W> BinSerializer for BinSerializerBase<W>
80where
81    W: Write,
82{
83    type Pipe = W;
84    fn pipe(&mut self) -> &mut Self::Pipe {
85        &mut self.pipe
86    }
87
88    fn dedup(&mut self) -> &mut DedupContext {
89        &mut self.dedup
90    }
91
92    fn mode(&self) -> Mode {
93        Mode::default()
94    }
95}
96
97pub struct WithMode<S> {
98    serializer: S,
99    mode: Mode,
100}
101
102impl<S> BinSerializer for WithMode<S>
103where
104    S: BinSerializer,
105{
106    type Pipe = S::Pipe;
107
108    fn pipe(&mut self) -> &mut Self::Pipe {
109        self.serializer.pipe()
110    }
111
112    fn dedup(&mut self) -> &mut DedupContext {
113        self.serializer.dedup()
114    }
115
116    fn mode(&self) -> Mode {
117        self.mode
118    }
119}
120
121pub struct PrescanSerializer {
122    pipe: NullWrite,
123    dedup: DedupContext,
124}
125
126impl PrescanSerializer {
127    pub fn new() -> Self {
128        PrescanSerializer {
129            pipe: NullWrite,
130            dedup: DedupContext::new(),
131        }
132    }
133}
134
135impl BinSerializer for PrescanSerializer {
136    type Pipe = NullWrite;
137
138    fn pipe(&mut self) -> &mut Self::Pipe {
139        &mut self.pipe
140    }
141
142    fn dedup(&mut self) -> &mut DedupContext {
143        &mut self.dedup
144    }
145
146    fn mode(&self) -> Mode {
147        Mode::default()
148    }
149}
150
151pub struct NullWrite;
152
153impl Write for NullWrite {
154    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
155        Ok(buf.len())
156    }
157
158    fn flush(&mut self) -> io::Result<()> {
159        Ok(())
160    }
161}