code0_definition_reader/
parser.rs1use crate::reader::{MetaType, Reader};
2use serde::Serialize;
3use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition};
4
5#[derive(Serialize, Clone, Debug)]
6pub struct DefinitionError {
7 pub definition: String,
8 pub definition_type: MetaType,
9 pub error: String,
10}
11
12#[derive(Debug)]
13pub struct Parser {
14 pub features: Vec<Feature>,
15}
16
17#[derive(Serialize, Clone, Debug)]
18pub 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
26impl 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
38impl Parser {
39 pub fn from_path(path: &str) -> Option<Self> {
40 let reader = Reader::from_path(path)?;
41
42 Some(Self::from_reader(reader))
43 }
44
45 pub fn from_reader(reader: Reader) -> Self {
46 let mut features: Vec<Feature> = vec![];
47
48 for meta in &reader.meta {
49 let feature = features.iter_mut().find(|f| f.name == meta.name);
50
51 if let Some(existing) = feature {
52 Parser::append_meta(existing, meta);
53 } else {
54 let mut new_feature = Feature::new(meta.name.clone());
55 Parser::append_meta(&mut new_feature, meta);
56 features.push(new_feature);
57 }
58 }
59
60 Parser { features }
61 }
62
63 fn extract_identifier(definition: &str, meta_type: MetaType) -> String {
64 let field_name = match meta_type {
65 MetaType::DataType | MetaType::FlowType => "identifier",
66 MetaType::RuntimeFunction => "runtime_name",
67 };
68
69 if let Some(start) = definition.find(&format!("\"{field_name}\"")) {
71 if let Some(colon_pos) = definition[start..].find(':') {
73 let after_colon = &definition[start + colon_pos + 1..];
74
75 let trimmed = after_colon.trim_start();
77 if let Some(stripped) = trimmed.strip_prefix('"') {
78 if let Some(end_quote) = stripped.find('"') {
80 return trimmed[1..end_quote + 1].to_string();
81 }
82 }
83 }
84 }
85
86 definition.to_string()
88 }
89
90 fn append_meta(feature: &mut Feature, meta: &crate::reader::Meta) {
91 for definition in &meta.data {
92 match meta.r#type {
93 MetaType::DataType => {
94 match serde_json::from_str::<DefinitionDataType>(definition) {
95 Ok(data_type) => feature.data_types.push(data_type),
96 Err(err) => feature.errors.push(DefinitionError {
97 definition: Parser::extract_identifier(definition, MetaType::DataType),
98 definition_type: MetaType::DataType,
99 error: err.to_string(),
100 }),
101 }
102 }
103 MetaType::FlowType => match serde_json::from_str::<FlowType>(definition) {
104 Ok(flow_type) => feature.flow_types.push(flow_type),
105 Err(err) => feature.errors.push(DefinitionError {
106 definition: Parser::extract_identifier(definition, MetaType::FlowType),
107 definition_type: MetaType::FlowType,
108 error: err.to_string(),
109 }),
110 },
111 MetaType::RuntimeFunction => {
112 match serde_json::from_str::<RuntimeFunctionDefinition>(definition) {
113 Ok(func) => feature.runtime_functions.push(func),
114 Err(err) => feature.errors.push(DefinitionError {
115 definition: Parser::extract_identifier(
116 definition,
117 MetaType::RuntimeFunction,
118 ),
119 definition_type: MetaType::RuntimeFunction,
120 error: err.to_string(),
121 }),
122 }
123 }
124 }
125 }
126 }
127}