utoipauto_core/
string_utils.rs

1use crate::{discover::discover_from_file, token_utils::Parameters};
2
3pub fn rem_first_and_last(value: &str) -> &str {
4    let mut chars = value.chars();
5    chars.next();
6    chars.next_back();
7    chars.as_str()
8}
9
10pub fn trim_whites(str: &str) -> String {
11    let s = str.trim();
12
13    let s: String = s.replace('\n', "");
14
15    s
16}
17
18pub fn trim_parentheses(str: &str) -> String {
19    let s = str.trim();
20
21    let s: String = s.replace(['(', ')'], "");
22
23    s
24}
25
26/// Extract the file paths from the attributes
27/// Support the old syntax (MODULE_TREE_PATH => MODULE_SRC_PATH) ; (MODULE_TREE_PATH => MODULE_SRC_PATH) ;
28/// and the new syntax MODULE_SRC_PATH, MODULE_SRC_PATH
29///
30/// # Example
31/// ```
32/// use utoipauto_core::string_utils::extract_paths;
33/// let paths = extract_paths(
34///    "(utoipa_auto_macro::tests::controllers::controller1 => ./utoipa-auto-macro/tests/controllers/controller1.rs) ; (utoipa_auto_macro::tests::controllers::controller2 => ./utoipa-auto-macro/tests/controllers/controller2.rs)"
35/// );
36/// assert_eq!(
37///   paths,
38///  vec![
39///    "./utoipa-auto-macro/tests/controllers/controller1.rs".to_string(),
40///   "./utoipa-auto-macro/tests/controllers/controller2.rs".to_string(),
41/// ]   
42/// );
43/// ```
44pub fn extract_paths(attributes: &str) -> Vec<String> {
45    let attributes = trim_parentheses(attributes);
46
47    if attributes.contains('|') {
48        panic!("Please use the new syntax ! paths=\"(MODULE_TREE_PATH => MODULE_SRC_PATH) ;\"")
49    }
50    let paths = if attributes.contains("=>") {
51        extract_paths_arrow(attributes)
52    } else {
53        extract_paths_coma(attributes)
54    };
55    if paths.is_empty() {
56        panic!("utoipauto: No paths specified !")
57    }
58    paths
59}
60
61// (MODULE_TREE_PATH => MODULE_SRC_PATH) ; (MODULE_TREE_PATH => MODULE_SRC_PATH) ;
62// extract the paths from the string
63// Here for legacy support
64fn extract_paths_arrow(attributes: String) -> Vec<String> {
65    let mut paths: Vec<String> = vec![];
66    let attributes = attributes.split(';');
67
68    for p in attributes {
69        let pair = p.split_once("=>");
70
71        if let Some(pair) = pair {
72            paths.push(trim_whites(pair.1));
73        }
74    }
75    paths
76}
77
78// MODULE_SRC_PATH, MODULE_SRC_PATH
79fn extract_paths_coma(attributes: String) -> Vec<String> {
80    let mut paths: Vec<String> = vec![];
81    let attributes = attributes.split(',');
82
83    for p in attributes {
84        paths.push(trim_whites(p));
85    }
86    paths
87}
88
89/// Return the list of all the functions with the #[utoipa] attribute
90/// and the list of all the structs with the #[derive(ToSchema)] attribute
91/// and the list of all the structs with the #[derive(ToResponse)] attribute
92pub fn discover(paths: Vec<String>, params: &Parameters) -> (String, String, String) {
93    let mut uto_paths: String = String::new();
94    let mut uto_models: String = String::new();
95    let mut uto_responses: String = String::new();
96    for p in paths {
97        let path = extract_crate_name(p);
98        let (list_fn, list_model, list_reponse) = discover_from_file(path.paths, path.crate_name, params);
99        // We need to add a coma after each path
100        for i in list_fn {
101            uto_paths.push_str(format!("{},", i).as_str());
102        }
103        for i in list_model {
104            uto_models.push_str(format!("{},", i).as_str());
105        }
106        for i in list_reponse {
107            uto_responses.push_str(format!("{},", i).as_str());
108        }
109    }
110    (uto_paths, uto_models, uto_responses)
111}
112
113#[derive(Debug, PartialEq)]
114struct Path {
115    paths: String,
116    crate_name: String,
117}
118
119fn extract_crate_name(path: String) -> Path {
120    let mut path = path.split(" from ");
121    let paths = path.next().unwrap();
122    let crate_name = path.next().unwrap_or("crate").to_string();
123    Path {
124        paths: paths.to_string(),
125        crate_name,
126    }
127}
128
129#[cfg(test)]
130mod test {
131    use crate::string_utils::extract_paths;
132
133    #[test]
134    fn test_extract_path() {
135        let paths = "./src";
136        let extracted = extract_paths(paths);
137        assert_eq!(extracted, vec!["./src".to_string()]);
138    }
139
140    #[test]
141    fn test_extract_crate_name() {
142        assert_eq!(
143            super::extract_crate_name(
144                "utoipa_auto_macro::from::controllers::controller1 from utoipa_auto_macro".to_string(),
145            ),
146            super::Path {
147                paths: "utoipa_auto_macro::from::controllers::controller1".to_string(),
148                crate_name: "utoipa_auto_macro".to_string()
149            }
150        );
151    }
152
153    #[test]
154    fn test_extract_crate_name_default() {
155        assert_eq!(
156            super::extract_crate_name("utoipa_auto_macro::from::controllers::controller1".to_string()),
157            super::Path {
158                paths: "utoipa_auto_macro::from::controllers::controller1".to_string(),
159                crate_name: "crate".to_string()
160            }
161        );
162    }
163
164    #[test]
165    fn test_extract_paths_arrow() {
166        assert_eq!(
167            super::extract_paths(
168                "(utoipa_auto_macro::tests::controllers::controller1 => ./utoipa-auto-macro/tests/controllers/controller1.rs) ; (utoipa_auto_macro::tests::controllers::controller2 => ./utoipa-auto-macro/tests/controllers/controller2.rs)"
169            ),
170            vec![
171                "./utoipa-auto-macro/tests/controllers/controller1.rs".to_string(),
172                "./utoipa-auto-macro/tests/controllers/controller2.rs".to_string()
173            ]
174        );
175    }
176
177    #[test]
178    fn test_extract_paths_coma() {
179        assert_eq!(
180            super::extract_paths(
181                "./utoipa-auto-macro/tests/controllers/controller1.rs, ./utoipa-auto-macro/tests/controllers/controller2.rs"
182            ),
183            vec![
184                "./utoipa-auto-macro/tests/controllers/controller1.rs".to_string(),
185                "./utoipa-auto-macro/tests/controllers/controller2.rs".to_string()
186            ]
187        );
188    }
189}