From 511be9df4635d2e1a92e13c5ef957e5db3043b47 Mon Sep 17 00:00:00 2001 From: Robert Mitwicki Date: Tue, 7 Nov 2023 20:22:07 +0100 Subject: [PATCH 1/2] feat(ocafile): Add support for refs and refn Support for reference sytanx in OCAfile: refs - SAID reference refn - name reference --- oca-file/src/ocafile.pest | 27 ++++++------ oca-file/src/ocafile/instructions/add.rs | 4 ++ oca-file/src/ocafile/instructions/helpers.rs | 46 +++++++++++++++----- oca/src/facade/fetch.rs | 13 ++++++ 4 files changed, 65 insertions(+), 25 deletions(-) diff --git a/oca-file/src/ocafile.pest b/oca-file/src/ocafile.pest index dcbfc3e..e83c4dc 100644 --- a/oca-file/src/ocafile.pest +++ b/oca-file/src/ocafile.pest @@ -171,19 +171,20 @@ attr_entry_key_pairs = ${ (arg_ws? ~ entry_key_pair ~ arg_ws?)+ } list_value = ${ (arg_ws? ~ key_value ~ arg_ws?)+ } unit_system = ${ (ASCII_ALPHANUMERIC | "-" | "_")+ } -attr_type = ${ ("Text" | - "Numeric" | - "Reference" | - "Boolean" | - "Binary" | - "DateTime" | - "Array[Text]" | - "Array[Numeric]" | - "Array[Reference]" | - "Array[Boolean]" | - "Array[Binary]" | - "Array[DateTime]" )} -attr_pair = @{attr_key ~ "=" ~ attr_type} +attr_type = @{ ("Text" | + "Numeric" | + "Boolean" | + "Binary" | + "DateTime" | + "Array[Text]" | + "Array[Numeric]" | + "Array[Boolean]" | + "Array[Binary]" | + "Array[DateTime]" )} +reference = @{ char+ } +said = @{ char+ } +_attr_type = ${ attr_type | (^"refs:" ~ said) | (^"refn:" ~ reference) } +attr_pair = @{attr_key ~ "=" ~ _attr_type} attr_pairs = ${ (arg_ws ~ attr_pair)+} lang = ${ ASCII_ALPHA{2} ~ ("-" ~ ASCII_ALPHA{2})? } diff --git a/oca-file/src/ocafile/instructions/add.rs b/oca-file/src/ocafile/instructions/add.rs index 67297ce..b4d2d76 100644 --- a/oca-file/src/ocafile/instructions/add.rs +++ b/oca-file/src/ocafile/instructions/add.rs @@ -47,6 +47,7 @@ impl AddInstruction { } } } + debug!("Attributes: {:?}", attributes); Some(Content { properties: None, attributes: Some(attributes), @@ -147,6 +148,8 @@ mod tests { fn test_add_attribute_instruction() { // test vector with example instruction and boolean if they should be valid or not let instructions = vec![ + ("ADD ATTRIBUTE documentNumber=snieg documentType=refs:12d1j02dj1092dj1092jd1092", false), + ("ADD ATTRIBUTE documentNumber=refn:snieg documentType=refs:12d1j02dj1092dj1092jd1092", true), ("ADD ATTRIBUTE documentNumber=Text documentType=Numeric", true), ("ADD ATTRIBUTE documentNumber=Text documentType=Numeric name=Text list=Array[Numeric]", true), ("ADD ATTRIBUTE name=Text", false), @@ -155,6 +158,7 @@ mod tests { ("add attribute name=Text", true), ("add attribute name=Random", false), ]; + let _ = env_logger::builder().is_test(true).try_init(); // loop over instructions to check if the are meeting the requirements for (instruction, is_valid) in instructions { diff --git a/oca-file/src/ocafile/instructions/helpers.rs b/oca-file/src/ocafile/instructions/helpers.rs index e2d418a..784cfac 100644 --- a/oca-file/src/ocafile/instructions/helpers.rs +++ b/oca-file/src/ocafile/instructions/helpers.rs @@ -11,24 +11,46 @@ pub fn extract_attribute_key_pairs(attr_pair: Pair) -> Option<(String, NestedVal let mut key = String::new(); let mut value = NestedValue::Value(String::new()); - debug!("Extract the attribute: {:?}", attr_pair); + debug!("Extracting the attribute from: {:?}", attr_pair); for item in attr_pair.into_inner() { match item.as_rule() { Rule::attr_key => { + debug!("Extracting attribute key"); key = item.as_str().to_string(); - } - Rule::attr_type => match AttributeType::from_str(item.as_span().as_str()) { - Ok(attr_type) => { - debug!("Attribute type: {:?}", attr_type); - if let Ok(serde_json::Value::String(v)) = serde_json::to_value(attr_type) { - value = NestedValue::Value(v); - } else { - panic!("Invalid attribute type {:?}", attr_type); + }, + Rule::_attr_type => { + debug!("Attribute type to parse: {:?}", item); + if let Some(attr_type) = item.clone().into_inner().next() { + match attr_type.as_rule() { + Rule::reference => { + debug!("Matching referance {:?}", item); + value = NestedValue::Reference(oca_ast::ast::RefValue::Name(attr_type.as_str().to_string())) + }, + Rule::attr_type => { + debug!("checking: {}", item); + match AttributeType::from_str(item.as_span().as_str()) { + Ok(attr_type) => { + debug!("Attribute type: {:?}", attr_type); + if let Ok(serde_json::Value::String(v)) = serde_json::to_value(attr_type) { + value = NestedValue::Value(v); + } else { + panic!("Invalid attribute type {:?}", attr_type); + } + } + Err(e) => { + panic!("Invalid attribute type {:?}", e); + } + } + } + Rule::said => { + debug!("Found said: {:?}", item ); + value = NestedValue::Reference(oca_ast::ast::RefValue::Said(attr_type.as_str().to_string())) + } + _ => { + panic!("Matching referance didn't worked"); + } } } - Err(e) => { - panic!("Invalid attribute type {:?}", e); - } }, Rule::key_value => { if let Some(nested_item) = item.clone().into_inner().next() { diff --git a/oca/src/facade/fetch.rs b/oca/src/facade/fetch.rs index a5adb76..222cee3 100644 --- a/oca/src/facade/fetch.rs +++ b/oca/src/facade/fetch.rs @@ -321,6 +321,19 @@ impl Facade { if let oca_ast::ast::NestedValue::Value(value) = value { line.push_str(format!("{}={} ", key, value).as_str()); } + if let oca_ast::ast::NestedValue::Reference(value) = value { + match value { + oca_ast::ast::RefValue::Name(refn) => { + line.push_str(format!("{}=refn:{} ", key, refn).as_str()); + } + oca_ast::ast::RefValue::Said(refs) => { + line.push_str(format!("{}=refs:{} ", key, refs).as_str()); + } + + } + } + // TODO handle Array and object? + }); } }; From 2cfdaee0097a223bc4899e143298c04c6fe3b90a Mon Sep 17 00:00:00 2001 From: Robert Mitwicki Date: Tue, 7 Nov 2023 21:51:10 +0100 Subject: [PATCH 2/2] chore(oca-file): improve debuging outputs --- oca-file/src/ocafile/instructions/add.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/oca-file/src/ocafile/instructions/add.rs b/oca-file/src/ocafile/instructions/add.rs index b4d2d76..ebc0634 100644 --- a/oca-file/src/ocafile/instructions/add.rs +++ b/oca-file/src/ocafile/instructions/add.rs @@ -24,18 +24,18 @@ impl AddInstruction { for attr_pairs in object.into_inner() { match attr_pairs.as_rule() { Rule::attr_pairs => { - info!("attribute: {:?}", attr_pairs); + debug!("Attribute pairs: {:?}", attr_pairs); for attr in attr_pairs.into_inner() { - debug!("Parsing attribute {:?}", attr); + debug!("Parsing attribute pair {:?}", attr); if let Some((key, value)) = helpers::extract_attribute_key_pairs(attr) { - debug!("Parsed attribute: {:?} = {:?}", key, value); + info!("Parsed attribute: {:?} = {:?}", key, value); // TODO find out how to parse nested objects attributes.insert(key, value); } else { - debug!("Skipping attribute"); + debug!("Attribute skipped"); } } }