use std::convert::TryInto;
use anyhow::Error;
use async_trait::async_trait;
use clap::Parser;
use tari_common_types::types::HashOutput;
use thiserror::Error;
use super::{CommandContext, HandleCommand, TypeOrHex};
use crate::commands::parser::Format;
#[derive(Debug, Parser)]
pub struct Args {
value: TypeOrHex<u64>,
#[clap(default_value_t)]
format: Format,
}
#[async_trait]
impl HandleCommand<Args> for CommandContext {
async fn handle_command(&mut self, args: Args) -> Result<(), Error> {
let format = args.format;
match args.value {
TypeOrHex::Type(value) => self.get_block(value, format).await,
TypeOrHex::Hex(hex) => {
let hash = hex.0.try_into()?;
self.get_block_by_hash(hash, format).await
},
}
}
}
#[derive(Error, Debug)]
enum ArgsError {
#[error("Block not found at height {height}")]
NotFoundAt { height: u64 },
}
impl CommandContext {
pub async fn get_block(&self, height: u64, format: Format) -> Result<(), Error> {
let block = self
.blockchain_db
.fetch_blocks(height..=height, false)
.await?
.pop()
.ok_or(ArgsError::NotFoundAt { height })?;
match format {
Format::Text => {
let block_data = self.blockchain_db.fetch_block_accumulated_data(*block.hash()).await?;
println!("{block}");
println!("-- Accumulated data --");
println!("{block_data}");
},
Format::Json => eprintln!("JSON format not supported for blocks in this command"),
}
Ok(())
}
pub async fn get_block_by_hash(&self, hash: HashOutput, format: Format) -> Result<(), Error> {
let block = self.blockchain_db.fetch_block_by_hash(hash, false).await?;
match block {
Some(block) => match format {
Format::Text => println!("{block}"),
Format::Json => eprintln!("JSON format not supported for blocks in this command"),
},
None => {
let block = self.blockchain_db.fetch_orphan(hash).await?;
println!("Found in orphan database");
match format {
Format::Text => println!("{block}"),
Format::Json => eprintln!("JSON format not supported for blocks in this command"),
}
},
};
Ok(())
}
}