@@ -10,64 +10,85 @@ use crate::{
1010 value:: { DefaultScalarValue , ScalarValue } ,
1111} ;
1212
13+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
14+ pub enum TypeModifier {
15+ NonNull ,
16+ List ( Option < usize > ) ,
17+ }
18+
19+ pub ( crate ) type BorrowedType < ' a > = Type < & ' a str , & ' a [ TypeModifier ] > ;
20+
1321/// Type literal in a syntax tree.
1422///
15- /// This enum carries no semantic information and might refer to types that do not exist.
23+ /// Carries no semantic information and might refer to types that don't exist.
1624#[ derive( Clone , Debug ) ]
17- pub enum Type < N = ArcStr > {
18- /// `null`able named type, e.g. `String`.
19- Named ( N ) ,
20-
21- /// `null`able list type, e.g. `[String]`.
22- ///
23- /// The list itself is `null`able, the containing [`Type`] might be non-`null`.
24- List ( Box < Type < N > > , Option < usize > ) ,
25-
26- /// Non-`null` named type, e.g. `String!`.
27- NonNullNamed ( N ) ,
28-
29- /// Non-`null` list type, e.g. `[String]!`.
30- ///
31- /// The list itself is non-`null`, the containing [`Type`] might be `null`able.
32- NonNullList ( Box < Type < N > > , Option < usize > ) ,
25+ pub struct Type < N = ArcStr , M = Box < [ TypeModifier ] > > {
26+ name : N ,
27+ modifiers : M ,
3328}
3429
35- impl < N > Eq for Type < N > where Self : PartialEq { }
30+ impl < N , M > Eq for Type < N , M > where Self : PartialEq { }
3631
37- impl < N1 : AsRef < str > , N2 : AsRef < str > > PartialEq < Type < N2 > > for Type < N1 > {
38- fn eq ( & self , other : & Type < N2 > ) -> bool {
39- match ( self , other) {
40- ( Self :: Named ( n1) , Type :: Named ( n2) ) => n1. as_ref ( ) == n2. as_ref ( ) ,
41- ( Self :: List ( lhs, s1) , Type :: List ( rhs, s2) ) => s1 == s2 && lhs. as_ref ( ) == rhs. as_ref ( ) ,
42- ( Self :: NonNullNamed ( n1) , Type :: NonNullNamed ( n2) ) => n1. as_ref ( ) == n2. as_ref ( ) ,
43- ( Self :: NonNullList ( lhs, s1) , Type :: NonNullList ( rhs, s2) ) => {
44- s1 == s2 && lhs. as_ref ( ) == rhs. as_ref ( )
45- }
46- _ => false ,
47- }
32+ impl < N1 , N2 , M1 , M2 > PartialEq < Type < N2 , M2 > > for Type < N1 , M1 >
33+ where
34+ N1 : AsRef < str > ,
35+ N2 : AsRef < str > ,
36+ M1 : AsRef < [ TypeModifier ] > ,
37+ M2 : AsRef < [ TypeModifier ] > ,
38+ {
39+ fn eq ( & self , other : & Type < N2 , M2 > ) -> bool {
40+ self . name . as_ref ( ) == other. name . as_ref ( )
41+ && self . modifiers . as_ref ( ) == other. modifiers . as_ref ( )
4842 }
4943}
5044
51- impl < N : fmt:: Display > fmt:: Display for Type < N > {
45+ impl < N , M > fmt:: Display for Type < N , M >
46+ where
47+ N : AsRef < str > ,
48+ M : AsRef < [ TypeModifier ] > ,
49+ {
5250 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
53- match self {
54- Self :: Named ( n ) => write ! ( f , "{n}" ) ,
55- Self :: NonNullNamed ( n ) => write ! ( f, "{n }!" ) ,
56- Self :: List ( t , _ ) => write ! ( f, "[{t }]" ) ,
57- Self :: NonNullList ( t , _ ) => write ! ( f, "[{t}]!" ) ,
51+ // PANIC: ` self.inner().unwrap()` never panics if there is at least on `TypeModifier`.
52+ match self . modifiers . as_ref ( ) . last ( ) {
53+ Some ( TypeModifier :: NonNull ) => write ! ( f, "{}!" , self . inner ( ) . unwrap ( ) ) ,
54+ Some ( TypeModifier :: List ( .. ) ) => write ! ( f, "[{}]" , self . inner ( ) . unwrap ( ) ) ,
55+ None => write ! ( f, "{}" , self . name . as_ref ( ) ) ,
5856 }
5957 }
6058}
6159
62- impl < N : AsRef < str > > Type < N > {
60+ impl < N : AsRef < str > , M > Type < N , M > {
61+ pub ( crate ) fn inner ( & self ) -> Option < BorrowedType < ' _ > >
62+ where
63+ M : AsRef < [ TypeModifier ] > ,
64+ {
65+ let modifiers = self . modifiers . as_ref ( ) ;
66+ match modifiers. len ( ) {
67+ 0 => None ,
68+ n => Some ( Type {
69+ name : self . name . as_ref ( ) ,
70+ modifiers : & modifiers[ ..n - 1 ] ,
71+ } ) ,
72+ }
73+ }
74+
6375 /// Returns the name of this named [`Type`].
6476 ///
6577 /// Only applies to named [`Type`]s. Lists will return [`None`].
6678 #[ must_use]
67- pub fn name ( & self ) -> Option < & str > {
68- match self {
69- Self :: Named ( n) | Self :: NonNullNamed ( n) => Some ( n. as_ref ( ) ) ,
70- Self :: List ( ..) | Self :: NonNullList ( ..) => None ,
79+ pub fn name ( & self ) -> Option < & str >
80+ where
81+ M : AsRef < [ TypeModifier ] > ,
82+ {
83+ if self
84+ . modifiers
85+ . as_ref ( )
86+ . iter ( )
87+ . any ( |m| matches ! ( m, TypeModifier :: List ( ..) ) )
88+ {
89+ None
90+ } else {
91+ Some ( self . name . as_ref ( ) )
7192 }
7293 }
7394
@@ -76,18 +97,18 @@ impl<N: AsRef<str>> Type<N> {
7697 /// All [`Type`] literals contain exactly one named type.
7798 #[ must_use]
7899 pub fn innermost_name ( & self ) -> & str {
79- match self {
80- Self :: Named ( n) | Self :: NonNullNamed ( n) => n. as_ref ( ) ,
81- Self :: List ( l, ..) | Self :: NonNullList ( l, ..) => l. innermost_name ( ) ,
82- }
100+ self . name . as_ref ( )
83101 }
84102
85103 /// Indicates whether this [`Type`] can only represent non-`null` values.
86104 #[ must_use]
87- pub fn is_non_null ( & self ) -> bool {
88- match self {
89- Self :: NonNullList ( ..) | Self :: NonNullNamed ( ..) => true ,
90- Self :: List ( ..) | Self :: Named ( ..) => false ,
105+ pub fn is_non_null ( & self ) -> bool
106+ where
107+ M : AsRef < [ TypeModifier ] > ,
108+ {
109+ match self . modifiers . as_ref ( ) . last ( ) {
110+ Some ( TypeModifier :: NonNull ) => true ,
111+ Some ( TypeModifier :: List ( ..) ) | None => false ,
91112 }
92113 }
93114}
0 commit comments