Skip to content

Commit de3fec7

Browse files
authored
feat: codec traits impl for i128 (#685)
1 parent 21e0573 commit de3fec7

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed

starknet-core/src/codec.rs

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ use crate::types::{Felt, U256};
77

88
pub 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+
178190
impl<T> Encode for Option<T>
179191
where
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+
346377
impl<'a, T> Decode<'a> for Option<T>
347378
where
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

Comments
 (0)