@@ -45,14 +45,19 @@ pub struct Directive<'a, T: Text<'a>> {
4545/// This represents integer number 
4646/// 
4747/// But since there is no definition on limit of number in spec 
48- /// (only in implemetation ), we do a trick similar to the one 
48+ /// (only in implementation ), we do a trick similar to the one 
4949/// in `serde_json`: encapsulate value in new-type, allowing type 
5050/// to be extended later. 
5151#[ derive( Debug ,  Clone ,  PartialEq ) ]  
52- // we use i64 as a reference implementation: graphql-js thinks even 32bit  
53- // integers is enough. We might consider lift this limit later though 
52+ // we use i64 as a reference implementation by default.  
53+ # [ cfg ( not ( feature =  "as_i32" ) ) ] 
5454pub  struct  Number ( pub ( crate )  i64 ) ; 
5555
56+ #[ derive( Debug ,  Clone ,  PartialEq ) ]  
57+ // Use i32 when the as_i32 feature is enabled 
58+ #[ cfg( feature = "as_i32" ) ]  
59+ pub  struct  Number ( pub ( crate )  i32 ) ; 
60+ 
5661#[ derive( Debug ,  Clone ,  PartialEq ) ]  
5762pub  enum  Value < ' a ,  T :  Text < ' a > >  { 
5863    Variable ( T :: Value ) , 
@@ -96,13 +101,43 @@ pub enum Type<'a, T: Text<'a>> {
96101impl  Number  { 
97102    /// Returns a number as i64 if it fits the type 
98103pub  fn  as_i64 ( & self )  -> Option < i64 >  { 
99-         Some ( self . 0 ) 
104+         #[ cfg( not( feature = "as_i32" ) ) ]  
105+         { 
106+             Some ( self . 0 ) 
107+         } 
108+         #[ cfg( feature = "as_i32" ) ]  
109+         { 
110+             Some ( self . 0  as  i64 ) 
111+         } 
112+     } 
113+ 
114+     /// Returns a number as i32 if it fits the type 
115+ pub  fn  as_i32 ( & self )  -> Option < i32 >  { 
116+         #[ cfg( not( feature = "as_i32" ) ) ]  
117+         { 
118+             if  self . 0  >= i32:: MIN  as  i64  && self . 0  <= i32:: MAX  as  i64  { 
119+                 Some ( self . 0  as  i32 ) 
120+             }  else  { 
121+                 None 
122+             } 
123+         } 
124+         #[ cfg( feature = "as_i32" ) ]  
125+         { 
126+             Some ( self . 0 ) 
127+         } 
100128    } 
101129} 
102130
103131impl  From < i32 >  for  Number  { 
104132    fn  from ( i :  i32 )  -> Self  { 
105-         Number ( i as  i64 ) 
133+         #[ cfg( not( feature = "as_i32" ) ) ]  
134+         { 
135+             Number ( i as  i64 ) 
136+         } 
137+         #[ cfg( feature = "as_i32" ) ]  
138+         { 
139+             Number ( i) 
140+         } 
106141    } 
107142} 
108143
@@ -418,6 +453,32 @@ mod tests {
418453        assert_eq ! ( Number :: from( i32 :: MAX ) . as_i64( ) ,  Some ( i32 :: MAX  as  i64 ) ) ; 
419454    } 
420455
456+     #[ test]  
457+     fn  number_as_i32_conversion ( )  { 
458+         // Test values that fit in i32 
459+         assert_eq ! ( Number :: from( 1 ) . as_i32( ) ,  Some ( 1 ) ) ; 
460+         assert_eq ! ( Number :: from( 584 ) . as_i32( ) ,  Some ( 584 ) ) ; 
461+         assert_eq ! ( Number :: from( i32 :: MIN ) . as_i32( ) ,  Some ( i32 :: MIN ) ) ; 
462+         assert_eq ! ( Number :: from( i32 :: MAX ) . as_i32( ) ,  Some ( i32 :: MAX ) ) ; 
463+ 
464+         #[ cfg( not( feature = "as_i32" ) ) ]  
465+         { 
466+             // Test values that don't fit in i32 (only when using i64 internally) 
467+             let  too_large = Number ( i32:: MAX  as  i64  + 1 ) ; 
468+             assert_eq ! ( too_large. as_i32( ) ,  None ) ; 
469+ 
470+             let  too_small = Number ( i32:: MIN  as  i64  - 1 ) ; 
471+             assert_eq ! ( too_small. as_i32( ) ,  None ) ; 
472+         } 
473+ 
474+         #[ cfg( feature = "as_i32" ) ]  
475+         { 
476+             // When using i32 internally, all values will fit in i32 
477+             assert_eq ! ( Number ( 0 ) . as_i32( ) ,  Some ( 0 ) ) ; 
478+             assert_eq ! ( Number ( -1 ) . as_i32( ) ,  Some ( -1 ) ) ; 
479+         } 
480+     } 
481+ 
421482    #[ test]  
422483    fn  unquote_unicode_string ( )  { 
423484        // basic tests 
0 commit comments