Lines
71.43 %
Functions
Branches
100 %
//! Commodity-convert submit and reply handling for `App`.
use cli_core::eval::{build_convert_amount_form, parse_scalar_reply};
use crate::app::App;
use crate::route::RouteCtx;
use crate::view::ViewId;
impl App {
/// Submit a `convert-amount` query.
///
/// Returns `false` only when the eval worker has stopped.
pub fn submit_commodity_convert(
&mut self,
amount_num_denom: &str,
amount_str: &str,
from: &str,
from_label: &str,
to: &str,
to_label: &str,
) -> bool {
let form = build_convert_amount_form(amount_num_denom, from, to);
if self.console_eval.is_none() {
self.status = "console not connected".to_string();
return false;
}
match self.dispatch_eval(
ViewId::Commodities,
RouteCtx::ConvertQuery {
amount_str: amount_str.to_string(),
from_label: from_label.to_string(),
to_label: to_label.to_string(),
},
form,
) {
Some(_) => true,
None => {
self.status = "eval worker stopped".to_string();
false
/// Handle a `convert-amount` reply by formatting a status message.
pub(super) fn deliver_convert_reply(
wire: &str,
match parse_scalar_reply(wire) {
Ok(result) => {
self.status = format!("{amount_str} {from_label} = {result} {to_label}");
Err(e) => self.status = format!("convert failed: {e}"),
#[cfg(test)]
mod tests {
use super::*;
use crate::widgets::EditMode;
use sqlx::types::Uuid;
fn make_app() -> App {
App::new(Uuid::new_v4(), EditMode::Emacs)
#[test]
fn submit_commodity_convert_without_eval_sets_status() {
let mut app = make_app();
let ok = app.submit_commodity_convert("9/2", "9/2", "uuid-from", "USD", "uuid-to", "EUR");
assert!(!ok, "no eval worker → returns false");
assert_eq!(app.status, "console not connected");
fn deliver_convert_reply_error_wire_sets_status() {
let wire = r#"(:id 1 :error (:code convert-error :message "no price found"))"#;
app.deliver_convert_reply(wire, "9/2", "USD", "EUR");
assert!(
app.status.contains("convert failed"),
"error reply sets descriptive status: {}",
app.status
);