grocery-to-json 0.0.3

Convert images of reciepts to jsons
Documentation
use chrono::{DateTime, Utc};
use regex::Regex;
use serde::{Deserialize, Serialize};

use crate::reciept::Reciept;

#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq)]
pub struct Item {
    pub id: u64,
    pub name: String,
    pub cost: f64,
}

#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct Aldi {
    pub location: String,
    pub total: f64,
    pub transaction_date: Option<DateTime<Utc>>,
    pub items: Vec<Item>,
}

impl TryFrom<Reciept> for Aldi {
    type Error = ();

    fn try_from(value: Reciept) -> Result<Self, Self::Error> {
        Ok(Aldi::convert(value.text))
    }
}

impl Aldi {
    fn convert(value: String) -> Aldi {
        Aldi {
            location: Self::get_store_name(),
            total: Self::get_total_cost(&value),
            transaction_date: Some(Utc::now()),
            items: Self::get_items(&value),
        }
    }

    fn get_store_name() -> String {
        "Aldi".to_owned()
    }

    fn get_total_cost(raw_text: &String) -> f64 {
        let re = Regex::new(r"AMOUNT DUE (.*)").unwrap();
        let caps = re.captures(&raw_text);

        match caps {
            Some(part) => match part.get(1) {
                Some(part) => match part.as_str().parse::<f64>() {
                    Ok(res) => res,
                    Err(_) => 0.0,
                },
                None => 0.0,
            },
            None => 0.0,
        }
    }

    fn get_items(raw_text: &String) -> Vec<Item> {
        let re = Regex::new(r"([0-9]{6,7}) ([^0-9,\n]*) (([0-9,\.]+) [A-Z]+)?").unwrap();
        let mut items: Vec<Item> = Vec::new();

        for cap in re.captures_iter(raw_text) {
            let item_id = match cap.get(1) {
                Some(part) => match part.as_str().parse::<u64>() {
                    Ok(res) => res,
                    Err(_) => 0,
                },
                None => 0,
            };

            let item_name = match cap.get(2) {
                Some(res) => res.as_str(),
                None => " ",
            };

            let item_cost = match cap.get(4) {
                Some(part) => match part.as_str().parse::<f64>() {
                    Ok(res) => res,
                    Err(_) => 0.0,
                },
                None => 0.0,
            };

            items.push(Item {
                id: item_id,
                name: item_name.to_owned(),
                cost: item_cost,
            });
        }

        items
    }
}