bluejay_parser/ast/definition/
enum_value_definition.rs

1use crate::lexical_token::{Name, StringValue};
2use crate::{
3    ast::{
4        definition::{Context, Directives},
5        ConstDirectives, FromTokens, ParseError, Tokens, TryFromTokens,
6    },
7    HasSpan,
8};
9use bluejay_core::definition::{EnumValueDefinition as CoreEnumValueDefinition, HasDirectives};
10
11#[derive(Debug)]
12pub struct EnumValueDefinition<'a, C: Context> {
13    description: Option<StringValue<'a>>,
14    name: Name<'a>,
15    directives: Option<Directives<'a, C>>,
16}
17
18impl<'a, C: Context> EnumValueDefinition<'a, C> {
19    pub fn name_token(&self) -> &Name<'a> {
20        &self.name
21    }
22}
23
24impl<'a, C: Context> CoreEnumValueDefinition for EnumValueDefinition<'a, C> {
25    fn description(&self) -> Option<&str> {
26        self.description.as_ref().map(AsRef::as_ref)
27    }
28
29    fn name(&self) -> &str {
30        self.name.as_ref()
31    }
32}
33
34impl<'a, C: Context> FromTokens<'a> for EnumValueDefinition<'a, C> {
35    fn from_tokens(tokens: &mut impl Tokens<'a>) -> Result<Self, ParseError> {
36        let description = tokens.next_if_string_value();
37        let name = tokens.expect_name()?;
38        if matches!(name.as_str(), "null" | "true" | "false") {
39            return Err(ParseError::InvalidEnumValue {
40                span: name.span().clone(),
41                value: name.as_str().to_string(),
42            });
43        }
44
45        let directives = ConstDirectives::try_from_tokens(tokens).transpose()?;
46        Ok(Self {
47            description,
48            name,
49            directives: directives.map(Directives::from),
50        })
51    }
52}
53
54impl<'a, C: Context> HasDirectives for EnumValueDefinition<'a, C> {
55    type Directives = Directives<'a, C>;
56
57    fn directives(&self) -> Option<&Self::Directives> {
58        self.directives.as_ref()
59    }
60}