Skip to main content

tui/app/
convert.rs

1//! Commodity-convert submit and reply handling for `App`.
2
3use cli_core::eval::{build_convert_amount_form, parse_scalar_reply};
4
5use crate::app::App;
6use crate::route::RouteCtx;
7use crate::view::ViewId;
8
9impl App {
10    /// Submit a `convert-amount` query.
11    ///
12    /// Returns `false` only when the eval worker has stopped.
13    pub fn submit_commodity_convert(
14        &mut self,
15        amount_num_denom: &str,
16        amount_str: &str,
17        from: &str,
18        from_label: &str,
19        to: &str,
20        to_label: &str,
21    ) -> bool {
22        let form = build_convert_amount_form(amount_num_denom, from, to);
23        if self.console_eval.is_none() {
24            self.status = "console not connected".to_string();
25            return false;
26        }
27        match self.dispatch_eval(
28            ViewId::Commodities,
29            RouteCtx::ConvertQuery {
30                amount_str: amount_str.to_string(),
31                from_label: from_label.to_string(),
32                to_label: to_label.to_string(),
33            },
34            form,
35        ) {
36            Some(_) => true,
37            None => {
38                self.status = "eval worker stopped".to_string();
39                false
40            }
41        }
42    }
43
44    /// Handle a `convert-amount` reply by formatting a status message.
45    pub(super) fn deliver_convert_reply(
46        &mut self,
47        wire: &str,
48        amount_str: &str,
49        from_label: &str,
50        to_label: &str,
51    ) {
52        match parse_scalar_reply(wire) {
53            Ok(result) => {
54                self.status = format!("{amount_str} {from_label} = {result} {to_label}");
55            }
56            Err(e) => self.status = format!("convert failed: {e}"),
57        }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64    use crate::widgets::EditMode;
65    use sqlx::types::Uuid;
66
67    fn make_app() -> App {
68        App::new(Uuid::new_v4(), EditMode::Emacs)
69    }
70
71    #[test]
72    fn submit_commodity_convert_without_eval_sets_status() {
73        let mut app = make_app();
74        let ok = app.submit_commodity_convert("9/2", "9/2", "uuid-from", "USD", "uuid-to", "EUR");
75        assert!(!ok, "no eval worker → returns false");
76        assert_eq!(app.status, "console not connected");
77    }
78
79    #[test]
80    fn deliver_convert_reply_error_wire_sets_status() {
81        let mut app = make_app();
82        let wire = r#"(:id 1 :error (:code convert-error :message "no price found"))"#;
83        app.deliver_convert_reply(wire, "9/2", "USD", "EUR");
84        assert!(
85            app.status.contains("convert failed"),
86            "error reply sets descriptive status: {}",
87            app.status
88        );
89    }
90}