Skip to main content

autoagents_core/
one_or_many.rs

1use serde::{Deserialize, Serialize};
2
3/// Stores either a single item or multiple items without forcing a Vec allocation.
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub enum OneOrMany<T> {
6    One(T),
7    Many(Vec<T>),
8}
9
10impl<T> OneOrMany<T> {
11    pub fn len(&self) -> usize {
12        match self {
13            OneOrMany::One(_) => 1,
14            OneOrMany::Many(items) => items.len(),
15        }
16    }
17
18    pub fn is_empty(&self) -> bool {
19        self.len() == 0
20    }
21
22    pub fn iter(&self) -> Box<dyn Iterator<Item = &T> + '_> {
23        match self {
24            OneOrMany::One(item) => Box::new(std::iter::once(item)),
25            OneOrMany::Many(items) => Box::new(items.iter()),
26        }
27    }
28
29    pub fn into_vec(self) -> Vec<T> {
30        match self {
31            OneOrMany::One(item) => vec![item],
32            OneOrMany::Many(items) => items,
33        }
34    }
35
36    pub fn map<U, F>(self, mut f: F) -> OneOrMany<U>
37    where
38        F: FnMut(T) -> U,
39    {
40        match self {
41            OneOrMany::One(item) => OneOrMany::One(f(item)),
42            OneOrMany::Many(items) => OneOrMany::Many(items.into_iter().map(f).collect()),
43        }
44    }
45}
46
47impl<T> From<Vec<T>> for OneOrMany<T> {
48    fn from(value: Vec<T>) -> Self {
49        if value.len() == 1 {
50            OneOrMany::One(value.into_iter().next().unwrap())
51        } else {
52            OneOrMany::Many(value)
53        }
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn test_one_len_and_is_empty() {
63        let one = OneOrMany::One(42);
64        assert_eq!(one.len(), 1);
65        assert!(!one.is_empty());
66    }
67
68    #[test]
69    fn test_many_len_and_is_empty() {
70        let many = OneOrMany::Many(vec![1, 2, 3]);
71        assert_eq!(many.len(), 3);
72        assert!(!many.is_empty());
73    }
74
75    #[test]
76    fn test_many_empty_is_empty() {
77        let many: OneOrMany<i32> = OneOrMany::Many(vec![]);
78        assert_eq!(many.len(), 0);
79        assert!(many.is_empty());
80    }
81
82    #[test]
83    fn test_one_iter() {
84        let one = OneOrMany::One(42);
85        let items: Vec<&i32> = one.iter().collect();
86        assert_eq!(items, vec![&42]);
87    }
88
89    #[test]
90    fn test_many_iter() {
91        let many = OneOrMany::Many(vec![1, 2, 3]);
92        let items: Vec<&i32> = many.iter().collect();
93        assert_eq!(items, vec![&1, &2, &3]);
94    }
95
96    #[test]
97    fn test_one_into_vec() {
98        let one = OneOrMany::One(42);
99        assert_eq!(one.into_vec(), vec![42]);
100    }
101
102    #[test]
103    fn test_many_into_vec() {
104        let many = OneOrMany::Many(vec![1, 2, 3]);
105        assert_eq!(many.into_vec(), vec![1, 2, 3]);
106    }
107
108    #[test]
109    fn test_one_map() {
110        let one = OneOrMany::One(2);
111        let mapped = one.map(|x| x * 10);
112        assert_eq!(mapped.into_vec(), vec![20]);
113    }
114
115    #[test]
116    fn test_many_map() {
117        let many = OneOrMany::Many(vec![1, 2, 3]);
118        let mapped = many.map(|x| x + 100);
119        assert_eq!(mapped.into_vec(), vec![101, 102, 103]);
120    }
121
122    #[test]
123    fn test_from_vec_single_becomes_one() {
124        let result: OneOrMany<i32> = vec![42].into();
125        assert!(matches!(result, OneOrMany::One(42)));
126    }
127
128    #[test]
129    fn test_from_vec_multi_becomes_many() {
130        let result: OneOrMany<i32> = vec![1, 2].into();
131        assert!(matches!(result, OneOrMany::Many(_)));
132        assert_eq!(result.len(), 2);
133    }
134
135    #[test]
136    fn test_from_vec_empty_becomes_many() {
137        let result: OneOrMany<i32> = vec![].into();
138        assert!(matches!(result, OneOrMany::Many(_)));
139        assert!(result.is_empty());
140    }
141
142    #[test]
143    fn test_serialize_deserialize_one() {
144        let one = OneOrMany::One("hello".to_string());
145        let json = serde_json::to_string(&one).unwrap();
146        let deserialized: OneOrMany<String> = serde_json::from_str(&json).unwrap();
147        assert_eq!(deserialized.into_vec(), vec!["hello"]);
148    }
149
150    #[test]
151    fn test_serialize_deserialize_many() {
152        let many = OneOrMany::Many(vec![1, 2, 3]);
153        let json = serde_json::to_string(&many).unwrap();
154        let deserialized: OneOrMany<i32> = serde_json::from_str(&json).unwrap();
155        assert_eq!(deserialized.into_vec(), vec![1, 2, 3]);
156    }
157}