use std::{future::Future, pin::Pin}; use futures::FutureExt; use mongod::{ derive::{Model, Referencable}, Model, ToAPI, Validate, }; use mongodb::bson::doc; use serde::{Deserialize, Serialize}; use serde_json::json; /// A Storage Location #[derive(Debug, Clone, Serialize, Deserialize, Model, Referencable)] pub struct Location { /// UUID #[serde(default)] pub _id: String, /// Name pub name: String, /// Parent pub parent: Option, /// Storage Conditions pub conditions: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct StorageConditions { /// Median temperature pub temperature: i64, } impl Validate for Location { async fn validate(&self) -> Result<(), String> { Ok(()) } } impl Location { /// Recursively get the conditions of a location. This inherits from parent locations. pub fn conditions_rec<'a>( &'a self, ) -> futures::future::BoxFuture<'a, Option> { async move { if let Some(cond) = &self.conditions { return Some(cond.clone()); } if let Some(parent) = &self.parent { if let Some(parent_loc) = Location::get(parent).await { if let Some(cond) = parent_loc.conditions_rec().await { return Some(cond); } } } None } .boxed() } } impl ToAPI for Location { async fn api(&self) -> serde_json::Value { json!({ "id": self._id, "name": self.name, "parent": self.parent, "conditions": self.conditions_rec().await }) } } impl Location { pub async fn add(&mut self, id: &str) { self._id = id.to_string(); self.insert_overwrite().await.unwrap(); } }