bazzar/crates/web/src/model.rs

115 lines
2.9 KiB
Rust

use std::collections::{HashMap, HashSet};
use seed::Url;
use crate::{shopping_cart, I18n, Page};
#[derive(Debug)]
pub struct Model {
/// URL object for path constructor
pub url: Url,
/// Access token
pub token: Option<String>,
/// Current SPA page
pub page: Page,
/// Logo url form favicon href
pub logo: Option<String>,
/// Shared data
pub shared: crate::shared::Model,
/// Translations
pub i18n: I18n,
/// Shopping cart information
pub cart: shopping_cart::ShoppingCart,
/// Application config
pub config: Config,
/// Debug only modal
#[cfg(debug_assertions)]
pub debug_modal: bool,
}
#[derive(Debug)]
pub struct Config {
pub pay_methods: Vec<::model::PaymentMethod>,
pub coupons: bool,
pub currency: &'static rusty_money::iso::Currency,
pub shipping: bool,
pub shipping_methods: Vec<model::ShippingMethod>,
}
impl Default for Config {
fn default() -> Self {
Self {
pay_methods: vec![],
coupons: false,
currency: rusty_money::iso::PLN,
shipping: false,
shipping_methods: vec![],
}
}
}
impl From<::model::api::Config> for Config {
fn from(
model::api::Config {
pay_methods,
coupons,
currency,
shipping,
shipping_methods,
}: model::api::Config,
) -> Self {
Self {
pay_methods,
coupons,
currency: rusty_money::iso::find(&currency).unwrap_or(rusty_money::iso::PLN),
shipping,
shipping_methods,
}
}
}
#[derive(Debug, Default)]
pub struct Products {
pub categories: Vec<model::api::Category>,
pub product_ids: Vec<model::ProductId>,
pub products: HashMap<model::ProductId, model::api::Product>,
}
impl Products {
pub fn update(&mut self, products: Vec<model::api::Product>) {
let len = products.len();
self.categories = products
.iter()
.fold(HashSet::with_capacity(len), |mut set, p| {
if let Some(category) = p.category.as_ref().cloned() {
set.insert(category);
}
set
})
.into_iter()
.collect();
self.categories.sort_by(|a, b| a.name.cmp(&b.name));
self.product_ids = products.iter().map(|p| p.id).collect();
self.products = {
let len = products.len();
products
.into_iter()
.fold(HashMap::with_capacity(len), |mut m, p| {
m.insert(p.id, p);
m
})
};
}
pub fn filter_product_ids<F>(&self, filter: F) -> Vec<model::ProductId>
where
F: Fn(&model::api::Product) -> bool,
{
self.product_ids
.iter()
.filter_map(|id| self.products.get(id).filter(|&p| filter(p)).map(|p| p.id))
.collect()
}
}