Skip to content

Commit 95b109d

Browse files
Merge pull request #17 from code0-tech/14-rust-definition-reader
Added Definition Reader
2 parents 359894a + b6dca0d commit 95b109d

File tree

8 files changed

+583
-74
lines changed

8 files changed

+583
-74
lines changed

Cargo.lock

Lines changed: 274 additions & 69 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
[package]
2-
name = "code0-definition"
3-
version = "0.1.0"
1+
[workspace]
2+
members = ["cli", "reader/rust"]
3+
4+
[workspace.package]
5+
version = "0.0.1"
46
edition = "2024"
57

6-
[build-dependencies]
8+
[workspace.dependencies]
79
serde = "1.0.219"
810
serde_json = "1.0.140"
9-
tucana = "0.0.31"
11+
tucana = "0.0.32"
12+
13+
[workspace.dependencies.reader]
14+
path = "../code0-definition/reader/rust"

cli/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "cli"
3+
version.workspace = true
4+
edition.workspace = true
5+
6+
[dependencies]
7+
clap = { version = "4.5.41", features = ["derive"] }
8+
reader = { workspace = true }
File renamed without changes.

reader/rust/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "reader"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
serde = { workspace = true }
8+
serde_json = { workspace = true }
9+
tucana = { workspace = true }

reader/rust/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod parser;
2+
pub mod reader;

reader/rust/src/parser.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use crate::reader::{MetaType, Reader};
2+
use serde::Serialize;
3+
use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition};
4+
5+
#[derive(Serialize, Clone, Debug)]
6+
pub struct DefinitionError {
7+
pub definition: String,
8+
pub definition_type: MetaType,
9+
pub error: String,
10+
}
11+
12+
#[derive(Debug)]
13+
pub struct Parser {
14+
pub features: Vec<Feature>,
15+
}
16+
17+
#[derive(Serialize, Clone, Debug)]
18+
pub struct Feature {
19+
pub name: String,
20+
pub data_types: Vec<DefinitionDataType>,
21+
pub flow_types: Vec<FlowType>,
22+
pub runtime_functions: Vec<RuntimeFunctionDefinition>,
23+
pub errors: Vec<DefinitionError>,
24+
}
25+
26+
impl Feature {
27+
fn new(name: String) -> Self {
28+
Feature {
29+
name,
30+
data_types: Vec::new(),
31+
flow_types: Vec::new(),
32+
runtime_functions: Vec::new(),
33+
errors: Vec::new(),
34+
}
35+
}
36+
}
37+
38+
impl Parser {
39+
40+
pub fn from_path(path: &str) -> Option<Self> {
41+
let reader = match Reader::from_path(path) {
42+
Some(reader) => reader,
43+
None => return None,
44+
};
45+
46+
Some(Self::from_reader(reader))
47+
}
48+
49+
pub fn from_reader(reader: Reader) -> Self {
50+
let mut features: Vec<Feature> = vec![];
51+
52+
for meta in &reader.meta {
53+
let feature = features.iter_mut().find(|f| f.name == meta.name);
54+
55+
if let Some(existing) = feature {
56+
Parser::append_meta(existing, meta);
57+
} else {
58+
let mut new_feature = Feature::new(meta.name.clone());
59+
Parser::append_meta(&mut new_feature, meta);
60+
features.push(new_feature);
61+
}
62+
}
63+
64+
Parser { features }
65+
}
66+
67+
fn append_meta(feature: &mut Feature, meta: &crate::reader::Meta) {
68+
for definition in &meta.data {
69+
match meta.r#type {
70+
MetaType::DataType => {
71+
match serde_json::from_str::<DefinitionDataType>(definition) {
72+
Ok(data_type) => feature.data_types.push(data_type),
73+
Err(err) => feature.errors.push(DefinitionError {
74+
definition: definition.to_string(),
75+
definition_type: MetaType::DataType,
76+
error: err.to_string()
77+
})
78+
}
79+
}
80+
MetaType::FlowType => match serde_json::from_str::<FlowType>(definition) {
81+
Ok(flow_type) => feature.flow_types.push(flow_type),
82+
Err(err) => feature.errors.push(DefinitionError {
83+
definition: definition.to_string(),
84+
definition_type: MetaType::FlowType,
85+
error: err.to_string()
86+
})
87+
},
88+
MetaType::RuntimeFunction => {
89+
match serde_json::from_str::<RuntimeFunctionDefinition>(definition) {
90+
Ok(func) => feature.runtime_functions.push(func),
91+
Err(err) => feature.errors.push(DefinitionError {
92+
definition: definition.to_string(),
93+
definition_type: MetaType::RuntimeFunction,
94+
error: err.to_string()
95+
})
96+
}
97+
}
98+
}
99+
}
100+
}
101+
}

reader/rust/src/reader.rs

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

0 commit comments

Comments
 (0)