@@ -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
98103 pub 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