toolcraft_utils/utils/
string_util.rs

1/// A trait for extracting values from a query string.
2pub trait QueryExtractor {
3    /// Extracts the value associated with the specified key from the query string.
4    ///
5    /// # Arguments
6    ///
7    /// * `key` - The key whose associated value is to be returned.
8    ///
9    /// # Returns
10    ///
11    /// * `Option<&str>` - Some(&str) if the key exists, otherwise None.
12    fn extract_value(&self, key: &str) -> Option<&str>;
13}
14
15impl<T: AsRef<str>> QueryExtractor for T {
16    /// Implementation of the `extract_value` method for any type that implements `AsRef<str>`.
17    ///
18    /// This method splits the query string by '&' to get key-value pairs,
19    /// then splits each pair by '=' to separate the key and value. It returns
20    /// the value associated with the specified key if found.
21    fn extract_value(&self, key: &str) -> Option<&str> {
22        self.as_ref().split('&').find_map(|pair| {
23            let mut parts = pair.split('=');
24            let k = parts.next()?;
25            let v = parts.next()?;
26            if k == key { Some(v) } else { None }
27        })
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::QueryExtractor;
34
35    /// Tests the `extract_value` method with a standard query string.
36    #[test]
37    fn test_extract_value() {
38        let query = "key1=val1&key2=val2&key3=val3";
39        let query_string = String::from(query);
40
41        assert_eq!(query.extract_value("key1"), Some("val1"));
42        assert_eq!(query.extract_value("key2"), Some("val2"));
43        assert_eq!(query.extract_value("key3"), Some("val3"));
44        assert_eq!(query.extract_value("key4"), None);
45
46        assert_eq!(query_string.extract_value("key1"), Some("val1"));
47        assert_eq!(query_string.extract_value("key2"), Some("val2"));
48        assert_eq!(query_string.extract_value("key3"), Some("val3"));
49        assert_eq!(query_string.extract_value("key4"), None);
50    }
51
52    /// Tests the `extract_value` method with an empty query string.
53    #[test]
54    fn test_extract_value_empty() {
55        let query = "";
56        let query_string = String::from(query);
57
58        assert_eq!(query.extract_value("key1"), None);
59        assert_eq!(query_string.extract_value("key1"), None);
60    }
61
62    /// Tests the `extract_value` method with a query string where a key has no value.
63    #[test]
64    fn test_extract_value_no_value() {
65        let query = "key1=&key2=val2";
66        let query_string = String::from(query);
67
68        assert_eq!(query.extract_value("key1"), Some(""));
69        assert_eq!(query.extract_value("key2"), Some("val2"));
70
71        assert_eq!(query_string.extract_value("key1"), Some(""));
72        assert_eq!(query_string.extract_value("key2"), Some("val2"));
73    }
74
75    /// Tests the `extract_value` method with a query string containing multiple keys with the same
76    /// name.
77    #[test]
78    fn test_extract_value_multiple_keys() {
79        let query = "key1=val1&key1=val2&key3=val3";
80        let query_string = String::from(query);
81
82        assert_eq!(query.extract_value("key1"), Some("val1")); // Only the first occurrence
83        assert_eq!(query.extract_value("key3"), Some("val3"));
84
85        assert_eq!(query_string.extract_value("key1"), Some("val1")); // Only the first occurrence
86        assert_eq!(query_string.extract_value("key3"), Some("val3"));
87    }
88
89    /// Tests the `extract_value` method with a malformed query string.
90    #[test]
91    fn test_extract_value_malformed_query() {
92        let query = "key1=val1&key2&key3=val3";
93        let query_string = String::from(query);
94
95        assert_eq!(query.extract_value("key1"), Some("val1"));
96        assert_eq!(query.extract_value("key2"), None);
97        assert_eq!(query.extract_value("key3"), Some("val3"));
98
99        assert_eq!(query_string.extract_value("key1"), Some("val1"));
100        assert_eq!(query_string.extract_value("key2"), None);
101        assert_eq!(query_string.extract_value("key3"), Some("val3"));
102    }
103}