code0_definition_reader/
reader.rs1use serde::Serialize;
2use std::io::ErrorKind;
3use std::{
4 fs::{self, DirEntry},
5 io::Error,
6 path::Path,
7};
8
9#[derive(Serialize, Debug, Clone, Copy)]
10pub enum MetaType {
11 FlowType,
12 DataType,
13 RuntimeFunction,
14}
15
16impl std::fmt::Display for MetaType {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match self {
19 MetaType::FlowType => write!(f, "FlowType"),
20 MetaType::DataType => write!(f, "DataType"),
21 MetaType::RuntimeFunction => write!(f, "RuntimeFunction"),
22 }
23 }
24}
25
26pub struct Reader {
27 pub meta: Vec<Meta>,
28}
29
30#[derive(Clone)]
31pub struct Meta {
32 pub name: String,
33 pub r#type: MetaType,
34 pub definition_string: String,
35 pub path: String,
36}
37
38impl Meta {
39 pub fn read_from_file<P>(name: String, r#type: MetaType, file_path: P) -> Result<Meta, Error>
40 where
41 P: AsRef<Path>,
42 {
43 let path = match file_path.as_ref().to_str() {
44 Some(path) => path,
45 None => return Err(Error::new(ErrorKind::InvalidInput, "Invalid path")),
46 };
47
48 if !path.ends_with("json") {
49 return Err(Error::new(
50 ErrorKind::InvalidInput,
51 format!(
52 "File {} does not end with .json",
53 file_path.as_ref().display()
54 ),
55 ));
56 }
57
58 let content = match fs::read_to_string(&file_path) {
59 Ok(content) => content,
60 Err(err) => {
61 println!("Error reading file: {err}");
62 return Err(err);
63 }
64 };
65
66 Ok(Meta {
67 name,
68 r#type,
69 definition_string: content,
70 path: path.to_string(),
71 })
72 }
73}
74
75impl Reader {
88 pub fn from_path(path: &str) -> Option<Reader> {
89 let mut result: Vec<Meta> = vec![];
90
91 for feature_path in fs::read_dir(path).unwrap() {
93 let feature_path_result = match feature_path {
94 Ok(path) => path,
95 Err(_) => continue,
96 };
97
98 let feature_name = match get_file_name(&feature_path_result) {
99 Some(file_name) => file_name,
100 None => continue,
101 };
102
103 for type_path in fs::read_dir(feature_path_result.path()).unwrap() {
105 let type_path_result = match type_path {
106 Ok(path) => path,
107 Err(_) => continue,
108 };
109
110 let meta_type = match get_file_name(&type_path_result) {
111 Some(name) => match name.as_str() {
112 "flow_type" => MetaType::FlowType,
113 "data_type" => MetaType::DataType,
114 "runtime_definition" => MetaType::RuntimeFunction,
115 _ => continue,
116 },
117 None => continue,
118 };
119
120 for definition_path in fs::read_dir(type_path_result.path()).unwrap() {
122 let definition_path_result = match definition_path {
123 Ok(path) => path,
124 Err(_) => continue,
125 };
126
127 if definition_path_result.file_type().unwrap().is_file() {
128 let meta = Meta::read_from_file(
129 feature_name.clone(),
130 meta_type,
131 definition_path_result.path(),
132 );
133
134 if let Ok(meta_result) = meta {
135 result.push(meta_result);
136 }
137 } else {
138 for sub_definition_path in
139 fs::read_dir(definition_path_result.path()).unwrap()
140 {
141 let sub_definition_path_result = match sub_definition_path {
142 Ok(path) => path,
143 Err(_) => continue,
144 };
145
146 let meta = Meta::read_from_file(
147 feature_name.clone(),
148 meta_type,
149 sub_definition_path_result.path(),
150 );
151
152 if let Ok(meta_result) = meta {
153 result.push(meta_result);
154 }
155 }
156 }
157 }
158 }
159 }
160
161 Some(Reader { meta: result })
162 }
163}
164
165fn get_file_name(entry: &DirEntry) -> Option<String> {
166 entry
167 .file_name()
168 .to_str()
169 .map(|file_name| file_name.to_string())
170}