summaryrefslogtreecommitdiffstats
path: root/crates/rebel-parse
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-05-05 20:35:30 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-05-05 21:42:11 +0200
commitb4c25932f538bbfe332f2ff406d510dbc9641339 (patch)
tree7625840a4ae379103582b56186972362503040aa /crates/rebel-parse
parent1f0894a45be2ba1bd2d17fef771cf41ecf46309d (diff)
downloadrebel-b4c25932f538bbfe332f2ff406d510dbc9641339.tar
rebel-b4c25932f538bbfe332f2ff406d510dbc9641339.zip
rebel-parse: make fetch bodies struct-like rather than block-like
Fetch statements can't have parameters, so we don't need a code block where a simple data structure would suffice.
Diffstat (limited to 'crates/rebel-parse')
-rw-r--r--crates/rebel-parse/src/ast/mod.rs21
-rw-r--r--crates/rebel-parse/src/grammar/recipe.rs4
2 files changed, 17 insertions, 8 deletions
diff --git a/crates/rebel-parse/src/ast/mod.rs b/crates/rebel-parse/src/ast/mod.rs
index 0598cbd..adeac2e 100644
--- a/crates/rebel-parse/src/ast/mod.rs
+++ b/crates/rebel-parse/src/ast/mod.rs
@@ -1,13 +1,13 @@
+use rustc_hash::FxHashSet;
+
pub mod expr;
pub mod pat;
pub mod typ;
-use expr::Expr;
-use pat::DestrPat;
+use expr::{Expr, StructField};
+use pat::{DestrPat, Pat};
use typ::Type;
-use self::pat::Pat;
-
pub type Recipe<'a> = Vec<RecipeStmt<'a>>;
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -15,7 +15,7 @@ pub enum RecipeStmt<'a> {
BlockStmt(BlockStmt<'a>),
Fetch {
name: Ident<'a>,
- block: Block<'a>,
+ entries: Vec<StructField<'a>>,
},
Task {
name: Ident<'a>,
@@ -28,7 +28,16 @@ impl<'a> RecipeStmt<'a> {
pub fn validate(&self) -> Result<(), ValidationError> {
match self {
RecipeStmt::BlockStmt(stmt) => stmt.validate(),
- RecipeStmt::Fetch { name: _, block } => block.validate(),
+ RecipeStmt::Fetch { name: _, entries } => {
+ let mut fields = FxHashSet::default();
+ for StructField { name, value } in entries {
+ if !fields.insert(name) {
+ return Err(ValidationError::DuplicateKey);
+ }
+ value.validate()?;
+ }
+ Ok(())
+ }
RecipeStmt::Task {
name: _,
params: _,
diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs
index 85a6d8d..96ef61d 100644
--- a/crates/rebel-parse/src/grammar/recipe.rs
+++ b/crates/rebel-parse/src/grammar/recipe.rs
@@ -19,8 +19,8 @@ peg::parser! {
= recipe:recipe_stmt()* { recipe }
pub rule recipe_stmt() -> ast::RecipeStmt<'a>
- = [Token::Keyword(Keyword::Fetch)] name:ident() p('{') block:block() p('}') {
- ast::RecipeStmt::Fetch { name, block }
+ = [Token::Keyword(Keyword::Fetch)] name:ident() p('{') entries:delimited(<struct_field()>, <p(',')>) p('}') {
+ ast::RecipeStmt::Fetch { name, entries }
}
/ [Token::Keyword(Keyword::Task)] name:ident() p('(') params:func_params() p(')')
p('{') block:block() p('}') {