1mod impl_from_seq_marked;
2mod impl_seq_value;
3
4use std::fmt;
5use std::ops::Deref;
6use std::ops::DerefMut;
7
8#[derive(Default, Clone, Eq, PartialEq)]
20#[cfg_attr(feature = "seqv-serde", derive(serde::Serialize, serde::Deserialize))]
21pub struct SeqV<M, T = Vec<u8>> {
22 pub seq: u64,
23 pub meta: Option<M>,
24 pub data: T,
25}
26
27impl<M, T> Deref for SeqV<M, T> {
28 type Target = T;
29
30 fn deref(&self) -> &Self::Target {
31 &self.data
32 }
33}
34
35impl<M, T> DerefMut for SeqV<M, T> {
36 fn deref_mut(&mut self) -> &mut Self::Target {
37 &mut self.data
38 }
39}
40
41impl<M, T> fmt::Debug for SeqV<M, T>
42where
43 M: fmt::Debug,
44 T: fmt::Debug,
45{
46 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47 let mut de = f.debug_struct("SeqV");
48 de.field("seq", &self.seq);
49 de.field("meta", &self.meta);
50 de.field("data", &"[binary]");
51
52 de.finish()
53 }
54}
55
56impl<M, T> SeqV<M, T> {
57 pub fn new(seq: u64, data: T) -> Self {
58 Self {
59 seq,
60 meta: None,
61 data,
62 }
63 }
64
65 pub fn new_with_meta(seq: u64, meta: Option<M>, data: T) -> Self {
66 Self { seq, meta, data }
67 }
68
69 #[must_use]
70 pub fn with_seq(mut self, seq: u64) -> Self {
71 self.seq = seq;
72 self
73 }
74
75 #[must_use]
76 pub fn with_meta(mut self, m: Option<M>) -> Self {
77 self.meta = m;
78 self
79 }
80
81 #[must_use]
82 pub fn with_value(mut self, v: T) -> Self {
83 self.data = v;
84 self
85 }
86
87 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> SeqV<M, U> {
89 SeqV {
90 seq: self.seq,
91 meta: self.meta,
92 data: f(self.data),
93 }
94 }
95
96 pub fn try_map<U, E>(self, f: impl FnOnce(T) -> Result<U, E>) -> Result<SeqV<M, U>, E> {
99 Ok(SeqV {
100 seq: self.seq,
101 meta: self.meta,
102 data: f(self.data)?,
103 })
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_new() {
113 let sv = SeqV::<(), _>::new(42, 100u64);
114 assert_eq!(sv.seq, 42);
115 assert_eq!(sv.meta, None);
116 assert_eq!(sv.data, 100);
117 }
118
119 #[test]
120 fn test_new_with_meta() {
121 let sv = SeqV::new_with_meta(10, Some("metadata"), 200u64);
122 assert_eq!(sv.seq, 10);
123 assert_eq!(sv.meta, Some("metadata"));
124 assert_eq!(sv.data, 200);
125
126 let sv_none = SeqV::new_with_meta(5, None::<String>, 300u64);
127 assert_eq!(sv_none.meta, None);
128 }
129
130 #[test]
131 fn test_builder_methods() {
132 let sv = SeqV::new(1, 100u64).with_seq(42).with_meta(Some("test")).with_value(200u64);
133
134 assert_eq!(sv.seq, 42);
135 assert_eq!(sv.meta, Some("test"));
136 assert_eq!(sv.data, 200);
137 }
138
139 #[test]
140 fn test_map() {
141 let sv = SeqV::new_with_meta(10, Some("meta"), 5u64);
142 let mapped = sv.map(|x| x * 2);
143
144 assert_eq!(mapped.seq, 10);
145 assert_eq!(mapped.meta, Some("meta"));
146 assert_eq!(mapped.data, 10u64);
147 }
148
149 #[test]
150 fn test_try_map_success() {
151 let sv = SeqV::new_with_meta(20, Some("meta"), "123");
152 let result = sv.try_map(|s| s.parse::<u64>());
153
154 assert!(result.is_ok());
155 let mapped = result.unwrap();
156 assert_eq!(mapped.seq, 20);
157 assert_eq!(mapped.meta, Some("meta"));
158 assert_eq!(mapped.data, 123u64);
159 }
160
161 #[test]
162 fn test_try_map_error() {
163 let sv = SeqV::<(), _>::new(30, "invalid");
164 let result = sv.try_map(|s| s.parse::<u64>());
165
166 assert!(result.is_err());
167 }
168
169 #[test]
170 fn test_deref() {
171 let sv = SeqV::<(), _>::new(1, vec![1, 2, 3]);
172 assert_eq!(sv.len(), 3);
173 assert_eq!(sv[0], 1);
174 }
175
176 #[test]
177 fn test_deref_mut() {
178 let mut sv = SeqV::<(), _>::new(1, vec![1, 2, 3]);
179 sv[0] = 10;
180 assert_eq!(sv.data[0], 10);
181 }
182
183 #[test]
184 fn test_default() {
185 let sv = SeqV::<String, u64>::default();
186 assert_eq!(sv.seq, 0);
187 assert_eq!(sv.meta, None);
188 assert_eq!(sv.data, 0);
189 }
190
191 #[test]
192 fn test_debug() {
193 let sv = SeqV::new_with_meta(42, Some("test"), vec![1, 2, 3]);
194 assert_eq!(
195 "SeqV { seq: 42, meta: Some(\"test\"), data: \"[binary]\" }",
196 format!("{:?}", sv)
197 );
198 }
199
200 #[test]
201 fn test_clone_eq() {
202 let sv1 = SeqV::new_with_meta(10, Some("meta"), 100u64);
203 let sv2 = sv1.clone();
204 assert_eq!(sv1, sv2);
205 }
206}
207
208#[cfg(test)]
209#[cfg(feature = "seqv-serde")]
210mod tests_serde {
211 use serde_json;
212
213 use super::*;
214
215 #[test]
216 fn test_serde() {
217 let sv = SeqV::new_with_meta(42, Some("metadata".to_string()), vec![1, 2, 3]);
218 let json = serde_json::to_string(&sv).unwrap();
219 let deserialized: SeqV<String, Vec<u8>> = serde_json::from_str(&json).unwrap();
220 assert_eq!(sv, deserialized);
221
222 let sv_none = SeqV::new_with_meta(10, None::<String>, vec![4, 5, 6]);
224 let json_none = serde_json::to_string(&sv_none).unwrap();
225 let deserialized_none: SeqV<String, Vec<u8>> = serde_json::from_str(&json_none).unwrap();
226 assert_eq!(sv_none, deserialized_none);
227 }
228}