Skip to main content

rustapi_core/
path_params.rs

1//! Path parameter types.
2
3use std::collections::HashMap;
4
5/// Path parameters collection.
6#[derive(Debug, Clone, Default)]
7pub struct PathParams {
8    inner: Vec<(String, String)>,
9}
10
11impl PathParams {
12    /// Create a new empty path params collection.
13    #[inline]
14    pub fn new() -> Self {
15        Self { inner: Vec::new() }
16    }
17
18    /// Create path params with pre-allocated capacity.
19    #[inline]
20    pub fn with_capacity(capacity: usize) -> Self {
21        Self {
22            inner: Vec::with_capacity(capacity),
23        }
24    }
25
26    /// Insert a key-value pair.
27    #[inline]
28    pub fn insert(&mut self, key: String, value: String) {
29        self.inner.push((key, value));
30    }
31
32    /// Get a value by key.
33    #[inline]
34    pub fn get(&self, key: &str) -> Option<&String> {
35        self.inner.iter().find(|(k, _)| k == key).map(|(_, v)| v)
36    }
37
38    /// Check if a key exists.
39    #[inline]
40    pub fn contains_key(&self, key: &str) -> bool {
41        self.inner.iter().any(|(k, _)| k == key)
42    }
43
44    /// Check if the collection is empty.
45    #[inline]
46    pub fn is_empty(&self) -> bool {
47        self.inner.is_empty()
48    }
49
50    /// Get the number of parameters.
51    #[inline]
52    pub fn len(&self) -> usize {
53        self.inner.len()
54    }
55
56    /// Iterate over key-value pairs.
57    #[inline]
58    pub fn iter(&self) -> impl Iterator<Item = (&String, &String)> {
59        self.inner.iter().map(|(k, v)| (k, v))
60    }
61
62    /// Convert to a HashMap (for backwards compatibility).
63    pub fn to_hashmap(&self) -> HashMap<String, String> {
64        self.inner.iter().cloned().collect()
65    }
66}
67
68impl FromIterator<(String, String)> for PathParams {
69    fn from_iter<I: IntoIterator<Item = (String, String)>>(iter: I) -> Self {
70        Self {
71            inner: iter.into_iter().collect(),
72        }
73    }
74}
75
76impl<'a> FromIterator<(&'a str, &'a str)> for PathParams {
77    fn from_iter<I: IntoIterator<Item = (&'a str, &'a str)>>(iter: I) -> Self {
78        Self {
79            inner: iter
80                .into_iter()
81                .map(|(k, v)| (k.to_string(), v.to_string()))
82                .collect(),
83        }
84    }
85}
86
87impl From<HashMap<String, String>> for PathParams {
88    fn from(map: HashMap<String, String>) -> Self {
89        Self {
90            inner: map.into_iter().collect(),
91        }
92    }
93}
94
95impl From<PathParams> for HashMap<String, String> {
96    fn from(params: PathParams) -> Self {
97        params.inner.into_iter().collect()
98    }
99}
100
101impl<'a> IntoIterator for &'a PathParams {
102    type Item = &'a (String, String);
103    type IntoIter = std::slice::Iter<'a, (String, String)>;
104
105    fn into_iter(self) -> Self::IntoIter {
106        self.inner.iter()
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn test_small_params() {
116        let mut params = PathParams::new();
117        params.insert("id".to_string(), "123".to_string());
118        params.insert("name".to_string(), "test".to_string());
119
120        assert_eq!(params.get("id"), Some(&"123".to_string()));
121        assert_eq!(params.get("name"), Some(&"test".to_string()));
122        assert_eq!(params.len(), 2);
123    }
124
125    #[test]
126    fn test_many_params() {
127        let mut params = PathParams::new();
128        for i in 0..10 {
129            params.insert(format!("key{}", i), format!("value{}", i));
130        }
131
132        assert_eq!(params.len(), 10);
133    }
134
135    #[test]
136    fn test_from_iterator() {
137        let params: PathParams = [("a", "1"), ("b", "2"), ("c", "3")].into_iter().collect();
138
139        assert_eq!(params.get("a"), Some(&"1".to_string()));
140        assert_eq!(params.get("b"), Some(&"2".to_string()));
141        assert_eq!(params.get("c"), Some(&"3".to_string()));
142    }
143
144    #[test]
145    fn test_to_hashmap_conversion() {
146        let mut params = PathParams::new();
147        params.insert("id".to_string(), "42".to_string());
148
149        let map = params.to_hashmap();
150        assert_eq!(map.get("id"), Some(&"42".to_string()));
151    }
152}