From 11c8820395bc2b9b1e428ea65cc11c6a5c513d91 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Wed, 13 Mar 2024 01:28:16 +0700 Subject: [PATCH] feat: enum value settings --- src/analyzer/indexer.rs | 4 +- src/ast/enums.rs | 11 +- src/ast/table.rs | 2 +- src/parser/mod.rs | 11 +- tests/out/comment.in.ron | 97 ++++++++------- tests/out/enum_tables.in.ron | 203 +++++++++++++++++--------------- tests/out/general_schema.in.ron | 18 +-- tests/out/project.in.ron | 18 +-- tests/out/sample_1.ron | 65 +++++----- 9 files changed, 229 insertions(+), 200 deletions(-) diff --git a/src/analyzer/indexer.rs b/src/analyzer/indexer.rs index 5667297..24a18d9 100644 --- a/src/analyzer/indexer.rs +++ b/src/analyzer/indexer.rs @@ -114,7 +114,9 @@ impl Indexer { let mut value_sets = BTreeSet::new(); for value in r#enum.values.iter() { - check_attr_duplicate_keys(&value.attributes, input)?; + if let Some(settings) = &value.settings { + check_attr_duplicate_keys(&settings.attributes, input)?; + } if !value_sets.insert(value.value.to_string.clone()) { throw_err(Err::DuplicateEnumValue, &value.span_range, input)?; diff --git a/src/ast/enums.rs b/src/ast/enums.rs index 31a2fe6..2130264 100644 --- a/src/ast/enums.rs +++ b/src/ast/enums.rs @@ -15,8 +15,17 @@ pub struct EnumBlock { pub struct EnumValue { /// The range of the span in the source text. pub span_range: SpanRange, - pub attributes: Vec, pub value: Ident, + pub settings: Option, +} + +#[derive(Debug, Clone, Default)] +pub struct EnumValueSettings { + /// The range of the span in the source text. + pub span_range: SpanRange, + /// A vector of key and optional value pairs representing attributes of the enum value. + pub attributes: Vec, + /// A note associated with the enum value. pub note: Option, } diff --git a/src/ast/table.rs b/src/ast/table.rs index dbac33d..35862da 100644 --- a/src/ast/table.rs +++ b/src/ast/table.rs @@ -169,7 +169,7 @@ impl FromStr for ColumnTypeName { pub struct ColumnSettings { /// The range of the span in the source text. pub span_range: SpanRange, - /// A vector of key-value pairs representing properties of the column. + /// A vector of key and optional value pairs representing attributes of the column. pub attributes: Vec, /// A boolean indicating if the column is a primary key. pub is_pk: bool, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 47402b3..391a4d4 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -375,21 +375,28 @@ fn parse_enum_value(pair: Pair) -> ParserResult { match p1.as_rule() { Rule::ident => acc.value = parse_ident(p1)?, Rule::enum_settings => { + let mut settings = EnumValueSettings { + span_range: s2r(p1.as_span()), + ..Default::default() + }; + for p2 in p1.into_inner() { match p2.as_rule() { Rule::attribute => { let attr = parse_attribute(p2)?; match attr.key.to_string.as_str() { - "note" => acc.note = attr.value.clone().map(|v| v.value.to_string()), + "note" => settings.note = attr.value.clone().map(|v| v.value.to_string()), _ => (), } - acc.attributes.push(attr); + settings.attributes.push(attr); } _ => throw_rules(&[Rule::attribute], p2)?, } } + + acc.settings = Some(settings); } _ => throw_rules(&[Rule::ident, Rule::enum_settings], p1)?, } diff --git a/tests/out/comment.in.ron b/tests/out/comment.in.ron index 4f326ad..bb6c5bf 100644 --- a/tests/out/comment.in.ron +++ b/tests/out/comment.in.ron @@ -290,72 +290,81 @@ SchemaBlock { values: [ EnumValue { span_range: 338..353, - attributes: [], value: Ident { span_range: 338..350, raw: "out_of_stock", to_string: "out_of_stock", }, - note: None, + settings: None, }, EnumValue { span_range: 353..380, - attributes: [ - Attribute { - span_range: 363..379, - key: Ident { - span_range: 363..367, - raw: "note", - to_string: "note", - }, - value: Some( - Literal { - span_range: 369..379, - raw: "'In stock'", - value: String( - "In stock", - ), - }, - ), - }, - ], value: Ident { span_range: 353..361, raw: "in_stock", to_string: "in_stock", }, - note: Some( - "In stock", - ), - }, - EnumValue { - span_range: 383..417, - attributes: [ - Attribute { - span_range: 396..416, - key: Ident { - span_range: 396..400, - raw: "note", - to_string: "note", - }, - value: Some( - Literal { - span_range: 402..416, - raw: "'less than 20'", - value: String( - "less than 20", + settings: Some( + EnumValueSettings { + span_range: 362..380, + attributes: [ + Attribute { + span_range: 363..379, + key: Ident { + span_range: 363..367, + raw: "note", + to_string: "note", + }, + value: Some( + Literal { + span_range: 369..379, + raw: "'In stock'", + value: String( + "In stock", + ), + }, ), }, + ], + note: Some( + "In stock", ), }, - ], + ), + }, + EnumValue { + span_range: 383..417, value: Ident { span_range: 383..394, raw: "running_low", to_string: "running_low", }, - note: Some( - "less than 20", + settings: Some( + EnumValueSettings { + span_range: 395..417, + attributes: [ + Attribute { + span_range: 396..416, + key: Ident { + span_range: 396..400, + raw: "note", + to_string: "note", + }, + value: Some( + Literal { + span_range: 402..416, + raw: "'less than 20'", + value: String( + "less than 20", + ), + }, + ), + }, + ], + note: Some( + "less than 20", + ), + }, ), }, ], diff --git a/tests/out/enum_tables.in.ron b/tests/out/enum_tables.in.ron index c69340e..99e36b3 100644 --- a/tests/out/enum_tables.in.ron +++ b/tests/out/enum_tables.in.ron @@ -17,112 +17,125 @@ SchemaBlock { values: [ EnumValue { span_range: 20..61, - attributes: [ - Attribute { - span_range: 29..60, - key: Ident { - span_range: 29..33, - raw: "note", - to_string: "note", - }, - value: Some( - Literal { - span_range: 35..60, - raw: "'Job created and pending'", - value: String( - "Job created and pending", - ), - }, - ), - }, - ], value: Ident { span_range: 20..27, raw: "created", to_string: "created", }, - note: Some( - "Job created and pending", - ), - }, - EnumValue { - span_range: 64..114, - attributes: [ - Attribute { - span_range: 73..113, - key: Ident { - span_range: 73..77, - raw: "note", - to_string: "note", - }, - value: Some( - Literal { - span_range: 79..113, - raw: "'Waiting for warehouse to process'", - value: String( - "Waiting for warehouse to process", + settings: Some( + EnumValueSettings { + span_range: 28..61, + attributes: [ + Attribute { + span_range: 29..60, + key: Ident { + span_range: 29..33, + raw: "note", + to_string: "note", + }, + value: Some( + Literal { + span_range: 35..60, + raw: "'Job created and pending'", + value: String( + "Job created and pending", + ), + }, ), }, + ], + note: Some( + "Job created and pending", ), }, - ], + ), + }, + EnumValue { + span_range: 64..114, value: Ident { span_range: 64..71, raw: "running", to_string: "running", }, - note: Some( - "Waiting for warehouse to process", + settings: Some( + EnumValueSettings { + span_range: 72..114, + attributes: [ + Attribute { + span_range: 73..113, + key: Ident { + span_range: 73..77, + raw: "note", + to_string: "note", + }, + value: Some( + Literal { + span_range: 79..113, + raw: "'Waiting for warehouse to process'", + value: String( + "Waiting for warehouse to process", + ), + }, + ), + }, + ], + note: Some( + "Waiting for warehouse to process", + ), + }, ), }, EnumValue { span_range: 117..124, - attributes: [], value: Ident { span_range: 117..121, raw: "done", to_string: "done", }, - note: None, + settings: None, }, EnumValue { span_range: 124..132, - attributes: [], value: Ident { span_range: 124..130, raw: "failed", to_string: "failed", }, - note: None, + settings: None, }, EnumValue { span_range: 132..196, - attributes: [ - Attribute { - span_range: 155..195, - key: Ident { - span_range: 155..159, - raw: "note", - to_string: "note", - }, - value: Some( - Literal { - span_range: 161..195, - raw: "'Enum label that has white spaces'", - value: String( - "Enum label that has white spaces", - ), - }, - ), - }, - ], value: Ident { span_range: 132..153, raw: "\"wait for validation\"", to_string: "wait for validation", }, - note: Some( - "Enum label that has white spaces", + settings: Some( + EnumValueSettings { + span_range: 154..196, + attributes: [ + Attribute { + span_range: 155..195, + key: Ident { + span_range: 155..159, + raw: "note", + to_string: "note", + }, + value: Some( + Literal { + span_range: 161..195, + raw: "'Enum label that has white spaces'", + value: String( + "Enum label that has white spaces", + ), + }, + ), + }, + ], + note: Some( + "Enum label that has white spaces", + ), + }, ), }, ], @@ -253,63 +266,65 @@ SchemaBlock { values: [ EnumValue { span_range: 310..341, - attributes: [ - Attribute { - span_range: 319..340, - key: Ident { - span_range: 319..323, - raw: "note", - to_string: "note", - }, - value: Some( - Literal { - span_range: 325..340, - raw: "'Order created'", - value: String( - "Order created", - ), - }, - ), - }, - ], value: Ident { span_range: 310..317, raw: "created", to_string: "created", }, - note: Some( - "Order created", + settings: Some( + EnumValueSettings { + span_range: 318..341, + attributes: [ + Attribute { + span_range: 319..340, + key: Ident { + span_range: 319..323, + raw: "note", + to_string: "note", + }, + value: Some( + Literal { + span_range: 325..340, + raw: "'Order created'", + value: String( + "Order created", + ), + }, + ), + }, + ], + note: Some( + "Order created", + ), + }, ), }, EnumValue { span_range: 344..354, - attributes: [], value: Ident { span_range: 344..351, raw: "pending", to_string: "pending", }, - note: None, + settings: None, }, EnumValue { span_range: 354..367, - attributes: [], value: Ident { span_range: 354..364, raw: "processing", to_string: "processing", }, - note: None, + settings: None, }, EnumValue { span_range: 367..377, - attributes: [], value: Ident { span_range: 367..376, raw: "completed", to_string: "completed", }, - note: None, + settings: None, }, ], }, diff --git a/tests/out/general_schema.in.ron b/tests/out/general_schema.in.ron index 1266e93..2191dc9 100644 --- a/tests/out/general_schema.in.ron +++ b/tests/out/general_schema.in.ron @@ -17,43 +17,39 @@ SchemaBlock { values: [ EnumValue { span_range: 25..37, - attributes: [], value: Ident { span_range: 25..34, raw: "\"created\"", to_string: "created", }, - note: None, + settings: None, }, EnumValue { span_range: 37..49, - attributes: [], value: Ident { span_range: 37..46, raw: "\"running\"", to_string: "running", }, - note: None, + settings: None, }, EnumValue { span_range: 49..58, - attributes: [], value: Ident { span_range: 49..55, raw: "\"done\"", to_string: "done", }, - note: None, + settings: None, }, EnumValue { span_range: 58..68, - attributes: [], value: Ident { span_range: 58..67, raw: "\"failure\"", to_string: "failure", }, - note: None, + settings: None, }, ], }, @@ -73,23 +69,21 @@ SchemaBlock { values: [ EnumValue { span_range: 97..114, - attributes: [], value: Ident { span_range: 97..111, raw: "\"Out of Stock\"", to_string: "Out of Stock", }, - note: None, + settings: None, }, EnumValue { span_range: 114..125, - attributes: [], value: Ident { span_range: 114..124, raw: "\"In Stock\"", to_string: "In Stock", }, - note: None, + settings: None, }, ], }, diff --git a/tests/out/project.in.ron b/tests/out/project.in.ron index 49da2d9..569298d 100644 --- a/tests/out/project.in.ron +++ b/tests/out/project.in.ron @@ -57,43 +57,39 @@ SchemaBlock { values: [ EnumValue { span_range: 175..187, - attributes: [], value: Ident { span_range: 175..184, raw: "\"created\"", to_string: "created", }, - note: None, + settings: None, }, EnumValue { span_range: 187..199, - attributes: [], value: Ident { span_range: 187..196, raw: "\"running\"", to_string: "running", }, - note: None, + settings: None, }, EnumValue { span_range: 199..208, - attributes: [], value: Ident { span_range: 199..205, raw: "\"done\"", to_string: "done", }, - note: None, + settings: None, }, EnumValue { span_range: 208..218, - attributes: [], value: Ident { span_range: 208..217, raw: "\"failure\"", to_string: "failure", }, - note: None, + settings: None, }, ], }, @@ -113,23 +109,21 @@ SchemaBlock { values: [ EnumValue { span_range: 247..264, - attributes: [], value: Ident { span_range: 247..261, raw: "\"Out of Stock\"", to_string: "Out of Stock", }, - note: None, + settings: None, }, EnumValue { span_range: 264..275, - attributes: [], value: Ident { span_range: 264..274, raw: "\"In Stock\"", to_string: "In Stock", }, - note: None, + settings: None, }, ], }, diff --git a/tests/out/sample_1.ron b/tests/out/sample_1.ron index 6b26686..4040aea 100644 --- a/tests/out/sample_1.ron +++ b/tests/out/sample_1.ron @@ -704,52 +704,55 @@ SchemaBlock { values: [ EnumValue { span_range: 1036..1044, - attributes: [], value: Ident { span_range: 1036..1041, raw: "draft", to_string: "draft", }, - note: None, + settings: None, }, EnumValue { span_range: 1044..1056, - attributes: [], value: Ident { span_range: 1044..1053, raw: "published", to_string: "published", }, - note: None, + settings: None, }, EnumValue { span_range: 1056..1094, - attributes: [ - Attribute { - span_range: 1065..1093, - key: Ident { - span_range: 1065..1069, - raw: "note", - to_string: "note", - }, - value: Some( - Literal { - span_range: 1071..1093, - raw: "'visible via URL only'", - value: String( - "visible via URL only", - ), - }, - ), - }, - ], value: Ident { span_range: 1056..1063, raw: "private", to_string: "private", }, - note: Some( - "visible via URL only", + settings: Some( + EnumValueSettings { + span_range: 1064..1094, + attributes: [ + Attribute { + span_range: 1065..1093, + key: Ident { + span_range: 1065..1069, + raw: "note", + to_string: "note", + }, + value: Some( + Literal { + span_range: 1071..1093, + raw: "'visible via URL only'", + value: String( + "visible via URL only", + ), + }, + ), + }, + ], + note: Some( + "visible via URL only", + ), + }, ), }, ], @@ -770,43 +773,39 @@ SchemaBlock { values: [ EnumValue { span_range: 1113..1120, - attributes: [], value: Ident { span_range: 1113..1117, raw: "\"A+\"", to_string: "A+", }, - note: None, + settings: None, }, EnumValue { span_range: 1120..1126, - attributes: [], value: Ident { span_range: 1120..1123, raw: "\"A\"", to_string: "A", }, - note: None, + settings: None, }, EnumValue { span_range: 1126..1133, - attributes: [], value: Ident { span_range: 1126..1130, raw: "\"A-\"", to_string: "A-", }, - note: None, + settings: None, }, EnumValue { span_range: 1133..1147, - attributes: [], value: Ident { span_range: 1133..1146, raw: "\"Not Yet Set\"", to_string: "Not Yet Set", }, - note: None, + settings: None, }, ], },