From b3de25914c96db63fd0c67e751c8d54e15a9b452 Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Tue, 11 Nov 2025 22:08:16 +0100 Subject: [PATCH 01/11] [feat] reimplement reader --- Cargo.lock | 2 + crates/package/Cargo.toml | 8 +- crates/package/src/lib.rs | 351 +++++++++----------------------------- 3 files changed, 91 insertions(+), 270 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 828eab0..93d745c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,9 +315,11 @@ dependencies = [ name = "code0-definition-reader" version = "0.0.0" dependencies = [ + "log", "serde", "serde_json", "tucana", + "walkdir", ] [[package]] diff --git a/crates/package/Cargo.toml b/crates/package/Cargo.toml index c598b3f..c93f39e 100644 --- a/crates/package/Cargo.toml +++ b/crates/package/Cargo.toml @@ -9,6 +9,8 @@ license = "Apache-2.0" readme = "../../README.md" [dependencies] -serde = { workspace = true } -serde_json = { workspace = true } -tucana = { workspace = true } \ No newline at end of file +walkdir = "2.5.0" +serde_json = "1.0.145" +serde = "1.0.228" +tucana = {workspace = true} +log = "0.4.28" \ No newline at end of file diff --git a/crates/package/src/lib.rs b/crates/package/src/lib.rs index a84d348..1701513 100644 --- a/crates/package/src/lib.rs +++ b/crates/package/src/lib.rs @@ -1,300 +1,117 @@ -pub mod package { - use serde::Serialize; - use std::io::ErrorKind; - use std::{ - fs::{self, DirEntry}, - io::Error, - path::Path, - }; - 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, - } +use std::{fs, io}; +use std::path::Path; +use serde::de::DeserializeOwned; +use serde::Deserialize; +use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition}; +use walkdir::WalkDir; + +#[derive(Deserialize, Debug)] +pub struct Feature { + pub name: String, + pub data_types: Vec, + pub flow_types: Vec, + pub functions: Vec +} - #[derive(Serialize, Clone, Debug)] - pub struct Feature { - pub name: String, - pub data_types: Vec, - pub flow_types: Vec, - pub runtime_functions: Vec, - pub errors: Vec, - } +pub fn read_features(path: &str) -> Result, io::Error> { + let definitions = Path::new(path); - impl Feature { - fn new(name: String) -> Self { - Feature { - name, - data_types: Vec::new(), - flow_types: Vec::new(), - runtime_functions: Vec::new(), - errors: Vec::new(), - } + match read_feature_content(definitions) { + Ok(features) => { + log::info!("Loaded Successfully {} features", features.len()); + Ok(features) + } + Err(err) => { + panic!("Cannot loaded content: {}", err) } } +} - impl Parser { - pub fn from_path(path: &str) -> Option { - let reader = Reader::from_path(path)?; - - Some(Self::from_reader(reader)) +fn read_feature_content(dir: &Path) -> Result, io::Error> { + let mut features: Vec = Vec::new(); + let readdir = match fs::read_dir(dir) { + Ok(readdir) => readdir, + Err(err) => { + log::error!("Failed to read directory {}: {}", dir.display(), err); + return Err(err); } + }; - pub fn from_reader(reader: Reader) -> Self { - let mut features: Vec = 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); - } + for entry_result in readdir { + let entry = match entry_result { + Ok(entry) => entry, + Err(err) => { + log::error!("Failed to read directory entry: {}", err); + continue; } + }; - Parser { features } - } + let path = entry.path(); - pub fn extract_identifier(definition: &str, meta_type: MetaType) -> String { - let field_name = match meta_type { - MetaType::DataType | MetaType::FlowType => "identifier", - MetaType::RuntimeFunction => "runtime_name", - }; + if path.is_dir() { + let feature_name = path + .file_name() + .unwrap_or_default() + .to_string_lossy() + .to_string(); - // Look for the field pattern: "field_name": "value" or "field_name":"value" - if let Some(start) = definition.find(&format!("\"{field_name}\"")) { - // Find the colon after the field name - if let Some(colon_pos) = definition[start..].find(':') { - let after_colon = &definition[start + colon_pos + 1..]; + let data_types_path = path.join("data_type"); + let data_types: Vec = collect_definitions(&data_types_path)?; - // Skip whitespace and find the opening quote - let trimmed = after_colon.trim_start(); - if let Some(stripped) = trimmed.strip_prefix('"') { - // Find the closing quote - if let Some(end_quote) = stripped.find('"') { - return trimmed[1..end_quote + 1].to_string(); - } - } - } - } + let flow_types_path = path.join("flow_type"); + let flow_types: Vec = collect_definitions(&flow_types_path)?; - // Fallback: return the whole definition if identifier can't be extracted - definition.to_string() - } + let functions_path = path.join("runtime_definition"); + let functions: Vec = collect_definitions(&functions_path)?; - fn append_meta(feature: &mut Feature, meta: &Meta) { - let definition = meta.definition_string.as_str(); - match meta.r#type { - MetaType::DataType => { - match serde_json::from_str::(definition) { - Ok(data_type) => feature.data_types.push(data_type), - Err(err) => feature.errors.push(DefinitionError { - definition: Parser::extract_identifier(definition, MetaType::DataType), - definition_type: MetaType::DataType, - error: err.to_string(), - }), - } - } - MetaType::FlowType => match serde_json::from_str::(definition) { - Ok(flow_type) => feature.flow_types.push(flow_type), - Err(err) => feature.errors.push(DefinitionError { - definition: Parser::extract_identifier(definition, MetaType::FlowType), - definition_type: MetaType::FlowType, - error: err.to_string(), - }), - }, - MetaType::RuntimeFunction => { - match serde_json::from_str::(definition) { - Ok(func) => feature.runtime_functions.push(func), - Err(err) => feature.errors.push(DefinitionError { - definition: Parser::extract_identifier( - definition, - MetaType::RuntimeFunction, - ), - definition_type: MetaType::RuntimeFunction, - error: err.to_string(), - }), - } - } - } - } - } - - #[derive(Serialize, Debug, Clone, Copy)] - pub enum MetaType { - FlowType, - DataType, - RuntimeFunction, - } + let feature = Feature { + name: feature_name, + data_types, + flow_types, + functions, + }; - impl std::fmt::Display for MetaType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - MetaType::FlowType => write!(f, "FlowType"), - MetaType::DataType => write!(f, "DataType"), - MetaType::RuntimeFunction => write!(f, "RuntimeFunction"), - } + features.push(feature); } } - pub struct Reader { - pub meta: Vec, - } + Ok(features) +} - #[derive(Clone)] - pub struct Meta { - pub name: String, - pub r#type: MetaType, - pub definition_string: String, - pub path: String, +fn collect_definitions(dir: &Path) -> Result, io::Error> +where + T: DeserializeOwned, +{ + let mut definitions = Vec::new(); + + if !dir.exists() { + return Ok(definitions); } - impl Meta { - pub fn read_from_file

( - name: String, - r#type: MetaType, - file_path: P, - ) -> Result - where - P: AsRef, - { - let path = match file_path.as_ref().to_str() { - Some(path) => path, - None => return Err(Error::new(ErrorKind::InvalidInput, "Invalid path")), - }; + for entry in WalkDir::new(dir) + .into_iter() + .filter_map(Result::ok) + { + let path = entry.path(); - if !path.ends_with("json") { - return Err(Error::new( - ErrorKind::InvalidInput, - format!( - "File {} does not end with .json", - file_path.as_ref().display() - ), - )); - } + if path.is_file() && path.extension().map_or(false, |ext| ext == "json") { - let content = match fs::read_to_string(&file_path) { + let content = match fs::read_to_string(path) { Ok(content) => content, Err(err) => { - println!("Error reading file: {err}"); - return Err(err); + log::error!("Failed to read file {}: {}", path.display(), err); + continue; } }; - Ok(Meta { - name, - r#type, - definition_string: content, - path: path.to_string(), - }) - } - } - - /// Reader - /// - /// Expecting the file system to look like: - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - impl Reader { - pub fn from_path(path: &str) -> Option { - let mut result: Vec = 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(), - ); - - if let Ok(meta_result) = meta { - result.push(meta_result); - } - } 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(), - ); - - if let Ok(meta_result) = meta { - result.push(meta_result); - } - } - } - } + match serde_json::from_str::(&content) { + Ok(def) => definitions.push(def), + Err(e) => { + log::error!("Failed to parse JSON in file {}: {}", path.display(), e); } } - - Some(Reader { meta: result }) } } - fn get_file_name(entry: &DirEntry) -> Option { - entry - .file_name() - .to_str() - .map(|file_name| file_name.to_string()) - } -} + Ok(definitions) +} \ No newline at end of file From 86eafd189caccd3701ee23d6caa1513f885a0580 Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Tue, 11 Nov 2025 22:13:45 +0100 Subject: [PATCH 02/11] [feat] reimplement reader --- crates/package/Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/package/Cargo.toml b/crates/package/Cargo.toml index c93f39e..3bae6d1 100644 --- a/crates/package/Cargo.toml +++ b/crates/package/Cargo.toml @@ -9,8 +9,8 @@ license = "Apache-2.0" readme = "../../README.md" [dependencies] -walkdir = "2.5.0" -serde_json = "1.0.145" -serde = "1.0.228" +walkdir = {workspace = true} +serde_json = {workspace = true} +serde = {workspace = true} tucana = {workspace = true} -log = "0.4.28" \ No newline at end of file +log = {workspace = true} \ No newline at end of file From 3098ada0fe86db84b9d8a46ec849b8aeccb2c7be Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Tue, 11 Nov 2025 22:14:37 +0100 Subject: [PATCH 03/11] [deps] walkDir edit --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 393f1a6..65d70b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,4 +18,5 @@ tokio = "1.47.0" futures = "0.3.31" zip = "6.0.0" bytes = "1.10.1" -prost = "0.14.1" \ No newline at end of file +prost = "0.14.1" +walkdir = "2.5.0" \ No newline at end of file From e026120c6cebe4ef59fe16e55cb471a0a3976a14 Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Tue, 11 Nov 2025 22:23:22 +0100 Subject: [PATCH 04/11] [deps] log edit --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 65d70b8..5b6aada 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,4 +19,5 @@ futures = "0.3.31" zip = "6.0.0" bytes = "1.10.1" prost = "0.14.1" -walkdir = "2.5.0" \ No newline at end of file +walkdir = "2.5.0" +log = "0.4.28" \ No newline at end of file From e5f96695711c31b2a579af53f92a8ffe8ee9d8a2 Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Tue, 11 Nov 2025 22:28:11 +0100 Subject: [PATCH 05/11] [ref] cargo clippy & format --- crates/cli/src/analyser/flow_type.rs | 40 ++++++++++++++-------------- crates/package/src/lib.rs | 18 +++++-------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/crates/cli/src/analyser/flow_type.rs b/crates/cli/src/analyser/flow_type.rs index 1ecb51a..beb8feb 100644 --- a/crates/cli/src/analyser/flow_type.rs +++ b/crates/cli/src/analyser/flow_type.rs @@ -36,27 +36,27 @@ impl Analyser { )); } - if let Some(identifier) = &flow.input_type_identifier { - if !self.data_type_identifier_exists(identifier, None) { - self.reporter.add(Diagnose::new( - name.clone(), - original.clone(), - DiagnosticKind::UndefinedDataTypeIdentifier { - identifier: identifier.clone(), - }, - )); - } + if let Some(identifier) = &flow.input_type_identifier + && !self.data_type_identifier_exists(identifier, None) + { + self.reporter.add(Diagnose::new( + name.clone(), + original.clone(), + DiagnosticKind::UndefinedDataTypeIdentifier { + identifier: identifier.clone(), + }, + )); } - if let Some(identifier) = &flow.return_type_identifier { - if !self.data_type_identifier_exists(identifier, None) { - self.reporter.add(Diagnose::new( - name.clone(), - original.clone(), - DiagnosticKind::UndefinedDataTypeIdentifier { - identifier: identifier.clone(), - }, - )); - } + if let Some(identifier) = &flow.return_type_identifier + && !self.data_type_identifier_exists(identifier, None) + { + self.reporter.add(Diagnose::new( + name.clone(), + original.clone(), + DiagnosticKind::UndefinedDataTypeIdentifier { + identifier: identifier.clone(), + }, + )); } for setting in &flow.settings { diff --git a/crates/package/src/lib.rs b/crates/package/src/lib.rs index 1701513..86be71e 100644 --- a/crates/package/src/lib.rs +++ b/crates/package/src/lib.rs @@ -1,7 +1,7 @@ -use std::{fs, io}; -use std::path::Path; -use serde::de::DeserializeOwned; use serde::Deserialize; +use serde::de::DeserializeOwned; +use std::path::Path; +use std::{fs, io}; use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition}; use walkdir::WalkDir; @@ -10,7 +10,7 @@ pub struct Feature { pub name: String, pub data_types: Vec, pub flow_types: Vec, - pub functions: Vec + pub functions: Vec, } pub fn read_features(path: &str) -> Result, io::Error> { @@ -88,14 +88,10 @@ where return Ok(definitions); } - for entry in WalkDir::new(dir) - .into_iter() - .filter_map(Result::ok) - { + for entry in WalkDir::new(dir).into_iter().filter_map(Result::ok) { let path = entry.path(); - if path.is_file() && path.extension().map_or(false, |ext| ext == "json") { - + if path.is_file() && path.extension().is_some_and(|ext| ext == "json") { let content = match fs::read_to_string(path) { Ok(content) => content, Err(err) => { @@ -114,4 +110,4 @@ where } Ok(definitions) -} \ No newline at end of file +} From 29a3232f41d81e711829fab9df6d18d4357fd9d3 Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Wed, 12 Nov 2025 20:20:50 +0100 Subject: [PATCH 06/11] [feat] custom Error Handling --- crates/package/src/lib.rs | 181 ++++++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 75 deletions(-) diff --git a/crates/package/src/lib.rs b/crates/package/src/lib.rs index 86be71e..6151555 100644 --- a/crates/package/src/lib.rs +++ b/crates/package/src/lib.rs @@ -1,11 +1,11 @@ use serde::Deserialize; use serde::de::DeserializeOwned; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::{fs, io}; -use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition}; +use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition, Version}; use walkdir::WalkDir; -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] pub struct Feature { pub name: String, pub data_types: Vec, @@ -13,101 +13,132 @@ pub struct Feature { pub functions: Vec, } -pub fn read_features(path: &str) -> Result, io::Error> { - let definitions = Path::new(path); +pub struct Reader { + should_break: bool, + accepted_features: Vec, + accepted_versions: Option, + path: String, +} - match read_feature_content(definitions) { - Ok(features) => { - log::info!("Loaded Successfully {} features", features.len()); - Ok(features) - } - Err(err) => { - panic!("Cannot loaded content: {}", err) - } - } +pub enum ReaderError { + JsonError { path: PathBuf, error: serde_json::Error }, + ReadFeatureError { path: String, source: Box }, + ReadDirectoryError { path: PathBuf, error: io::Error }, + ReadFileError { path: PathBuf, error: io::Error }, + DirectoryEntryError(io::Error), } -fn read_feature_content(dir: &Path) -> Result, io::Error> { - let mut features: Vec = Vec::new(); - let readdir = match fs::read_dir(dir) { - Ok(readdir) => readdir, - Err(err) => { - log::error!("Failed to read directory {}: {}", dir.display(), err); - return Err(err); +impl Reader { + pub fn read_features(&self, path: &str) -> Result, ReaderError> { + let definitions = Path::new(path); + + match self.read_feature_content(definitions) { + Ok(features) => { + log::info!("Loaded Successfully {} features", features.len()); + Ok(features) + } + Err(err) => { + log::error!("Failed to read features from {}", path); + Err(ReaderError::ReadFeatureError { + path: path.to_string(), + source: Box::new(err), + }) + } } - }; + } - for entry_result in readdir { - let entry = match entry_result { - Ok(entry) => entry, + fn read_feature_content(&self, dir: &Path) -> Result, ReaderError> { + let mut features: Vec = Vec::new(); + let readdir = match fs::read_dir(dir) { + Ok(readdir) => readdir, Err(err) => { - log::error!("Failed to read directory entry: {}", err); - continue; + log::error!("Failed to read directory {}: {}", dir.display(), err); + return Err(ReaderError::ReadDirectoryError { + path: dir.to_path_buf(), + error: err, + }); } }; - let path = entry.path(); + for entry_result in readdir { + let entry = match entry_result { + Ok(entry) => entry, + Err(err) => { + log::error!("Failed to read directory entry: {}", err); + return Err(ReaderError::DirectoryEntryError(err)); + } + }; - if path.is_dir() { - let feature_name = path - .file_name() - .unwrap_or_default() - .to_string_lossy() - .to_string(); + let path = entry.path(); - let data_types_path = path.join("data_type"); - let data_types: Vec = collect_definitions(&data_types_path)?; + if path.is_dir() { + let feature_name = path + .file_name() + .unwrap_or_default() + .to_string_lossy() + .to_string(); - let flow_types_path = path.join("flow_type"); - let flow_types: Vec = collect_definitions(&flow_types_path)?; + let data_types_path = path.join("data_type"); + let data_types: Vec = self.collect_definitions(&data_types_path)?; - let functions_path = path.join("runtime_definition"); - let functions: Vec = collect_definitions(&functions_path)?; + let flow_types_path = path.join("flow_type"); + let flow_types: Vec = self.collect_definitions(&flow_types_path)?; - let feature = Feature { - name: feature_name, - data_types, - flow_types, - functions, - }; + let functions_path = path.join("runtime_definition"); + let functions: Vec = self.collect_definitions(&functions_path)?; - features.push(feature); - } - } - - Ok(features) -} + let feature = Feature { + name: feature_name, + data_types, + flow_types, + functions, + }; -fn collect_definitions(dir: &Path) -> Result, io::Error> -where - T: DeserializeOwned, -{ - let mut definitions = Vec::new(); + features.push(feature); + } + } - if !dir.exists() { - return Ok(definitions); + Ok(features) } - for entry in WalkDir::new(dir).into_iter().filter_map(Result::ok) { - let path = entry.path(); + fn collect_definitions(&self, dir: &Path) -> Result, ReaderError> + where + T: DeserializeOwned, + { + let mut definitions = Vec::new(); - if path.is_file() && path.extension().is_some_and(|ext| ext == "json") { - let content = match fs::read_to_string(path) { - Ok(content) => content, - Err(err) => { - log::error!("Failed to read file {}: {}", path.display(), err); - continue; - } - }; + if !dir.exists() { + return Ok(definitions); + } - match serde_json::from_str::(&content) { - Ok(def) => definitions.push(def), - Err(e) => { - log::error!("Failed to parse JSON in file {}: {}", path.display(), e); + for entry in WalkDir::new(dir).into_iter().filter_map(Result::ok) { + let path = entry.path(); + + if path.is_file() && path.extension().is_some_and(|ext| ext == "json") { + let content = match fs::read_to_string(path) { + Ok(content) => content, + Err(err) => { + log::error!("Failed to read file {}: {}", path.display(), err); + return Err(ReaderError::ReadFileError { + path: path.to_path_buf(), + error: err, + }) + } + }; + + match serde_json::from_str::(&content) { + Ok(def) => definitions.push(def), + Err(e) => { + log::error!("Failed to parse JSON in file {}: {}", path.display(), e); + return Err(ReaderError::JsonError { + path: path.to_path_buf(), + error: e, + }); + } } } } - } - Ok(definitions) + Ok(definitions) + } } From 1e59c384234e4370327e32bb46ddac3285ed9d5f Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Wed, 12 Nov 2025 20:21:44 +0100 Subject: [PATCH 07/11] [ref] cargo clippy & format --- crates/package/src/lib.rs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/crates/package/src/lib.rs b/crates/package/src/lib.rs index 6151555..2eb44bf 100644 --- a/crates/package/src/lib.rs +++ b/crates/package/src/lib.rs @@ -21,10 +21,22 @@ pub struct Reader { } pub enum ReaderError { - JsonError { path: PathBuf, error: serde_json::Error }, - ReadFeatureError { path: String, source: Box }, - ReadDirectoryError { path: PathBuf, error: io::Error }, - ReadFileError { path: PathBuf, error: io::Error }, + JsonError { + path: PathBuf, + error: serde_json::Error, + }, + ReadFeatureError { + path: String, + source: Box, + }, + ReadDirectoryError { + path: PathBuf, + error: io::Error, + }, + ReadFileError { + path: PathBuf, + error: io::Error, + }, DirectoryEntryError(io::Error), } @@ -79,13 +91,15 @@ impl Reader { .to_string(); let data_types_path = path.join("data_type"); - let data_types: Vec = self.collect_definitions(&data_types_path)?; + let data_types: Vec = + self.collect_definitions(&data_types_path)?; let flow_types_path = path.join("flow_type"); let flow_types: Vec = self.collect_definitions(&flow_types_path)?; let functions_path = path.join("runtime_definition"); - let functions: Vec = self.collect_definitions(&functions_path)?; + let functions: Vec = + self.collect_definitions(&functions_path)?; let feature = Feature { name: feature_name, @@ -122,7 +136,7 @@ impl Reader { return Err(ReaderError::ReadFileError { path: path.to_path_buf(), error: err, - }) + }); } }; From 08e4cebf3b75f23f117391793a7eb83ca465565e Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Thu, 13 Nov 2025 20:34:22 +0100 Subject: [PATCH 08/11] [feat] outsourcing ReaderError --- crates/package/src/enum/mod.rs | 1 + crates/package/src/enum/reader_error.rs | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 crates/package/src/enum/mod.rs create mode 100644 crates/package/src/enum/reader_error.rs diff --git a/crates/package/src/enum/mod.rs b/crates/package/src/enum/mod.rs new file mode 100644 index 0000000..73faec6 --- /dev/null +++ b/crates/package/src/enum/mod.rs @@ -0,0 +1 @@ +pub mod reader_error; \ No newline at end of file diff --git a/crates/package/src/enum/reader_error.rs b/crates/package/src/enum/reader_error.rs new file mode 100644 index 0000000..f7ce17c --- /dev/null +++ b/crates/package/src/enum/reader_error.rs @@ -0,0 +1,24 @@ +use std::path::PathBuf; +use std::io; +use serde_json; + +#[derive(Debug)] +pub enum ReaderError { + JsonError { + path: PathBuf, + error: serde_json::Error, + }, + ReadFeatureError { + path: String, + source: Box, + }, + ReadDirectoryError { + path: PathBuf, + error: io::Error, + }, + ReadFileError { + path: PathBuf, + error: io::Error, + }, + DirectoryEntryError(io::Error), +} \ No newline at end of file From 92af8c53df28eb241eaa2b7bd3cda504c78c3c3d Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Thu, 13 Nov 2025 20:34:59 +0100 Subject: [PATCH 09/11] [feat] outsourcing Feature struct --- crates/package/src/struct/feature.rs | 10 ++++++++++ crates/package/src/struct/mod.rs | 1 + 2 files changed, 11 insertions(+) create mode 100644 crates/package/src/struct/feature.rs create mode 100644 crates/package/src/struct/mod.rs diff --git a/crates/package/src/struct/feature.rs b/crates/package/src/struct/feature.rs new file mode 100644 index 0000000..50887d7 --- /dev/null +++ b/crates/package/src/struct/feature.rs @@ -0,0 +1,10 @@ +use serde::Deserialize; +use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition}; + +#[derive(Deserialize, Debug, Clone)] +pub struct Feature { + pub name: String, + pub data_types: Vec, + pub flow_types: Vec, + pub functions: Vec, +} \ No newline at end of file diff --git a/crates/package/src/struct/mod.rs b/crates/package/src/struct/mod.rs new file mode 100644 index 0000000..548e340 --- /dev/null +++ b/crates/package/src/struct/mod.rs @@ -0,0 +1 @@ +pub mod feature; \ No newline at end of file From 274ae97f0e9a34591b82e06d716368694e0d8c3e Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Thu, 13 Nov 2025 20:35:23 +0100 Subject: [PATCH 10/11] [feat] outsourcing Feature & ReaderError --- crates/package/src/lib.rs | 52 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/crates/package/src/lib.rs b/crates/package/src/lib.rs index 2eb44bf..734bb52 100644 --- a/crates/package/src/lib.rs +++ b/crates/package/src/lib.rs @@ -1,17 +1,14 @@ +mod r#struct; +mod r#enum; + use serde::Deserialize; use serde::de::DeserializeOwned; use std::path::{Path, PathBuf}; use std::{fs, io}; use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition, Version}; use walkdir::WalkDir; - -#[derive(Deserialize, Debug, Clone)] -pub struct Feature { - pub name: String, - pub data_types: Vec, - pub flow_types: Vec, - pub functions: Vec, -} +use crate::r#enum::reader_error::ReaderError; +use crate::r#struct::feature::Feature; pub struct Reader { should_break: bool, @@ -20,27 +17,21 @@ pub struct Reader { path: String, } -pub enum ReaderError { - JsonError { - path: PathBuf, - error: serde_json::Error, - }, - ReadFeatureError { +impl Reader { + pub fn configure( path: String, - source: Box, - }, - ReadDirectoryError { - path: PathBuf, - error: io::Error, - }, - ReadFileError { - path: PathBuf, - error: io::Error, - }, - DirectoryEntryError(io::Error), -} + should_break: bool, + accepted_features: Vec, + accepted_versions: Option, + ) -> Self { + Self { + should_break, + accepted_features, + accepted_versions, + path, + } + } -impl Reader { pub fn read_features(&self, path: &str) -> Result, ReaderError> { let definitions = Path::new(path); @@ -90,6 +81,13 @@ impl Reader { .to_string_lossy() .to_string(); + if !self.accepted_features.is_empty() + && !self.accepted_features.contains(&feature_name) + { + log::info!("Skipping feature: {}", feature_name); + continue; + } + let data_types_path = path.join("data_type"); let data_types: Vec = self.collect_definitions(&data_types_path)?; From 9290c1b844b8e00de907d566a658ffe02598a46b Mon Sep 17 00:00:00 2001 From: Joe Jobst Date: Thu, 13 Nov 2025 20:36:09 +0100 Subject: [PATCH 11/11] [ref] cargo clippy & format --- crates/package/src/enum/mod.rs | 2 +- crates/package/src/enum/reader_error.rs | 6 +++--- crates/package/src/lib.rs | 11 +++++------ crates/package/src/struct/feature.rs | 2 +- crates/package/src/struct/mod.rs | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/crates/package/src/enum/mod.rs b/crates/package/src/enum/mod.rs index 73faec6..e98e7c8 100644 --- a/crates/package/src/enum/mod.rs +++ b/crates/package/src/enum/mod.rs @@ -1 +1 @@ -pub mod reader_error; \ No newline at end of file +pub mod reader_error; diff --git a/crates/package/src/enum/reader_error.rs b/crates/package/src/enum/reader_error.rs index f7ce17c..9c62cd0 100644 --- a/crates/package/src/enum/reader_error.rs +++ b/crates/package/src/enum/reader_error.rs @@ -1,6 +1,6 @@ -use std::path::PathBuf; -use std::io; use serde_json; +use std::io; +use std::path::PathBuf; #[derive(Debug)] pub enum ReaderError { @@ -21,4 +21,4 @@ pub enum ReaderError { error: io::Error, }, DirectoryEntryError(io::Error), -} \ No newline at end of file +} diff --git a/crates/package/src/lib.rs b/crates/package/src/lib.rs index 734bb52..c6546bd 100644 --- a/crates/package/src/lib.rs +++ b/crates/package/src/lib.rs @@ -1,14 +1,13 @@ -mod r#struct; mod r#enum; +mod r#struct; -use serde::Deserialize; +use crate::r#enum::reader_error::ReaderError; +use crate::r#struct::feature::Feature; use serde::de::DeserializeOwned; -use std::path::{Path, PathBuf}; -use std::{fs, io}; +use std::fs; +use std::path::Path; use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition, Version}; use walkdir::WalkDir; -use crate::r#enum::reader_error::ReaderError; -use crate::r#struct::feature::Feature; pub struct Reader { should_break: bool, diff --git a/crates/package/src/struct/feature.rs b/crates/package/src/struct/feature.rs index 50887d7..8f815cc 100644 --- a/crates/package/src/struct/feature.rs +++ b/crates/package/src/struct/feature.rs @@ -7,4 +7,4 @@ pub struct Feature { pub data_types: Vec, pub flow_types: Vec, pub functions: Vec, -} \ No newline at end of file +} diff --git a/crates/package/src/struct/mod.rs b/crates/package/src/struct/mod.rs index 548e340..c193906 100644 --- a/crates/package/src/struct/mod.rs +++ b/crates/package/src/struct/mod.rs @@ -1 +1 @@ -pub mod feature; \ No newline at end of file +pub mod feature;