Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
343 changes: 274 additions & 69 deletions Cargo.lock

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
[package]
name = "code0-definition"
version = "0.1.0"
[workspace]
members = ["cli", "reader/rust"]

[workspace.package]
version = "0.0.1"
edition = "2024"

[build-dependencies]
[workspace.dependencies]
serde = "1.0.219"
serde_json = "1.0.140"
tucana = "0.0.31"
tucana = "0.0.32"

[workspace.dependencies.reader]
path = "../code0-definition/reader/rust"
8 changes: 8 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "cli"
version.workspace = true
edition.workspace = true

[dependencies]
clap = { version = "4.5.41", features = ["derive"] }
reader = { workspace = true }
File renamed without changes.
9 changes: 9 additions & 0 deletions reader/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "reader"
version = "0.1.0"
edition = "2024"

[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tucana = { workspace = true }
2 changes: 2 additions & 0 deletions reader/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod parser;
pub mod reader;
101 changes: 101 additions & 0 deletions reader/rust/src/parser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use crate::reader::{MetaType, Reader};
use serde::Serialize;
use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition};

#[derive(Serialize, Clone, Debug)]
pub struct DefinitionError {
pub definition: String,
pub definition_type: MetaType,
pub error: String,
}

#[derive(Debug)]
pub struct Parser {
pub features: Vec<Feature>,
}

#[derive(Serialize, Clone, Debug)]
pub struct Feature {
pub name: String,
pub data_types: Vec<DefinitionDataType>,
pub flow_types: Vec<FlowType>,
pub runtime_functions: Vec<RuntimeFunctionDefinition>,
pub errors: Vec<DefinitionError>,
}

impl Feature {
fn new(name: String) -> Self {
Feature {
name,
data_types: Vec::new(),
flow_types: Vec::new(),
runtime_functions: Vec::new(),
errors: Vec::new(),
}
}
}

impl Parser {

pub fn from_path(path: &str) -> Option<Self> {
let reader = match Reader::from_path(path) {
Some(reader) => reader,
None => return None,
};

Some(Self::from_reader(reader))
}

pub fn from_reader(reader: Reader) -> Self {
let mut features: Vec<Feature> = vec![];

for meta in &reader.meta {
let feature = features.iter_mut().find(|f| f.name == meta.name);

if let Some(existing) = feature {
Parser::append_meta(existing, meta);
} else {
let mut new_feature = Feature::new(meta.name.clone());
Parser::append_meta(&mut new_feature, meta);
features.push(new_feature);
}
}

Parser { features }
}

fn append_meta(feature: &mut Feature, meta: &crate::reader::Meta) {
for definition in &meta.data {
match meta.r#type {
MetaType::DataType => {
match serde_json::from_str::<DefinitionDataType>(definition) {
Ok(data_type) => feature.data_types.push(data_type),
Err(err) => feature.errors.push(DefinitionError {
definition: definition.to_string(),
definition_type: MetaType::DataType,
error: err.to_string()
})
}
}
MetaType::FlowType => match serde_json::from_str::<FlowType>(definition) {
Ok(flow_type) => feature.flow_types.push(flow_type),
Err(err) => feature.errors.push(DefinitionError {
definition: definition.to_string(),
definition_type: MetaType::FlowType,
error: err.to_string()
})
},
MetaType::RuntimeFunction => {
match serde_json::from_str::<RuntimeFunctionDefinition>(definition) {
Ok(func) => feature.runtime_functions.push(func),
Err(err) => feature.errors.push(DefinitionError {
definition: definition.to_string(),
definition_type: MetaType::RuntimeFunction,
error: err.to_string()
})
}
}
}
}
}
}
179 changes: 179 additions & 0 deletions reader/rust/src/reader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
use std::{
fs::{self, DirEntry},
io::Error,
path::Path,
};

#[derive(Debug, Clone, Copy)]
pub enum MetaType {
FlowType,
DataType,
RuntimeFunction,
}

#[derive(Debug)]
pub struct Reader {
pub meta: Vec<Meta>,
}

#[derive(Debug)]
pub struct Meta {
pub name: String,
pub r#type: MetaType,
pub data: Vec<String>,
}

impl Meta {
pub fn read_from_file<P>(name: String, r#type: MetaType, file_path: P) -> Result<Meta, Error>
where
P: AsRef<Path>,
{
let mut inside_code = false;
let mut current_block = vec![];
let mut code_snippets = vec![];

let content = match fs::read_to_string(file_path) {
Ok(content) => content,
Err(err) => {
println!("Error reading file: {}", err);
return Err(err);
}
};

for line in content.lines() {
if line.contains("```") {
inside_code = !inside_code;

if !inside_code {
let code_snippet = current_block.join(" ");
code_snippets.push(code_snippet);
current_block.clear();
}
}

if inside_code {
if line.starts_with("```") {
continue;
}

current_block.push(line.to_string());
}
}

Ok(Meta {
name: name,
r#type: r#type,
data: code_snippets,
})
}
}

/// Reader
///
/// Expecting the file system too look like:
/// - <path>
/// - <feature>
/// - <flow_types>
/// - <data_types>
/// - <runtime_functions>
/// - <feature>
/// - <flow_types>
/// - <data_types>
/// - <runtime_functions>
impl Reader {
pub fn from_path(path: &str) -> Option<Reader> {
let mut result: Vec<Meta> = vec![];

// Reading the path folder
for feature_path in fs::read_dir(path).unwrap() {
let feature_path_result = match feature_path {
Ok(path) => path,
Err(_) => continue,
};

let feature_name = match get_file_name(&feature_path_result) {
Some(file_name) => file_name,
None => continue,
};

// Reading the feature folder
for type_path in fs::read_dir(feature_path_result.path()).unwrap() {

let type_path_result = match type_path {
Ok(path) => path,
Err(_) => continue,
};

let meta_type = match get_file_name(&type_path_result) {
Some(name) => match name.as_str() {
"flow_type" => MetaType::FlowType,
"data_type" => MetaType::DataType,
"runtime_definition" => MetaType::RuntimeFunction,
_ => continue,
},
None => continue,
};

// Reading the type folder
for definition_path in fs::read_dir(type_path_result.path()).unwrap() {

let definition_path_result = match definition_path {
Ok(path) => path,
Err(_) => continue,
};

if definition_path_result.file_type().unwrap().is_file() {
let meta = Meta::read_from_file(
feature_name.clone(),
meta_type,
definition_path_result.path(),
);

match meta {
Ok(meta_result) => {
result.push(meta_result);
}
Err(err) => {
println!("Error reading meta: {:?}", err);
}
}
} else {
for sub_definition_path in
fs::read_dir(definition_path_result.path()).unwrap()
{
let sub_definition_path_result = match sub_definition_path {
Ok(path) => path,
Err(_) => continue,
};

let meta = Meta::read_from_file(
feature_name.clone(),
meta_type,
sub_definition_path_result.path(),
);

match meta {
Ok(meta_result) => {
result.push(meta_result);
}
Err(err) => {
println!("Error reading meta: {:?}", err);
}
}
}
}
}
}
}

Some(Reader { meta: result })
}
}

fn get_file_name(entry: &DirEntry) -> Option<String> {
if let Some(file_name) = entry.file_name().to_str() {
Some(file_name.to_string())
} else {
None
}
}