use mongod::{derive::{Model, Referencable}, Validate}; use mongodb::bson::doc; use serde::{Deserialize, Serialize}; use serde_json::json; #[derive(Debug, Clone, Serialize, Deserialize, Model, Referencable)] pub struct Transaction { pub _id: String, pub item: String, pub variant: String, pub price: Price, pub origin: Option, pub consumed: Option, pub timestamp: i64, } impl Validate for Transaction { async fn validate(&self) -> Result<(), String> { Ok(()) } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Consumed { pub destination: String, pub price: Price, } impl Transaction { pub fn new(item: &str, variant: &str, price: Price, origin: Option<&str>) -> Self { Self { _id: uuid::Uuid::new_v4().to_string(), item: item.to_string(), variant: variant.to_string(), price, consumed: None, origin: origin.map(|x| x.to_string()), timestamp: chrono::Utc::now().timestamp(), } } pub fn api_json(&self) -> serde_json::Value { json!({ "uuid": self._id, "item": self.item, "variant": self.variant, "price": self.price, "origin": self.origin, "timestamp": self.timestamp }) } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Price { pub value: f64, pub currency: String, } impl Price { pub fn new(value: f64, currency: &str) -> Self { Self { value, currency: currency.to_string(), } } fn parse(price: &str) -> Option { let (value, currency) = price.split_once(' ')?; Some(Self { value: value.parse().ok()?, currency: currency.to_string(), }) } } impl TryFrom for Price { type Error = (); fn try_from(value: String) -> Result { Self::parse(&value).ok_or(()) } }