use super::entities::{QuotaDefinition, TimePeriod, UsageType}; use crate::common::value_objects::DateTimeStamp; use chrono::{Datelike, NaiveDate, TimeZone, Utc}; pub struct QuotaCheckResult { pub allowed: bool, pub current_usage: u64, pub limit: u64, pub is_unlimited: bool, } pub fn check_quota( quota: &QuotaDefinition, usage_type: UsageType, current_usage: u64, requested_amount: u64, ) -> QuotaCheckResult { if !quota.is_enforced { return QuotaCheckResult { allowed: true, current_usage, limit: 0, is_unlimited: true, }; } let rule = quota.rules.iter().find(|r| r.dimension == usage_type); let Some(rule) = rule else { return QuotaCheckResult { allowed: true, current_usage, limit: 0, is_unlimited: true, }; }; if rule.is_unlimited { return QuotaCheckResult { allowed: true, current_usage, limit: 0, is_unlimited: true, }; } QuotaCheckResult { allowed: current_usage + requested_amount <= rule.limit_value, current_usage, limit: rule.limit_value, is_unlimited: false, } } pub fn period_start(period: TimePeriod) -> Option { let now = Utc::now(); match period { TimePeriod::Daily => { let start = NaiveDate::from_ymd_opt(now.year(), now.month(), now.day()) .expect("valid date") .and_hms_opt(0, 0, 0) .expect("valid time"); Some(DateTimeStamp::from_datetime(Utc.from_utc_datetime(&start))) } TimePeriod::Monthly => { let start = NaiveDate::from_ymd_opt(now.year(), now.month(), 1) .expect("valid date") .and_hms_opt(0, 0, 0) .expect("valid time"); Some(DateTimeStamp::from_datetime(Utc.from_utc_datetime(&start))) } TimePeriod::Lifetime => None, } }