bluejay_parser/ast/
directive.rs1use crate::ast::{Arguments, FromTokens, IsMatch, ParseError, Tokens, TryFromTokens};
2use crate::lexical_token::{Name, PunctuatorType};
3use crate::{HasSpan, Span};
4
5#[derive(Debug)]
6pub struct Directive<'a, const CONST: bool> {
7 name: Name<'a>,
8 arguments: Option<Arguments<'a, CONST>>,
9 span: Span,
10}
11
12pub type ConstDirective<'a> = Directive<'a, true>;
13pub type VariableDirective<'a> = Directive<'a, false>;
14
15impl<'a, const CONST: bool> IsMatch<'a> for Directive<'a, CONST> {
16 #[inline]
17 fn is_match(tokens: &mut impl Tokens<'a>) -> bool {
18 tokens.peek_punctuator_matches(0, PunctuatorType::At)
19 }
20}
21
22impl<'a, const CONST: bool> FromTokens<'a> for Directive<'a, CONST> {
23 #[inline]
24 fn from_tokens(tokens: &mut impl Tokens<'a>) -> Result<Self, ParseError> {
25 let at_span = tokens.expect_punctuator(PunctuatorType::At)?;
26 let name = tokens.expect_name()?;
27 let arguments = Arguments::try_from_tokens(tokens).transpose()?;
28 let span = match &arguments {
29 Some(arguments) => at_span.merge(arguments.span()),
30 None => at_span.merge(name.span()),
31 };
32
33 Ok(Self {
34 name,
35 arguments,
36 span,
37 })
38 }
39}
40
41impl<'a, const CONST: bool> bluejay_core::Directive<CONST> for Directive<'a, CONST> {
42 type Arguments = Arguments<'a, CONST>;
43
44 fn name(&self) -> &str {
45 self.name.as_ref()
46 }
47
48 fn arguments(&self) -> Option<&Self::Arguments> {
49 self.arguments.as_ref()
50 }
51}
52
53impl<'a, const CONST: bool> HasSpan for Directive<'a, CONST> {
54 fn span(&self) -> &Span {
55 &self.span
56 }
57}
58
59impl<'a, const CONST: bool> Directive<'a, CONST> {
60 pub fn name(&self) -> &Name<'a> {
61 &self.name
62 }
63}