utility_cli_rs/network_view_at_block/
mod.rs

1use std::str::FromStr;
2
3use color_eyre::eyre::ContextCompat;
4use strum::{EnumDiscriminants, EnumIter, EnumMessage};
5use unc_primitives::types::{BlockId, BlockReference, Finality};
6
7pub type OnAfterGettingBlockReferenceCallback =
8    std::sync::Arc<dyn Fn(&crate::config::NetworkConfig, &BlockReference) -> crate::CliResult>;
9
10#[derive(Clone)]
11pub struct ArgsForViewContext {
12    pub config: crate::config::Config,
13    pub interacting_with_account_ids: Vec<unc_primitives::types::AccountId>,
14    pub on_after_getting_block_reference_callback: OnAfterGettingBlockReferenceCallback,
15}
16
17#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
18#[interactive_clap(input_context = ArgsForViewContext)]
19#[interactive_clap(output_context = NetworkViewAtBlockArgsContext)]
20pub struct NetworkViewAtBlockArgs {
21    /// What is the name of the network?
22    #[interactive_clap(skip_default_input_arg)]
23    network_name: String,
24    #[interactive_clap(subcommand)]
25    next: ViewAtBlock,
26}
27
28#[derive(Clone)]
29pub struct NetworkViewAtBlockArgsContext {
30    network_config: crate::config::NetworkConfig,
31    on_after_getting_block_reference_callback: OnAfterGettingBlockReferenceCallback,
32}
33
34impl NetworkViewAtBlockArgsContext {
35    pub fn from_previous_context(
36        previous_context: ArgsForViewContext,
37        scope: &<NetworkViewAtBlockArgs as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
38    ) -> color_eyre::eyre::Result<Self> {
39        let network_connection = previous_context.config.network_connection.clone();
40        let network_config = network_connection
41            .get(&scope.network_name)
42            .wrap_err("Failed to get network config!")?
43            .clone();
44        Ok(Self {
45            network_config,
46            on_after_getting_block_reference_callback: previous_context
47                .on_after_getting_block_reference_callback,
48        })
49    }
50}
51
52impl NetworkViewAtBlockArgs {
53    fn input_network_name(
54        context: &ArgsForViewContext,
55    ) -> color_eyre::eyre::Result<Option<String>> {
56        crate::common::input_network_name(&context.config, &context.interacting_with_account_ids)
57    }
58}
59
60#[derive(Debug, EnumDiscriminants, Clone, interactive_clap::InteractiveClap)]
61#[interactive_clap(context = NetworkViewAtBlockArgsContext)]
62#[strum_discriminants(derive(EnumMessage, EnumIter))]
63/// Сhoose block for view:
64pub enum ViewAtBlock {
65    #[strum_discriminants(strum(
66        message = "now               - View properties in the final block"
67    ))]
68    /// View properties in the final block
69    Now(Now),
70    #[strum_discriminants(strum(
71        message = "at-block-height   - View properties in a height-selected block"
72    ))]
73    /// View properties in a height-selected block
74    AtBlockHeight(AtBlockHeight),
75    #[strum_discriminants(strum(
76        message = "at-block-hash     - View properties in a hash-selected block"
77    ))]
78    /// View properties in a hash-selected block
79    AtBlockHash(BlockIdHash),
80}
81
82#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
83#[interactive_clap(input_context = NetworkViewAtBlockArgsContext)]
84#[interactive_clap(output_context = NowContext)]
85pub struct Now;
86
87#[derive(Debug, Clone)]
88pub struct NowContext;
89
90impl NowContext {
91    pub fn from_previous_context(
92        previous_context: NetworkViewAtBlockArgsContext,
93        _scope: &<Now as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
94    ) -> color_eyre::eyre::Result<Self> {
95        let block_reference = Finality::Final.into();
96
97        (previous_context.on_after_getting_block_reference_callback)(
98            &previous_context.network_config,
99            &block_reference,
100        )?;
101        Ok(Self)
102    }
103}
104
105#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
106#[interactive_clap(input_context = NetworkViewAtBlockArgsContext)]
107#[interactive_clap(output_context = AtBlockHeightContext)]
108pub struct AtBlockHeight {
109    /// Type the block ID height:
110    block_id_height: unc_primitives::types::BlockHeight,
111}
112
113#[derive(Debug, Clone)]
114pub struct AtBlockHeightContext;
115
116impl AtBlockHeightContext {
117    pub fn from_previous_context(
118        previous_context: NetworkViewAtBlockArgsContext,
119        scope: &<AtBlockHeight as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
120    ) -> color_eyre::eyre::Result<Self> {
121        let block_reference = BlockReference::BlockId(BlockId::Height(scope.block_id_height));
122
123        (previous_context.on_after_getting_block_reference_callback)(
124            &previous_context.network_config,
125            &block_reference,
126        )?;
127        Ok(Self)
128    }
129}
130
131#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
132#[interactive_clap(input_context = NetworkViewAtBlockArgsContext)]
133#[interactive_clap(output_context = BlockIdHashContext)]
134pub struct BlockIdHash {
135    /// Type the block ID hash:
136    block_id_hash: String,
137}
138
139#[derive(Debug, Clone)]
140pub struct BlockIdHashContext;
141
142impl BlockIdHashContext {
143    pub fn from_previous_context(
144        previous_context: NetworkViewAtBlockArgsContext,
145        scope: &<BlockIdHash as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
146    ) -> color_eyre::eyre::Result<Self> {
147        let block_reference = BlockReference::BlockId(BlockId::Hash(
148            unc_primitives::hash::CryptoHash::from_str(&scope.block_id_hash).unwrap(),
149        ));
150
151        (previous_context.on_after_getting_block_reference_callback)(
152            &previous_context.network_config,
153            &block_reference,
154        )?;
155        Ok(Self)
156    }
157}