1use crate::TextWrapper;
2use alloy_primitives::{Address, FixedBytes, Uint, hex};
3use sqlx::{
4 Encode, Sqlite, Type,
5 encode::IsNull,
6 error::BoxDynError,
7 sqlite::{SqliteArgumentValue, SqliteTypeInfo},
8};
9
10impl<const N: usize> Type<Sqlite> for TextWrapper<FixedBytes<N>> {
11 fn type_info() -> SqliteTypeInfo {
12 <String as Type<Sqlite>>::type_info()
13 }
14
15 fn compatible(ty: &SqliteTypeInfo) -> bool {
16 <String as Type<Sqlite>>::compatible(ty)
17 }
18}
19
20impl<const N: usize> Encode<'_, Sqlite> for TextWrapper<FixedBytes<N>> {
21 fn encode_by_ref(
22 &self,
23 args: &mut Vec<SqliteArgumentValue<'_>>,
24 ) -> Result<IsNull, BoxDynError> {
25 let s = hex::encode(self.0.as_slice());
26 args.push(SqliteArgumentValue::Text(s.into()));
27 Ok(IsNull::No)
28 }
29}
30
31impl<'r, const N: usize> ::sqlx::Decode<'r, Sqlite> for TextWrapper<FixedBytes<N>> {
32 fn decode(value: ::sqlx::sqlite::SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
33 let text = <&str as ::sqlx::Decode<Sqlite>>::decode(value)?;
34 let bytes = hex::decode(text)?;
35 if bytes.len() != N {
36 return Err(format!("expected {N} bytes but got {}", bytes.len()).into());
37 }
38 let mut ret = [0u8; N];
39 ret.copy_from_slice(&bytes);
40 Ok(TextWrapper(ret.into()))
41 }
42}
43
44impl<const BITS: usize, const LIMBS: usize> Type<Sqlite> for TextWrapper<Uint<BITS, LIMBS>> {
45 fn type_info() -> SqliteTypeInfo {
46 <String as Type<Sqlite>>::type_info()
47 }
48
49 fn compatible(ty: &SqliteTypeInfo) -> bool {
50 <String as Type<Sqlite>>::compatible(ty)
51 }
52}
53
54impl<const BITS: usize, const LIMBS: usize> Encode<'_, Sqlite> for TextWrapper<Uint<BITS, LIMBS>> {
55 fn encode_by_ref(
56 &self,
57 args: &mut Vec<SqliteArgumentValue<'_>>,
58 ) -> Result<IsNull, BoxDynError> {
59 let s = self.0.to_string();
60 args.push(SqliteArgumentValue::Text(s.into()));
61 Ok(IsNull::No)
62 }
63}
64
65impl<'r, const BITS: usize, const LIMBS: usize> ::sqlx::Decode<'r, Sqlite>
66 for TextWrapper<Uint<BITS, LIMBS>>
67{
68 fn decode(value: ::sqlx::sqlite::SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
69 let text = <&str as ::sqlx::Decode<Sqlite>>::decode(value)?;
70 let uint = text.parse::<Uint<BITS, LIMBS>>()?;
71 Ok(TextWrapper(uint))
72 }
73}
74
75impl Type<Sqlite> for TextWrapper<Address> {
76 fn type_info() -> SqliteTypeInfo {
77 <String as Type<Sqlite>>::type_info()
78 }
79
80 fn compatible(ty: &SqliteTypeInfo) -> bool {
81 <String as Type<Sqlite>>::compatible(ty)
82 }
83}
84
85impl Encode<'_, Sqlite> for TextWrapper<Address> {
86 fn encode_by_ref(
87 &self,
88 args: &mut Vec<SqliteArgumentValue<'_>>,
89 ) -> Result<IsNull, BoxDynError> {
90 TextWrapper(self.0.0).encode_by_ref(args)
91 }
92}
93
94impl<'r> ::sqlx::Decode<'r, Sqlite> for TextWrapper<Address> {
95 fn decode(value: ::sqlx::sqlite::SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
96 let text_wrapper = <TextWrapper<FixedBytes<20>> as ::sqlx::Decode<Sqlite>>::decode(value)?;
97 Ok(TextWrapper(Address(text_wrapper.0)))
98 }
99}