code0_definition_reader/
reader.rs

1use serde::Serialize;
2use std::{
3    fs::{self, DirEntry},
4    io::Error,
5    path::Path,
6};
7
8#[derive(Serialize, Debug, Clone, Copy)]
9pub enum MetaType {
10    FlowType,
11    DataType,
12    RuntimeFunction,
13}
14
15impl std::fmt::Display for MetaType {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        match self {
18            MetaType::FlowType => write!(f, "FlowType"),
19            MetaType::DataType => write!(f, "DataType"),
20            MetaType::RuntimeFunction => write!(f, "RuntimeFunction"),
21        }
22    }
23}
24
25#[derive(Debug)]
26pub struct Reader {
27    pub meta: Vec<Meta>,
28}
29
30#[derive(Debug)]
31pub struct Meta {
32    pub name: String,
33    pub r#type: MetaType,
34    pub data: Vec<String>,
35}
36
37impl Meta {
38    pub fn read_from_file<P>(name: String, r#type: MetaType, file_path: P) -> Result<Meta, Error>
39    where
40        P: AsRef<Path>,
41    {
42        let mut inside_code = false;
43        let mut current_block = vec![];
44        let mut code_snippets = vec![];
45
46        let content = match fs::read_to_string(file_path) {
47            Ok(content) => content,
48            Err(err) => {
49                println!("Error reading file: {err}");
50                return Err(err);
51            }
52        };
53
54        for line in content.lines() {
55            if line.contains("```") {
56                inside_code = !inside_code;
57
58                if !inside_code {
59                    let code_snippet = current_block.join(" ");
60                    code_snippets.push(code_snippet);
61                    current_block.clear();
62                }
63            }
64
65            if inside_code {
66                if line.starts_with("```") {
67                    continue;
68                }
69
70                current_block.push(line.to_string());
71            }
72        }
73
74        Ok(Meta {
75            name,
76            r#type,
77            data: code_snippets,
78        })
79    }
80}
81
82/// Reader
83///
84/// Expecting the file system too look like:
85/// - <path>
86///   - <feature>
87///     - <flow_types>
88///     - <data_types>
89///     - <runtime_functions>
90///    - <feature>
91///     - <flow_types>
92///     - <data_types>
93///     - <runtime_functions>
94impl Reader {
95    pub fn from_path(path: &str) -> Option<Reader> {
96        let mut result: Vec<Meta> = vec![];
97
98        // Reading the path folder
99        for feature_path in fs::read_dir(path).unwrap() {
100            let feature_path_result = match feature_path {
101                Ok(path) => path,
102                Err(_) => continue,
103            };
104
105            let feature_name = match get_file_name(&feature_path_result) {
106                Some(file_name) => file_name,
107                None => continue,
108            };
109
110            // Reading the feature folder
111            for type_path in fs::read_dir(feature_path_result.path()).unwrap() {
112                let type_path_result = match type_path {
113                    Ok(path) => path,
114                    Err(_) => continue,
115                };
116
117                let meta_type = match get_file_name(&type_path_result) {
118                    Some(name) => match name.as_str() {
119                        "flow_type" => MetaType::FlowType,
120                        "data_type" => MetaType::DataType,
121                        "runtime_definition" => MetaType::RuntimeFunction,
122                        _ => continue,
123                    },
124                    None => continue,
125                };
126
127                // Reading the type folder
128                for definition_path in fs::read_dir(type_path_result.path()).unwrap() {
129                    let definition_path_result = match definition_path {
130                        Ok(path) => path,
131                        Err(_) => continue,
132                    };
133
134                    if definition_path_result.file_type().unwrap().is_file() {
135                        let meta = Meta::read_from_file(
136                            feature_name.clone(),
137                            meta_type,
138                            definition_path_result.path(),
139                        );
140
141                        match meta {
142                            Ok(meta_result) => {
143                                result.push(meta_result);
144                            }
145                            Err(err) => {
146                                println!("Error reading meta: {err:?}");
147                            }
148                        }
149                    } else {
150                        for sub_definition_path in
151                            fs::read_dir(definition_path_result.path()).unwrap()
152                        {
153                            let sub_definition_path_result = match sub_definition_path {
154                                Ok(path) => path,
155                                Err(_) => continue,
156                            };
157
158                            let meta = Meta::read_from_file(
159                                feature_name.clone(),
160                                meta_type,
161                                sub_definition_path_result.path(),
162                            );
163
164                            match meta {
165                                Ok(meta_result) => {
166                                    result.push(meta_result);
167                                }
168                                Err(err) => {
169                                    println!("Error reading meta: {err:?}");
170                                }
171                            }
172                        }
173                    }
174                }
175            }
176        }
177
178        Some(Reader { meta: result })
179    }
180}
181
182fn get_file_name(entry: &DirEntry) -> Option<String> {
183    entry
184        .file_name()
185        .to_str()
186        .map(|file_name| file_name.to_string())
187}