1use std::fmt;
2
3use crate::InternalSeq;
4use crate::SeqMarked;
5
6mod impl_from_seq_marked;
7mod impl_from_seqv;
8
9#[derive(Debug)]
19#[derive(Clone, Copy)]
20#[derive(PartialEq, Eq)]
21#[derive(PartialOrd, Ord)]
22#[cfg_attr(
23 feature = "seq-marked-serde",
24 derive(serde::Serialize, serde::Deserialize)
25)]
26#[cfg_attr(
27 feature = "seq-marked-bincode",
28 derive(bincode::Encode, bincode::Decode)
29)]
30pub struct SeqData<D = Vec<u8>> {
31 seq: u64,
33 data: D,
34}
35
36impl<D> SeqData<D> {
37 pub fn new(seq: u64, data: D) -> Self {
39 Self { seq, data }
40 }
41
42 pub fn map<U>(self, f: impl FnOnce(D) -> U) -> SeqData<U> {
54 SeqData {
55 seq: self.seq,
56 data: f(self.data),
57 }
58 }
59
60 pub fn try_map<U, E>(self, f: impl FnOnce(D) -> Result<U, E>) -> Result<SeqData<U>, E> {
61 Ok(SeqData {
62 seq: self.seq,
63 data: f(self.data)?,
64 })
65 }
66
67 pub fn as_ref(&self) -> SeqData<&D> {
69 SeqData {
70 seq: self.seq,
71 data: &self.data,
72 }
73 }
74
75 pub fn order_key(&self) -> SeqMarked<()> {
77 SeqMarked::new_normal(self.seq, ())
78 }
79
80 pub fn internal_seq(&self) -> InternalSeq {
82 InternalSeq::new(self.seq)
83 }
84
85 pub fn user_seq(&self) -> u64 {
87 self.seq
88 }
89
90 pub fn max(a: Self, b: Self) -> Self {
92 if a.order_key() > b.order_key() { a } else { b }
93 }
94
95 pub fn max_ref<'l>(a: &'l Self, b: &'l Self) -> &'l Self {
97 if a.order_key() > b.order_key() { a } else { b }
98 }
99
100 pub fn data(&self) -> &D {
102 &self.data
103 }
104
105 pub fn into_data(self) -> D {
107 self.data
108 }
109
110 pub fn into_parts(self) -> (u64, D) {
111 (self.seq, self.data)
112 }
113
114 pub fn display_with_debug(&self) -> impl fmt::Display + '_
116 where D: fmt::Debug {
117 struct DisplaySeqData<'a, D>(&'a SeqData<D>);
118
119 impl<D> fmt::Display for DisplaySeqData<'_, D>
120 where D: fmt::Debug
121 {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 write!(f, "{{seq: {}, ", self.0.seq)?;
124 write!(f, "({:?})", self.0.data)?;
125 write!(f, "}}")
126 }
127 }
128
129 DisplaySeqData(self)
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use std::cmp::Ordering;
136
137 use Ordering::Equal;
138 use Ordering::Greater;
139 use Ordering::Less;
140
141 use super::*;
142 use crate::testing::ts;
143
144 pub(crate) fn norm<D>(seq: u64, d: D) -> SeqData<D> {
146 SeqData::new(seq, d)
147 }
148
149 #[test]
150 fn test_seq_data_is_copy() {
151 let seq_marked = SeqData::new(5, "data");
152 let seq_marked_copy = seq_marked;
153 assert_eq!(seq_marked, seq_marked_copy);
154 }
155
156 #[test]
157 fn test_new() {
158 let seq_marked = SeqData::new(5, "data");
159 assert_eq!(seq_marked.seq, 5);
160 assert_eq!(seq_marked.data, "data");
161 }
162
163 #[test]
164 fn test_map() -> anyhow::Result<()> {
165 let a = norm(1, 1u64);
166 assert_eq!(norm(1, 2u32), a.map(|x| (x * 2) as u32));
167
168 let a = ts::<u64>(1);
169 assert_eq!(ts::<u32>(1), a.map(|x| (x * 2) as u32));
170
171 Ok(())
172 }
173
174 #[test]
175 fn test_as_ref() -> anyhow::Result<()> {
176 let a = norm(1, 1u64);
177 assert_eq!(norm(1, &1u64), a.as_ref());
178
179 let a = ts::<u64>(1);
180 assert_eq!(ts::<&u64>(1), a.as_ref());
181
182 Ok(())
183 }
184
185 #[test]
186 fn test_order_key() -> anyhow::Result<()> {
187 assert!(norm(1, 1u64).order_key() == norm(1, 1u64).order_key());
188 assert!(norm(1, 2u64).order_key() == norm(1, 1u64).order_key());
189 assert!(norm(2, 2u64).order_key() > norm(1, 1u64).order_key());
190
191 assert!(ts::<u64>(1).order_key() > norm(1, 1u64).order_key());
192 assert!(ts::<u64>(2).order_key() > norm(1, 1u64).order_key());
193
194 assert!(ts::<u64>(2).order_key() > ts::<u64>(1).order_key());
195 assert!(ts::<u64>(1).order_key() == ts::<u64>(1).order_key());
196
197 Ok(())
198 }
199
200 #[test]
201 fn test_partial_ord() -> anyhow::Result<()> {
202 fn pcmp<D: PartialOrd>(a: &SeqData<D>, b: &SeqData<D>) -> Option<Ordering> {
203 PartialOrd::partial_cmp(a, b)
204 }
205
206 assert_eq!(Some(Greater), pcmp(&norm(2, 2u64), &norm(1, 2u64)));
209 assert_eq!(Some(Equal), pcmp(&norm(2, 2u64), &norm(2, 2u64)));
210 assert_eq!(Some(Less), pcmp(&norm(2, 2u64), &norm(3, 2u64)));
211
212 assert_eq!(Some(Greater), pcmp(&norm(2, 2u64), &norm(2, 1u64)));
215 assert_eq!(Some(Equal), pcmp(&norm(2, 2u64), &norm(2, 2u64)));
216 assert_eq!(Some(Less), pcmp(&norm(2, 2u64), &norm(2, 3u64)));
217
218 Ok(())
219 }
220
221 #[test]
222 fn test_seq_data_order_key() {
223 let a = SeqData::new(1, "data1");
224
225 assert_eq!(a.order_key(), SeqMarked::new_normal(1, ()));
226 }
227
228 #[test]
229 fn test_max() {
230 assert_eq!(
231 SeqData::<u64>::new(2, 1),
232 SeqData::<u64>::max(SeqData::<u64>::new(1, 1), SeqData::<u64>::new(2, 1))
233 );
234 assert_eq!(
235 SeqData::<u64>::new(2, 1),
236 SeqData::<u64>::max(SeqData::<u64>::new(1, 2), SeqData::<u64>::new(2, 1))
237 );
238 }
239
240 #[test]
241 fn test_max_ref() {
242 let m1 = SeqData::new(1, 2);
243 let m2 = SeqData::new(3, 2);
244
245 assert_eq!(SeqData::max_ref(&m1, &m2), &m2);
246
247 assert_eq!(SeqData::max_ref(&m1, &m1), &m1);
248 assert_eq!(SeqData::max_ref(&m2, &m2), &m2);
249 }
250
251 #[test]
252 fn test_into_parts() {
253 let seq_marked = SeqData::new(5, "data");
254 let (seq, marked) = seq_marked.into_parts();
255 assert_eq!(seq, 5);
256 assert_eq!(marked, "data");
257 }
258
259 #[test]
260 fn test_internal_seq() {
261 let seq_marked = SeqData::new(5, "data");
262 assert_eq!(*seq_marked.internal_seq(), 5);
263 }
264
265 #[test]
266 fn test_user_seq() {
267 let seq_marked = SeqData::new(5, "data");
268 assert_eq!(seq_marked.user_seq(), 5);
269 }
270
271 #[test]
272 fn test_display_with_debug() {
273 let seq_marked = SeqData::new(5, "data");
274 assert_eq!(
275 format!("{}", seq_marked.display_with_debug()),
276 "{seq: 5, (\"data\")}"
277 );
278 }
279}
280
281#[cfg(test)]
282#[cfg(feature = "seq-marked-bincode")]
283mod tests_bincode {
284
285 use super::*;
286 use crate::testing::bincode_config;
287 use crate::testing::test_bincode_decode;
288
289 #[test]
290 fn test_marked_bincode() {
291 let a = SeqData::new(5, 1u64);
292 let encoded = bincode::encode_to_vec(&a, bincode_config()).unwrap();
293 let (decoded, n): (SeqData<u64>, usize) =
294 bincode::decode_from_slice(&encoded, bincode_config()).unwrap();
295 assert_eq!(n, 2);
296 assert_eq!(a, decoded);
297 }
298
299 #[test]
300 fn test_marked_bincode_decode_v010() -> anyhow::Result<()> {
301 let value = SeqData::new(5, 1u64);
302 let encoded = vec![5, 1];
303
304 test_bincode_decode(&encoded, &value)?;
305
306 Ok(())
307 }
308}
309
310#[cfg(test)]
311#[cfg(feature = "seq-marked-serde")]
312mod tests_serde {
313 use super::*;
314 use crate::testing::test_serde_decode;
315
316 #[test]
317 fn test_marked_serde() {
318 let a = SeqData::new(5, 1u64);
319 let encoded = serde_json::to_string(&a).unwrap();
320 let decoded: SeqData<u64> = serde_json::from_str(&encoded).unwrap();
321 assert_eq!(a, decoded);
322 }
323
324 #[test]
325 fn test_marked_serde_decode_v010() -> anyhow::Result<()> {
326 let value = SeqData::new(5, 1u64);
327 let encoded = r#"{"seq":5,"data":1}"#;
328
329 test_serde_decode(encoded, &value)?;
330
331 Ok(())
332 }
333}