Skip to main content

smart_calculator/
lib.rs

1pub mod data;
2pub mod error;
3pub mod evaluators;
4mod formatting;
5pub mod http;
6pub mod parser;
7pub mod provider;
8pub mod types;
9
10use std::sync::Arc;
11
12use crate::{
13    error::{Error, Result},
14    evaluators::{
15        currency::{evaluate_crypto, evaluate_currency},
16        date::evaluate_date,
17        math::evaluate_math,
18        time::evaluate_time,
19        unit::evaluate_unit,
20    },
21    parser::detect_intent,
22    provider::DefaultProvider,
23    types::{CalculatorResult, Config, Intent},
24};
25
26pub async fn calculate(input: &str, options: Option<Config>) -> Result<CalculatorResult> {
27    let trimmed = input.trim();
28    if trimmed.is_empty() {
29        return Err(Error::RequiredParameter("input".to_string()));
30    }
31
32    let options = options.unwrap_or_default();
33    let intent = detect_intent(trimmed);
34
35    let provider = options
36        .rate_provider()
37        .unwrap_or_else(|| Arc::new(DefaultProvider));
38
39    match intent {
40        Intent::Currency { amount, from, to } => evaluate_currency(
41            amount,
42            from,
43            to,
44            Some(provider.as_ref()),
45            options.locale().clone(),
46            options.precision(),
47        )
48        .await
49        .map_err(|err| Error::Evaluation(err.to_string())),
50        Intent::Crypto { amount, from, to } => evaluate_crypto(
51            amount,
52            from,
53            to,
54            Some(provider.as_ref()),
55            options.locale().clone(),
56            options.precision(),
57        )
58        .await
59        .map_err(|err| Error::Evaluation(err.to_string())),
60        Intent::Math { expression } => {
61            evaluate_math(expression, options.locale().clone(), options.precision())
62                .map_err(|err| Error::Evaluation(err.to_string()))
63        }
64        Intent::Date { query } => {
65            evaluate_date(query).map_err(|err| Error::Evaluation(err.to_string()))
66        }
67        Intent::Time {
68            query,
69            from,
70            to,
71            time,
72        } => evaluate_time(query, from, to, time, options.timezone().clone())
73            .map_err(|err| Error::Evaluation(err.to_string())),
74        Intent::Unit {
75            amount, from, to, ..
76        } => evaluate_unit(
77            amount,
78            from,
79            to,
80            options.locale().clone(),
81            options.precision(),
82        )
83        .map_err(|err| Error::Evaluation(err.to_string())),
84    }
85}