11use std:: { borrow:: Cow , fmt, hash:: Hash , slice, vec} ;
22
33use arcstr:: ArcStr ;
4-
54use indexmap:: IndexMap ;
5+ use smallvec:: { SmallVec , smallvec} ;
66
77use crate :: {
88 executor:: Variables ,
@@ -22,7 +22,7 @@ pub(crate) type BorrowedType<'a> = Type<&'a str, &'a [TypeModifier]>;
2222///
2323/// Carries no semantic information and might refer to types that don't exist.
2424#[ derive( Clone , Debug ) ]
25- pub struct Type < N = ArcStr , M = Box < [ TypeModifier ] > > {
25+ pub struct Type < N = ArcStr , M = SmallVec < [ TypeModifier ; 2 ] > > {
2626 name : N ,
2727 modifiers : M ,
2828}
@@ -48,27 +48,56 @@ where
4848 M : AsRef < [ TypeModifier ] > ,
4949{
5050 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
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( ) ) ,
51+ match self . modifier ( ) {
52+ Some ( TypeModifier :: NonNull ) => write ! ( f, "{}!" , self . inner( ) ) ,
53+ Some ( TypeModifier :: List ( ..) ) => write ! ( f, "[{}]" , self . inner( ) ) ,
5554 None => write ! ( f, "{}" , self . name. as_ref( ) ) ,
5655 }
5756 }
5857}
5958
59+ impl < ' a , N , M > From < & ' a Type < N , M > > for BorrowedType < ' a >
60+ where
61+ N : AsRef < str > ,
62+ M : AsRef < [ TypeModifier ] > ,
63+ {
64+ fn from ( value : & ' a Type < N , M > ) -> Self {
65+ Self {
66+ name : value. name . as_ref ( ) ,
67+ modifiers : value. modifiers . as_ref ( ) ,
68+ }
69+ }
70+ }
71+
72+ impl < ' a > BorrowedType < ' a > {
73+ pub ( crate ) fn inner_borrowed ( & self ) -> BorrowedType < ' a > {
74+ let modifiers = self . modifiers . as_ref ( ) ;
75+ match modifiers. len ( ) {
76+ 0 => unreachable ! ( ) ,
77+ n => Type {
78+ name : self . name ,
79+ modifiers : & modifiers[ ..n - 1 ] ,
80+ } ,
81+ }
82+ }
83+
84+ pub ( crate ) fn borrowed_name ( & self ) -> & ' a str {
85+ self . name
86+ }
87+ }
88+
6089impl < N : AsRef < str > , M > Type < N , M > {
61- pub ( crate ) fn inner ( & self ) -> Option < BorrowedType < ' _ > >
90+ pub ( crate ) fn inner ( & self ) -> BorrowedType < ' _ >
6291 where
6392 M : AsRef < [ TypeModifier ] > ,
6493 {
6594 let modifiers = self . modifiers . as_ref ( ) ;
6695 match modifiers. len ( ) {
67- 0 => None ,
68- n => Some ( Type {
96+ 0 => unreachable ! ( ) ,
97+ n => Type {
6998 name : self . name . as_ref ( ) ,
7099 modifiers : & modifiers[ ..n - 1 ] ,
71- } ) ,
100+ } ,
72101 }
73102 }
74103
@@ -100,6 +129,15 @@ impl<N: AsRef<str>, M> Type<N, M> {
100129 self . name . as_ref ( )
101130 }
102131
132+ /// Returns the [`TypeModifier`] of this [`Type`], if any.
133+ #[ must_use]
134+ pub fn modifier ( & self ) -> Option < & TypeModifier >
135+ where
136+ M : AsRef < [ TypeModifier ] > ,
137+ {
138+ self . modifiers . as_ref ( ) . last ( )
139+ }
140+
103141 /// Indicates whether this [`Type`] can only represent non-`null` values.
104142 #[ must_use]
105143 pub fn is_non_null ( & self ) -> bool
@@ -111,6 +149,50 @@ impl<N: AsRef<str>, M> Type<N, M> {
111149 Some ( TypeModifier :: List ( ..) ) | None => false ,
112150 }
113151 }
152+
153+ #[ must_use]
154+ pub fn is_list ( & self ) -> bool
155+ where
156+ M : AsRef < [ TypeModifier ] > ,
157+ {
158+ match self . modifiers . as_ref ( ) . last ( ) {
159+ Some ( TypeModifier :: NonNull ) => self . inner ( ) . is_non_null ( ) ,
160+ Some ( TypeModifier :: List ( ..) ) => true ,
161+ None => false ,
162+ }
163+ }
164+ }
165+
166+ impl < N : AsRef < str > > Type < N > {
167+ /// Wraps this [`Type`] into the provided [`TypeModifier`].
168+ fn wrap ( mut self , modifier : TypeModifier ) -> Self {
169+ self . modifiers . push ( modifier) ;
170+ self
171+ }
172+
173+ pub fn wrap_list ( self , size_hint : Option < usize > ) -> Self {
174+ // TODO: assert?
175+ self . wrap ( TypeModifier :: List ( size_hint) )
176+ }
177+
178+ pub fn wrap_non_null ( self ) -> Self {
179+ // TODO: assert?
180+ self . wrap ( TypeModifier :: NonNull )
181+ }
182+
183+ pub fn nullable ( mut self ) -> Self {
184+ if self . is_non_null ( ) {
185+ _ = self . modifiers . pop ( ) ;
186+ }
187+ self
188+ }
189+
190+ pub fn named ( name : impl Into < N > ) -> Self {
191+ Self {
192+ name : name. into ( ) ,
193+ modifiers : smallvec ! [ ] ,
194+ }
195+ }
114196}
115197
116198/// A JSON-like value that can be passed into the query execution, either
0 commit comments