Skip to main content

gm_lib/
utils.rs

1pub mod account;
2pub mod assets;
3pub mod cursor;
4pub mod erc20;
5pub mod text;
6
7pub trait Inquire<DefaultValue = ()>
8where
9    Self: Sized,
10{
11    fn inquire(default: &DefaultValue) -> Option<Self>;
12}
13
14/// Macro to implement `Inquire` for enums that derive `EnumIter`
15#[macro_export]
16macro_rules! impl_inquire_selection {
17    ($enum_name:ident, $carry_on_name:tt) => {
18        impl $crate::utils::Inquire<$carry_on_name> for $enum_name {
19            fn inquire(_: &$carry_on_name) -> Option<$enum_name> {
20                let options: Vec<$enum_name> = $enum_name::iter().collect();
21
22                inquire::Select::new("Choose subcommand:", options)
23                    .with_formatter(&|a| format!("{a}"))
24                    .prompt()
25                    .ok()
26            }
27        }
28    };
29}
30
31pub trait Handle<CarryOn = ()>
32where
33    Self: Sized + Inquire<CarryOn>,
34{
35    fn handle(&self, carry_on: CarryOn);
36
37    // If action value is None, call `inquire` to get the action
38    fn handle_optn_inquire(action: &Option<Self>, carry_on: CarryOn) {
39        if let Some(action) = action {
40            action.handle(carry_on);
41        } else {
42            let result = Self::inquire(&carry_on);
43            if let Some(action) = result {
44                action.handle(carry_on);
45            }
46        };
47    }
48}
49
50pub type Provider = alloy::providers::fillers::FillProvider<
51    alloy::providers::fillers::JoinFill<
52        alloy::providers::Identity,
53        alloy::providers::fillers::JoinFill<
54            alloy::providers::fillers::GasFiller,
55            alloy::providers::fillers::JoinFill<
56                alloy::providers::fillers::BlobGasFiller,
57                alloy::providers::fillers::JoinFill<
58                    alloy::providers::fillers::NonceFiller,
59                    alloy::providers::fillers::ChainIdFiller,
60                >,
61            >,
62        >,
63    >,
64    alloy::providers::RootProvider,
65>;
66
67pub trait SerdeResponseParse {
68    fn serde_parse_custom<T>(self) -> impl std::future::Future<Output = crate::Result<T>> + Send
69    where
70        T: serde::de::DeserializeOwned;
71}
72
73impl SerdeResponseParse for reqwest::Response {
74    async fn serde_parse_custom<T>(self) -> crate::Result<T>
75    where
76        T: serde::de::DeserializeOwned,
77    {
78        serde_response_parse::<T>(self).await
79    }
80}
81
82async fn serde_response_parse<T>(response: reqwest::Response) -> crate::Result<T>
83where
84    T: serde::de::DeserializeOwned,
85{
86    serde_path_to_error::deserialize(&mut serde_json::Deserializer::from_str(
87        &response.text().await?,
88    ))
89    .map_err(|e| crate::Error::SerdePathToError(Box::new(e)))
90}