use std::collections::{BTreeMap, BTreeSet};
use crate::{
features::FeatureId,
modules::ModuleId,
tariffs::{QuotaType, TariffId, TariffModuleResource},
utils::ExampleData,
};
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "redis",
derive(redis_args::ToRedisArgs, redis_args::FromRedisValue)
)]
#[cfg_attr(feature = "redis", to_redis_args(serde), from_redis_value(serde))]
#[cfg_attr(
feature = "utoipa",
derive(utoipa::ToSchema),
schema(example = json!(TariffResource::example_data())),
)]
pub struct TariffResource {
pub id: TariffId,
pub name: String,
pub quotas: BTreeMap<QuotaType, u64>,
pub modules: BTreeMap<ModuleId, TariffModuleResource>,
}
impl TariffResource {
pub fn has_feature_enabled(&self, module: &ModuleId, feature: &FeatureId) -> bool {
self.modules
.get(module)
.map(|m| m.has_feature_enabled(feature))
.unwrap_or_default()
}
pub fn module_features(&self, module: &ModuleId) -> Option<&BTreeSet<FeatureId>> {
self.modules.get(module).map(|m| &m.features)
}
pub fn quota(&self, quota: &QuotaType) -> Option<u64> {
self.quotas.get(quota).copied()
}
}
impl ExampleData for TariffResource {
fn example_data() -> Self {
Self {
id: TariffId::nil(),
name: "Starter tariff".to_string(),
quotas: BTreeMap::from_iter([(QuotaType::MaxStorage, 50000)]),
modules: [
("core", TariffModuleResource::default()),
("livekit", TariffModuleResource::default()),
(
"recording",
TariffModuleResource {
features: BTreeSet::from_iter(["record"
.parse()
.expect("valid feature id")]),
},
),
("chat", TariffModuleResource::default()),
("moderation", TariffModuleResource::default()),
]
.into_iter()
.map(|(module, resource)| {
(
module.parse::<ModuleId>().expect("valid module id"),
resource,
)
})
.collect(),
}
}
}
#[cfg(all(test, feature = "serde"))]
mod serde_tests {
use pretty_assertions::assert_eq;
use super::*;
#[test]
fn tariff_resource() {
use serde_json::json;
let expected = json!({
"id": "00000000-0000-0000-0000-000000000000",
"name": "tariff name",
"quotas": {
"max_storage": 11,
"room_time_limit_secs": 12,
"room_participant_limit": 13,
},
"modules": {
"mod_a": {
"features": ["feat_a"],
},
},
});
let produced = serde_json::to_value(TariffResource {
id: TariffId::nil(),
name: "tariff name".to_string(),
quotas: BTreeMap::from([
(QuotaType::MaxStorage, 11u64),
(QuotaType::RoomTimeLimitSecs, 12u64),
(QuotaType::RoomParticipantLimit, 13u64),
]),
modules: [(
"mod_a",
TariffModuleResource {
features: BTreeSet::from(["feat_a".parse().expect("valid feature id")]),
},
)]
.into_iter()
.map(|(module, resource)| {
(
module.parse::<ModuleId>().expect("valid module id"),
resource,
)
})
.collect(),
})
.unwrap();
assert_eq!(expected, produced);
}
}