maybe_multiple/
multiple.rs1#[cfg(feature = "serde")]
4use serde::ser::SerializeSeq;
5
6use thiserror::Error;
7
8#[derive(Debug)]
9#[cfg_attr(
10 feature = "serde",
11 derive(serde::Deserialize),
12 serde(try_from = "Vec<T>")
13)]
14pub struct Multiple<T> {
15 head: [T; 2],
16 tail: Vec<T>,
17}
18
19impl<T> Multiple<T> {
24 #[allow(clippy::len_without_is_empty)] pub fn len(&self) -> usize {
26 self.tail.len() + 2
27 }
28}
29
30#[derive(Debug, PartialEq, Eq, Error)]
35#[error("could not convert from Vec: Vec contains fewer than 2 elements")]
36pub struct VecSizeError;
37
38impl<T> TryFrom<Vec<T>> for Multiple<T> {
39 type Error = VecSizeError;
40
41 fn try_from(v: Vec<T>) -> Result<Self, Self::Error> {
42 let mut iter = v.into_iter();
43
44 let (Some(a), Some(b)) = (iter.next(), iter.next()) else {
45 return Err(VecSizeError);
46 };
47
48 Ok(Self {
49 head: [a, b],
50 tail: iter.collect(),
51 })
52 }
53}
54
55impl<T> From<Multiple<T>> for Vec<T> {
56 fn from(m: Multiple<T>) -> Self {
57 let mut v = Vec::from(m.head);
58 v.extend(m.tail);
59 v
60 }
61}
62
63impl<T> PartialEq for Multiple<T>
64where
65 T: PartialEq,
66{
67 fn eq(&self, other: &Self) -> bool {
68 self.head == other.head && self.tail == other.tail
69 }
70}
71
72impl<T> Eq for Multiple<T> where T: Eq {}
73
74#[cfg(feature = "serde")]
75impl<T> serde::Serialize for Multiple<T>
76where
77 T: serde::Serialize,
78{
79 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
80 where
81 S: serde::Serializer,
82 {
83 let mut seq = serializer.serialize_seq(Some(self.len()))?;
84 seq.serialize_element(&self.head[0])?;
85 seq.serialize_element(&self.head[1])?;
86 for t in &self.tail {
87 seq.serialize_element(t)?;
88 }
89 seq.end()
90 }
91}
92
93#[cfg(test)]
98mod tests {
99 use super::{Multiple, VecSizeError};
100 use pretty_assertions::assert_eq;
101 use proptest::collection::size_range;
102 use test_strategy::proptest;
103
104 #[test]
105 fn manual_conversions() {
106 let vec: Vec<u8> = vec![];
107 assert_eq!(Multiple::try_from(vec).unwrap_err(), VecSizeError);
108
109 let vec: Vec<u8> = vec![42];
110 assert_eq!(Multiple::try_from(vec).unwrap_err(), VecSizeError);
111
112 let vec: Vec<u8> = vec![42, 43];
113 assert_eq!(Vec::from(Multiple::try_from(vec.clone()).unwrap()), vec);
114
115 let vec: Vec<u8> = vec![42, 43, 44];
116 assert_eq!(Vec::from(Multiple::try_from(vec.clone()).unwrap()), vec);
117 }
118
119 #[proptest]
120 fn proptest_conversions(vec: Vec<u8>) {
121 if vec.len() < 2 {
122 assert_eq!(Multiple::try_from(vec).unwrap_err(), VecSizeError);
123 } else {
124 assert_eq!(Vec::from(Multiple::try_from(vec.clone()).unwrap()), vec);
125 }
126 }
127
128 #[proptest]
129 fn serialize_deserialize(#[any(size_range(2..128).lift())] vec: Vec<u8>) {
130 let multiple = Multiple::try_from(vec.clone()).unwrap();
131 assert_eq!(
132 serde_json::to_string(&multiple).unwrap(),
133 serde_json::to_string(&vec).unwrap()
134 );
135
136 let vec_str = serde_json::to_string(&vec).unwrap();
137 assert_eq!(
138 serde_json::from_str::<Multiple<_>>(&vec_str).unwrap(),
139 multiple
140 );
141 }
142}