convers 0.2.1

Cool convert library that converts almost everything(not yet).Units,Languages,Calculations,etc.
Documentation
use anyhow::{bail, Result};
use regex::Regex;
use serde_json::Value;
#[derive(Debug)]
pub struct Currency {
    pub currency: String,
    pub amount: f64,
}

impl Currency {
    pub fn new(currency: String, amount: f64) -> Self {
        Self { currency, amount }
    }

    pub fn txt(&self) -> String {
        format!("{} {}", self.amount, self.currency)
    }

    pub fn from_str(query: &String) -> Result<Currency> {
        let mut curr = Currency::new(String::new(), 0.);
        let num_str = query
            .chars()
            .take_while(|c| c.is_digit(10) || c == &'.')
            .collect::<String>();
        match num_str.parse::<f64>() {
            Ok(v) => curr.amount = v,
            Err(_) => {}
        };
        let curr_part = query.chars().skip(num_str.len()).collect::<String>();
        if curr_part.is_empty() {
            bail!("Invalid conversion query: error parsing unit part.");
        }
        curr.currency = curr_part;

        Ok(curr)
    }
}

// Converts currency from args.
pub async fn curr_convert(from: &str, to: &str, amount: f64) -> Result<Currency> {
    let response = reqwest::get(
        "https://open.er-api.com/v6/latest/".to_owned() + from.to_uppercase().as_str(),
    )
    .await?
    .json::<Value>()
    .await?;
    let rates = response["rates"].as_object();
    if let None = rates {
        bail!("Invalid conversion query: error parsing rates part.");
    }
    let rates = rates.unwrap();
    let rate = rates.get(&to.to_uppercase());
    if let None = rate {
        bail!("Invalid conversion query: error parsing rate part.");
    }
    if let None = rate.unwrap().as_f64() {
        bail!("Invalid conversion query: error parsing rate part.");
    }
    let curr = Currency::new(to.to_string(), amount * rate.unwrap().as_f64().unwrap());
    Ok(curr)
}

// Converts currency from String query.
pub async fn curr_convert_q(query: &String) -> Result<Currency> {
    let regex = Regex::new(r"(:|to)").unwrap();
    let parts: Vec<&str> = regex.split(query).collect(); //

    if parts.len() != 2 {
        bail!("Invalid conversion query: error parsing parts.");
    }
    let from_part = parts[0].split_whitespace().collect::<String>();
    let to_part = parts[1].split_whitespace().collect::<String>();
    let from = match Currency::from_str(&from_part) {
        Ok(m) => m,
        Err(_) => bail!("Invalid conversion query: error parsing from part."),
    };
    let to = match Currency::from_str(&to_part) {
        Ok(m) => m,
        Err(_) => bail!("Invalid conversion query: error parsing to part"),
    };
    let curr = curr_convert(&from.currency, &to.currency, from.amount).await?;

    Ok(curr)
}