@@ -45,14 +45,19 @@ pub struct Directive<'a, T: Text<'a>> {
45
45
/// This represents integer number
46
46
///
47
47
/// 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
49
49
/// in `serde_json`: encapsulate value in new-type, allowing type
50
50
/// to be extended later.
51
51
#[ 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" ) ) ]
54
54
pub struct Number ( pub ( crate ) i64 ) ;
55
55
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
+
56
61
#[ derive( Debug , Clone , PartialEq ) ]
57
62
pub enum Value < ' a , T : Text < ' a > > {
58
63
Variable ( T :: Value ) ,
@@ -96,13 +101,43 @@ pub enum Type<'a, T: Text<'a>> {
96
101
impl Number {
97
102
/// Returns a number as i64 if it fits the type
98
103
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
+ }
100
128
}
101
129
}
102
130
103
131
impl From < i32 > for Number {
104
132
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
+ }
106
141
}
107
142
}
108
143
@@ -418,6 +453,32 @@ mod tests {
418
453
assert_eq ! ( Number :: from( i32 :: MAX ) . as_i64( ) , Some ( i32 :: MAX as i64 ) ) ;
419
454
}
420
455
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
+
421
482
#[ test]
422
483
fn unquote_unicode_string ( ) {
423
484
// basic tests
0 commit comments