From 9dc142a386fbaf094839ab8f0f28b8785ed3079f Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Fri, 27 Sep 2024 00:24:26 -0700 Subject: [PATCH] AttributeSet --- src/alias.rs | 2 +- src/attribute.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 +- src/parser.rs | 6 ++++-- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/alias.rs b/src/alias.rs index 286cefd064..2f7072afaf 100644 --- a/src/alias.rs +++ b/src/alias.rs @@ -3,7 +3,7 @@ use super::*; /// An alias, e.g. `name := target` #[derive(Debug, PartialEq, Clone, Serialize)] pub(crate) struct Alias<'src, T = Rc>> { - pub(crate) attributes: BTreeSet>, + pub(crate) attributes: AttributeSet<'src>, pub(crate) name: Name<'src>, #[serde( bound(serialize = "T: Keyed<'src>"), diff --git a/src/attribute.rs b/src/attribute.rs index c34d3f6644..53d8fd2f3a 100644 --- a/src/attribute.rs +++ b/src/attribute.rs @@ -135,6 +135,53 @@ impl<'src> Display for Attribute<'src> { } } +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct AttributeSet<'src> { + inner: BTreeSet>, +} + +impl<'src> Serialize for AttributeSet<'src> { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.inner.serialize(serializer) + } +} + +impl<'src> AttributeSet<'src> { + pub(crate) fn empty() -> Self { + Self { + inner: BTreeSet::new(), + } + } + + pub(crate) fn from_set(input: BTreeSet>) -> Self { + Self { inner: input } + } + + pub(crate) fn contains(&self, attribute: &Attribute) -> bool { + self.inner.contains(attribute) + } + + //pub(crate) fn ensure_validity(&self, valid_attributes: + + /// Get the names of all Group attributes defined in this attribute set + pub(crate) fn groups(&self) -> Vec<&StringLiteral<'src>> { + self + .inner + .iter() + .filter_map(|attr| { + if let Attribute::Group(name) = attr { + Some(name) + } else { + None + } + }) + .collect() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/lib.rs b/src/lib.rs index 75e3332be4..fcfd7d2cc7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ pub(crate) use { crate::{ alias::Alias, analyzer::Analyzer, argument_parser::ArgumentParser, assignment::Assignment, - assignment_resolver::AssignmentResolver, ast::Ast, attribute::Attribute, binding::Binding, + assignment_resolver::AssignmentResolver, ast::Ast, attribute::{Attribute, AttributeSet}, binding::Binding, color::Color, color_display::ColorDisplay, command_color::CommandColor, command_ext::CommandExt, compilation::Compilation, compile_error::CompileError, compile_error_kind::CompileErrorKind, compiler::Compiler, condition::Condition, diff --git a/src/parser.rs b/src/parser.rs index da2ff76f3f..c767593d21 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -339,7 +339,9 @@ impl<'run, 'src> Parser<'run, 'src> { } else if self.next_is(Identifier) { match Keyword::from_lexeme(next.lexeme()) { Some(Keyword::Alias) if self.next_are(&[Identifier, Identifier, ColonEquals]) => { - items.push(Item::Alias(self.parse_alias(take_attributes())?)); + items.push(Item::Alias( + self.parse_alias(AttributeSet::from_set(take_attributes()))?, + )); } Some(Keyword::Export) if self.next_are(&[Identifier, Identifier, ColonEquals]) => { self.presume_keyword(Keyword::Export)?; @@ -462,7 +464,7 @@ impl<'run, 'src> Parser<'run, 'src> { /// Parse an alias, e.g `alias name := target` fn parse_alias( &mut self, - attributes: BTreeSet>, + attributes: AttributeSet<'src>, ) -> CompileResult<'src, Alias<'src, Name<'src>>> { self.presume_keyword(Keyword::Alias)?; let name = self.parse_name()?;