@@ -2,13 +2,15 @@ use libquickjs_ng_sys::{JSContext, JSValue};
22use serde:: { ser, Serialize } ;
33
44use crate :: utils:: {
5- create_bool, create_empty_array, create_empty_object, create_float, create_int, create_null ,
6- create_string, create_undefined, own_raw_value,
5+ create_bigint , create_bool, create_empty_array, create_empty_object, create_float, create_int,
6+ create_null , create_string, create_undefined, own_raw_value,
77} ;
88use crate :: value:: { OwnedJsArray , OwnedJsObject , OwnedJsValue } ;
99
1010use super :: error:: { Error , Result } ;
1111
12+ const MAX_SAFE_INTEGER : u64 = 9007199254740991 ;
13+
1214/// A structure that serializes Rust values into JS values.
1315pub struct Serializer {
1416 context : * mut JSContext ,
@@ -153,39 +155,65 @@ impl<'a> ser::Serializer for &'a mut Serializer {
153155 // will be serialized the same. Other formats, especially compact binary
154156 // formats, may need independent logic for the different sizes.
155157 fn serialize_i8 ( self , v : i8 ) -> Result < ( ) > {
156- self . serialize_i64 ( i64 :: from ( v) )
158+ self . serialize_i32 ( i32 :: from ( v) )
157159 }
158160
159161 fn serialize_i16 ( self , v : i16 ) -> Result < ( ) > {
160- self . serialize_i64 ( i64 :: from ( v) )
162+ self . serialize_i32 ( i32 :: from ( v) )
161163 }
162164
163165 fn serialize_i32 ( self , v : i32 ) -> Result < ( ) > {
164- self . serialize_i64 ( i64:: from ( v) )
166+ let value = create_int ( self . context , v as i32 ) ;
167+ self . set_node_value ( value)
165168 }
166169
167170 // Not particularly efficient but this is example code anyway. A more
168171 // performant approach would be to use the `itoa` crate.
169172 fn serialize_i64 ( self , v : i64 ) -> Result < ( ) > {
170- let value = create_int ( self . context , v as i32 ) ;
171- self . set_node_value ( value)
173+ if v > MAX_SAFE_INTEGER as i64 {
174+ let value = create_bigint ( self . context , ( v as i64 ) . into ( ) ) ?;
175+ self . set_node_value ( value)
176+ } else if v > i32:: MAX as i64 {
177+ let value = create_float ( self . context , v as f64 ) ;
178+ self . set_node_value ( value)
179+ } else {
180+ let value = create_int ( self . context , v as i32 ) ;
181+ self . set_node_value ( value)
182+ }
172183 }
173184
174185 fn serialize_u8 ( self , v : u8 ) -> Result < ( ) > {
175- self . serialize_u64 ( u64 :: from ( v) )
186+ self . serialize_i32 ( i32 :: from ( v) )
176187 }
177188
178189 fn serialize_u16 ( self , v : u16 ) -> Result < ( ) > {
179- self . serialize_u64 ( u64 :: from ( v) )
190+ self . serialize_i32 ( i32 :: from ( v) )
180191 }
181192
182193 fn serialize_u32 ( self , v : u32 ) -> Result < ( ) > {
183- self . serialize_u64 ( u64:: from ( v) )
194+ if v > i32:: MAX as u32 {
195+ let value = create_float ( self . context , v as f64 ) ;
196+ self . set_node_value ( value)
197+ } else {
198+ let value = create_int ( self . context , v as i32 ) ;
199+ self . set_node_value ( value)
200+ }
184201 }
185202
186203 fn serialize_u64 ( self , v : u64 ) -> Result < ( ) > {
187- let value = create_int ( self . context , v as i32 ) ;
188- self . set_node_value ( value)
204+ if v > i64:: MAX as u64 {
205+ let value = create_bigint ( self . context , num_bigint:: BigInt :: from ( v) . into ( ) ) ?;
206+ self . set_node_value ( value)
207+ } else if v > MAX_SAFE_INTEGER {
208+ let value = create_bigint ( self . context , ( v as i64 ) . into ( ) ) ?;
209+ self . set_node_value ( value)
210+ } else if v > i32:: MAX as u64 {
211+ let value = create_float ( self . context , v as f64 ) ;
212+ self . set_node_value ( value)
213+ } else {
214+ let value = create_int ( self . context , v as i32 ) ;
215+ self . set_node_value ( value)
216+ }
189217 }
190218
191219 fn serialize_f32 ( self , v : f32 ) -> Result < ( ) > {
0 commit comments