bluejay_parser/ast/definition/
custom_scalar_type_definition.rs

1use crate::ast::{
2    definition::{Context, Directives},
3    ConstDirectives, DepthLimiter, FromTokens, ParseError, Tokens, TryFromTokens,
4};
5use crate::lexical_token::{Name, StringValue};
6use crate::Span;
7use bluejay_core::definition::{HasDirectives, ScalarTypeDefinition as CoreScalarTypeDefinition};
8use bluejay_core::Value;
9use std::borrow::Cow;
10use std::marker::PhantomData;
11
12#[derive(Debug)]
13pub struct CustomScalarTypeDefinition<'a, C: Context> {
14    description: Option<StringValue<'a>>,
15    _scalar_identifier_span: Span,
16    name: Name<'a>,
17    directives: Option<Directives<'a, C>>,
18    context: PhantomData<C>,
19}
20
21impl<'a, C: Context> CustomScalarTypeDefinition<'a, C> {
22    pub(crate) fn name(&self) -> &Name<'a> {
23        &self.name
24    }
25}
26
27impl<C: Context> CoreScalarTypeDefinition for CustomScalarTypeDefinition<'_, C> {
28    fn description(&self) -> Option<&str> {
29        self.description.as_ref().map(AsRef::as_ref)
30    }
31
32    fn name(&self) -> &str {
33        self.name.as_ref()
34    }
35
36    fn coerce_input<const CONST: bool>(
37        &self,
38        value: &impl Value<CONST>,
39    ) -> Result<(), Cow<'static, str>> {
40        C::coerce_custom_scalar_input(self, value)
41    }
42}
43
44impl<C: Context> CustomScalarTypeDefinition<'_, C> {
45    pub(crate) const SCALAR_IDENTIFIER: &'static str = "scalar";
46}
47
48impl<'a, C: Context> FromTokens<'a> for CustomScalarTypeDefinition<'a, C> {
49    fn from_tokens(
50        tokens: &mut impl Tokens<'a>,
51        depth_limiter: DepthLimiter,
52    ) -> Result<Self, ParseError> {
53        let description = tokens.next_if_string_value();
54        let scalar_identifier_span = tokens.expect_name_value(Self::SCALAR_IDENTIFIER)?;
55        let name = tokens.expect_name()?;
56        let directives =
57            ConstDirectives::try_from_tokens(tokens, depth_limiter.bump()?).transpose()?;
58        Ok(Self {
59            description,
60            _scalar_identifier_span: scalar_identifier_span,
61            name,
62            directives: directives.map(Directives::from),
63            context: Default::default(),
64        })
65    }
66}
67
68impl<'a, C: Context> HasDirectives for CustomScalarTypeDefinition<'a, C> {
69    type Directives = Directives<'a, C>;
70
71    fn directives(&self) -> Option<&Self::Directives> {
72        self.directives.as_ref()
73    }
74}