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}