cdb/src/item.rs
2024-08-28 09:38:10 +02:00

129 lines
3.1 KiB
Rust

use std::collections::HashMap;
use mongod::{
derive::{Model, Referencable},
Validate,
};
use mongodb::bson::doc;
use serde::{Deserialize, Serialize};
use serde_json::json;
use crate::variant::Variant;
// todo : api key auth
// ITEM
// VARIANTS
// QUANTIZATION
// IMPORT / EXPORT
// DEPENDENCIES
// DEMAND STATS
// SEASONAL REVIEWS
/// Represents a single item in a collection of physical goods.
///
/// This struct serves as a blueprint for describing individual items within
/// a larger inventory or database of physical goods. It includes fields for
/// the name of the item and its category.
#[derive(Debug, Clone, Serialize, Deserialize, Model, Referencable)]
pub struct Item {
/// The ID
pub _id: String,
/// The name of the Item
pub name: String,
/// Category of the Item
pub category: Option<String>,
/// The variants of an Item.
/// Each key of the `HashMap<_>` is the ID of a variant and contains a `Variant`
pub variants: HashMap<String, Variant>,
}
impl Validate for Item {
async fn validate(&self) -> Result<(), String> {
Ok(())
}
}
impl Item {
/// Creates a new `Item` from a parsed markdown document
pub fn new(doc: &mdq::Document) -> Self {
let id = std::path::Path::new(&doc.path)
.file_stem()
.unwrap()
.to_str()
.unwrap()
.to_string();
let category = doc
.frontmatter
.as_mapping()
.unwrap()
.get("category")
.map(|x| x.as_str().unwrap().to_string());
let name = doc
.frontmatter
.as_mapping()
.unwrap()
.get("name")
.unwrap()
.as_str()
.unwrap()
.to_string();
let mut variants = HashMap::new();
let variants_lst = doc
.frontmatter
.as_mapping()
.unwrap()
.get("variants")
.map(|x| x.as_mapping().unwrap().clone())
.unwrap();
assert!(
!variants_lst.is_empty(),
"Item {id} needs at least one variant."
);
for (variant_id, variant) in variants_lst {
variants.insert(
variant_id.as_str().unwrap().to_string(),
Variant::from_yml(&variant, variant_id.as_str().unwrap(), &id),
);
}
Self {
_id: id,
name,
category,
variants,
}
}
}
impl Item {
/// Get this items variant names
pub fn get_variants(&self) -> Vec<String> {
self.variants.keys().cloned().collect()
}
/// Get a `Variant` of an `Item`
pub fn variant(&self, variant: &str) -> Option<Variant> {
self.variants.get(variant).cloned()
}
pub fn api_json(&self) -> serde_json::Value {
let variants: HashMap<String, serde_json::Value> = self
.variants
.iter()
.map(|(key, value)| (key.clone(), value.api_json()))
.collect();
json!({
"item": self.name,
"category": self.category,
"variants": variants
})
}
}