Skip to content

Commit

Permalink
introduce writeln_safe_io
Browse files Browse the repository at this point in the history
  • Loading branch information
rozhkovdmitrii committed May 8, 2023
1 parent f520ceb commit aad8cc0
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 32 deletions.
57 changes: 25 additions & 32 deletions mm2src/adex_cli/src/adex_proc/response_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::io::Write;
use super::smart_fraction_fmt::SmartFractionFmt;
use super::OrderbookConfig;
use crate::adex_config::{AdexConfig, PricePrecision, VolumePrecision};
use common::io::{write_safe_io, writeln_safe_io, WriteSafeIO};

pub(crate) trait ResponseHandler {
fn print_response(&self, response: Json) -> Result<(), ()>;
Expand Down Expand Up @@ -44,7 +45,7 @@ impl ResponseHandler for ResponseHandlerImpl<'_> {
object
.iter()
.map(SimpleCliTable::from_pair)
.for_each(|value| writeln!(self.writer.borrow_mut(), "{}: {:?}", value.key, value.value).unwrap());
.for_each(|value| writeln_safe_io!(self.writer.borrow_mut(), "{}: {:?}", value.key, value.value));
Ok(())
}

Expand All @@ -63,7 +64,7 @@ impl ResponseHandler for ResponseHandlerImpl<'_> {

let base_vol_head = "Volume: ".to_string() + &orderbook.base;
let rel_price_head = "Price: ".to_string() + &orderbook.rel;
writeln!(
writeln_safe_io!(
writer,
"{}",
AskBidRow::new(
Expand All @@ -78,19 +79,17 @@ impl ResponseHandler for ResponseHandlerImpl<'_> {
"Order conf (bc,bn:rc,rn)",
&otderbook_config
)
)
.expect("Failed to write orderbook");
);

let price_prec = config.orderbook_price_precision();
let vol_prec = config.orderbook_volume_precision();

if orderbook.asks.is_empty() {
writeln!(
writeln_safe_io!(
writer,
"{}",
AskBidRow::new("", "No asks found", "", "", "", "", "", "", "", &otderbook_config)
)
.expect("Failed to write orderbook");
);
} else {
let skip = orderbook
.asks
Expand All @@ -104,47 +103,47 @@ impl ResponseHandler for ResponseHandlerImpl<'_> {
.sorted_by(cmp_asks)
.skip(skip)
.map(|entry| AskBidRow::from_orderbook_entry(entry, vol_prec, price_prec, &otderbook_config))
.for_each(|row: AskBidRow| writeln!(writer, "{}", row).unwrap());
.for_each(|row: AskBidRow| writeln_safe_io!(writer, "{}", row));
}
writeln!(writer, "{}", AskBidRow::new_delimiter(&otderbook_config)).expect("Failed to write orderbook");
writeln_safe_io!(writer, "{}", AskBidRow::new_delimiter(&otderbook_config));

if orderbook.bids.is_empty() {
writeln!(
writeln_safe_io!(
writer,
"{}",
AskBidRow::new("", "No bids found", "", "", "", "", "", "", "", &otderbook_config)
)
.unwrap();
);
} else {
orderbook
.bids
.iter()
.sorted_by(cmp_bids)
.take(otderbook_config.bids_limit.unwrap_or(usize::MAX))
.map(|entry| AskBidRow::from_orderbook_entry(entry, vol_prec, price_prec, &otderbook_config))
.for_each(|row: AskBidRow| writeln!(writer, "{}", row).expect("Failed to write orderbook"));
.for_each(|row: AskBidRow| writeln_safe_io!(writer, "{}", row));
}
Ok(())
}

fn on_get_enabled_response(&self, enabled: &KmdWalletRpcResult<GetEnabledResponse>) -> Result<(), ()> {
writeln!(self.writer.borrow_mut(), "{:8} {}", "Ticker", "Address").expect("Failed to write");
let mut writer = self.writer.borrow_mut();
writeln_safe_io!(writer, "{:8} {}", "Ticker", "Address");
for row in &enabled.result {
writeln!(self.writer.borrow_mut(), "{:8} {}", row.ticker, row.address).unwrap();
writeln_safe_io!(writer, "{:8} {}", row.ticker, row.address);
}
Ok(())
}

fn on_version_response(&self, response: &MmVersionResponse) -> Result<(), ()> {
let mut writer = self.writer.borrow_mut();
writeln!(writer, "Version: {}", response.result).expect("Failed to write version");
writeln!(writer, "Datetime: {}", response.datetime).expect("Failed to write version");
writeln_safe_io!(writer, "Version: {}", response.result);
writeln_safe_io!(writer, "Datetime: {}", response.datetime);
Ok(())
}

fn on_enable_response(&self, response: &CoinInitResponse) -> Result<(), ()> {
let mut writer = self.writer.borrow_mut();
writeln!(
writeln_safe_io!(
writer,
"coin: {}\naddress: {}\nbalance: {}\nunspendable_balance: {}\nrequired_confirmations: {}\nrequires_notarization: {}",
response.coin,
Expand All @@ -153,47 +152,41 @@ impl ResponseHandler for ResponseHandlerImpl<'_> {
response.unspendable_balance,
response.required_confirmations,
if response.requires_notarization { "Yes" } else { "No" }
)
.expect("Failed to write enable response");
);
if response.mature_confirmations.is_some() {
writeln!(
writeln_safe_io!(
writer,
"mature_confirmations: {}",
response.mature_confirmations.unwrap()
)
.expect("Failed to write enable response");
);
}
Ok(())
}

fn on_balance_response(&self, response: &BalanceResponse) -> Result<(), ()> {
writeln!(
writeln_safe_io!(
self.writer.borrow_mut(),
"coin: {}\nbalance: {}\nunspendable: {}\naddress: {}",
response.coin,
response.balance,
response.unspendable_balance,
response.address
)
.expect("Failed to write balance response");
);
Ok(())
}

fn on_sell_response(&self, response: &KmdWalletRpcResult<SellBuyResponse>) -> Result<(), ()> {
let mut writer = self.writer.borrow_mut();
writeln!(writer, "Order uuid: {}", response.request.uuid).expect("Failed to write sell response");
writeln_safe_io!(self.writer.borrow_mut(), "Order uuid: {}", response.request.uuid);
Ok(())
}

fn on_buy_response(&self, response: &KmdWalletRpcResult<SellBuyResponse>) -> Result<(), ()> {
let mut writer = self.writer.borrow_mut();
writeln!(writer, "Buy order uuid: {}", response.request.uuid).expect("Failed to write sell response");
writeln_safe_io!(self.writer.borrow_mut(), "Buy order uuid: {}", response.request.uuid);
Ok(())
}

fn on_stop_response(&self, response: &KmdWalletRpcResult<Status>) -> Result<(), ()> {
let mut writer = self.writer.borrow_mut();
writeln!(writer, "Service stopped: {}", response.result).expect("Failed to write stop response");
writeln_safe_io!(self.writer.borrow_mut(), "Service stopped: {}", response.result);
Ok(())
}
}
Expand Down
2 changes: 2 additions & 0 deletions mm2src/common/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ pub mod jsonrpc_client;
#[macro_use]
pub mod fmt;
#[macro_use]
pub mod io;
#[macro_use]
pub mod log;

pub mod crash_reports;
Expand Down
35 changes: 35 additions & 0 deletions mm2src/common/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::cell::RefMut;
use std::fmt;
use std::io::Write;
use std::ops::DerefMut;

mod macros {
#[macro_export]
macro_rules! write_safe_io {
($dst:expr, $($arg:tt)*) => {
$dst.write_safe(format_args!($($arg)*))
}
}
#[macro_export]
macro_rules! writeln_safe_io {
($dst:expr, $fmt:tt, $($arg:tt)*) => {{
write_safe_io!($dst, concat!($fmt, "\n"), $($arg)*);
}}
}
pub use write_safe_io;
pub use writeln_safe_io;
}

pub use macros::{write_safe_io, writeln_safe_io};

pub trait WriteSafeIO {
fn write_safe<'a>(&mut self, args: fmt::Arguments<'_>)
where
Self: DerefMut<Target = &'a mut dyn Write>,
{
let writer = self.deref_mut();
Write::write_fmt(writer, args).expect("`write_fmt` should never fail for `WriteSafeIO` types")
}
}

impl WriteSafeIO for RefMut<'_, &'_ mut dyn Write> {}

0 comments on commit aad8cc0

Please sign in to comment.