@@ -7,6 +7,11 @@ use crate::types::{Felt, U256};
77
88pub use starknet_core_derive:: { Decode , Encode } ;
99
10+ const I128_MIN : Felt =
11+ Felt :: from_hex_unchecked ( "0x0800000000000010ffffffffffffffff80000000000000000000000000000001" ) ;
12+ const I128_MAX : Felt =
13+ Felt :: from_hex_unchecked ( "0x000000000000000000000000000000007fffffffffffffffffffffffffffffff" ) ;
14+
1015/// Any type where [`Felt`]s can be written into. This would typically be [`Vec<Felt>`], but can
1116/// also be something like a stateful hasher.
1217///
@@ -175,6 +180,13 @@ impl Encode for U256 {
175180 }
176181}
177182
183+ impl Encode for i128 {
184+ fn encode < W : FeltWriter > ( & self , writer : & mut W ) -> Result < ( ) , Error > {
185+ writer. write ( ( * self ) . into ( ) ) ;
186+ Ok ( ( ) )
187+ }
188+ }
189+
178190impl < T > Encode for Option < T >
179191where
180192 T : Encode ,
@@ -343,6 +355,25 @@ impl<'a> Decode<'a> for U256 {
343355 }
344356}
345357
358+ impl < ' a > Decode < ' a > for i128 {
359+ fn decode_iter < T > ( iter : & mut T ) -> Result < Self , Error >
360+ where
361+ T : Iterator < Item = & ' a Felt > ,
362+ {
363+ let input = iter. next ( ) . ok_or_else ( Error :: input_exhausted) ?;
364+
365+ if input <= & I128_MAX {
366+ // Range checked. Safe to unwrap.
367+ Ok ( input. to_i128 ( ) . unwrap ( ) )
368+ } else if input >= & I128_MIN {
369+ // Range checked. Safe to unwrap.
370+ Ok ( Self :: MIN + ( input - I128_MIN ) . to_i128 ( ) . unwrap ( ) )
371+ } else {
372+ Err ( Error :: value_out_of_range ( input, "i128" ) )
373+ }
374+ }
375+ }
376+
346377impl < ' a , T > Decode < ' a > for Option < T >
347378where
348379 T : Decode < ' a > ,
@@ -553,6 +584,71 @@ mod tests {
553584 ) ;
554585 }
555586
587+ #[ test]
588+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test:: wasm_bindgen_test) ]
589+ fn test_encode_i128 ( ) {
590+ for ( raw, felt) in [
591+ (
592+ 0i128 ,
593+ Felt :: from_hex_unchecked (
594+ "0x0000000000000000000000000000000000000000000000000000000000000000" ,
595+ ) ,
596+ ) ,
597+ (
598+ -1i128 ,
599+ Felt :: from_hex_unchecked (
600+ "0x0800000000000011000000000000000000000000000000000000000000000000" ,
601+ ) ,
602+ ) ,
603+ (
604+ 1i128 ,
605+ Felt :: from_hex_unchecked (
606+ "0x0000000000000000000000000000000000000000000000000000000000000001" ,
607+ ) ,
608+ ) ,
609+ (
610+ 10000i128 ,
611+ Felt :: from_hex_unchecked (
612+ "0x0000000000000000000000000000000000000000000000000000000000002710" ,
613+ ) ,
614+ ) ,
615+ (
616+ -10000i128 ,
617+ Felt :: from_hex_unchecked (
618+ "0x0800000000000010ffffffffffffffffffffffffffffffffffffffffffffd8f1" ,
619+ ) ,
620+ ) ,
621+ (
622+ i128:: MIN ,
623+ Felt :: from_hex_unchecked (
624+ "0x0800000000000010ffffffffffffffff80000000000000000000000000000001" ,
625+ ) ,
626+ ) ,
627+ (
628+ i128:: MIN + 1 ,
629+ Felt :: from_hex_unchecked (
630+ "0x0800000000000010ffffffffffffffff80000000000000000000000000000002" ,
631+ ) ,
632+ ) ,
633+ (
634+ i128:: MAX ,
635+ Felt :: from_hex_unchecked (
636+ "0x000000000000000000000000000000007fffffffffffffffffffffffffffffff" ,
637+ ) ,
638+ ) ,
639+ (
640+ i128:: MAX - 1 ,
641+ Felt :: from_hex_unchecked (
642+ "0x000000000000000000000000000000007ffffffffffffffffffffffffffffffe" ,
643+ ) ,
644+ ) ,
645+ ] {
646+ let mut serialized = Vec :: < Felt > :: new ( ) ;
647+ raw. encode ( & mut serialized) . unwrap ( ) ;
648+ assert_eq ! ( serialized, vec![ felt] ) ;
649+ }
650+ }
651+
556652 #[ test]
557653 #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test:: wasm_bindgen_test) ]
558654 fn test_encode_u256 ( ) {
@@ -817,6 +913,69 @@ mod tests {
817913 ) ;
818914 }
819915
916+ #[ test]
917+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test:: wasm_bindgen_test) ]
918+ fn test_decode_i128 ( ) {
919+ for ( raw, felt) in [
920+ (
921+ 0i128 ,
922+ Felt :: from_hex_unchecked (
923+ "0x0000000000000000000000000000000000000000000000000000000000000000" ,
924+ ) ,
925+ ) ,
926+ (
927+ -1i128 ,
928+ Felt :: from_hex_unchecked (
929+ "0x0800000000000011000000000000000000000000000000000000000000000000" ,
930+ ) ,
931+ ) ,
932+ (
933+ 1i128 ,
934+ Felt :: from_hex_unchecked (
935+ "0x0000000000000000000000000000000000000000000000000000000000000001" ,
936+ ) ,
937+ ) ,
938+ (
939+ 10000i128 ,
940+ Felt :: from_hex_unchecked (
941+ "0x0000000000000000000000000000000000000000000000000000000000002710" ,
942+ ) ,
943+ ) ,
944+ (
945+ -10000i128 ,
946+ Felt :: from_hex_unchecked (
947+ "0x0800000000000010ffffffffffffffffffffffffffffffffffffffffffffd8f1" ,
948+ ) ,
949+ ) ,
950+ (
951+ i128:: MIN ,
952+ Felt :: from_hex_unchecked (
953+ "0x0800000000000010ffffffffffffffff80000000000000000000000000000001" ,
954+ ) ,
955+ ) ,
956+ (
957+ i128:: MIN + 1 ,
958+ Felt :: from_hex_unchecked (
959+ "0x0800000000000010ffffffffffffffff80000000000000000000000000000002" ,
960+ ) ,
961+ ) ,
962+ (
963+ i128:: MAX ,
964+ Felt :: from_hex_unchecked (
965+ "0x000000000000000000000000000000007fffffffffffffffffffffffffffffff" ,
966+ ) ,
967+ ) ,
968+ (
969+ i128:: MAX - 1 ,
970+ Felt :: from_hex_unchecked (
971+ "0x000000000000000000000000000000007ffffffffffffffffffffffffffffffe" ,
972+ ) ,
973+ ) ,
974+ ] {
975+ assert_eq ! ( raw, i128 :: decode( & [ felt] ) . unwrap( ) ) ;
976+ }
977+ }
978+
820979 #[ test]
821980 #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test:: wasm_bindgen_test) ]
822981 fn test_decode_u256 ( ) {
0 commit comments