diff options
Diffstat (limited to 'src/models.rs')
| -rw-r--r-- | src/models.rs | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/src/models.rs b/src/models.rs index b3f23d1..9e14b71 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,9 +1,10 @@ + use chrono::{DateTime, NaiveDate, Utc}; use serde::{Deserialize, Serialize}; -use strum::EnumIter; +use strum::{EnumIter, IntoStaticStr}; use uuid::Uuid; -#[derive(sqlx::Type, Serialize, Deserialize, EnumIter)] +#[derive(sqlx::Type, Serialize, Deserialize, EnumIter, Debug, IntoStaticStr)] #[sqlx(type_name = "metric_type")] pub enum MetricType { BodyWeight, @@ -11,7 +12,7 @@ pub enum MetricType { Waist, } -#[derive(sqlx::Type, Serialize, Deserialize, EnumIter)] +#[derive(sqlx::Type, Serialize, Deserialize, EnumIter, Debug, IntoStaticStr)] #[sqlx(type_name = "unit")] pub enum Unit { Kilogram, @@ -28,6 +29,7 @@ pub struct MeasurementView { } #[derive(Deserialize)] +#[serde(try_from = "MeasurementDataUnchecked")] pub struct MeasurementData { pub measured_at: DateTime<Utc>, pub metric_type: MetricType, @@ -36,12 +38,51 @@ pub struct MeasurementData { } #[derive(Deserialize)] +struct MeasurementDataUnchecked { + pub measured_at: DateTime<Utc>, + pub metric_type: MetricType, + pub value: f64, + pub unit: Unit, +} + +impl TryFrom<MeasurementDataUnchecked> for MeasurementData { + type Error = String; + + fn try_from(value: MeasurementDataUnchecked) -> Result<Self, Self::Error> { + if value.value < 0.0 || value.value.is_nan() { + return Err("Invalid value".to_string()); + } + match (&value.metric_type, &value.unit) { + (MetricType::BodyWeight, Unit::Kilogram) + | (MetricType::Hip, Unit::Centimeter) + | (MetricType::Waist, Unit::Centimeter) => Ok(Self { + measured_at: value.measured_at, + metric_type: value.metric_type, + value: value.value, + unit: value.unit, + }), + (metric_type, unit) => { + let metric_type: &'static str = metric_type.into(); + let unit: &'static str = unit.into(); + Err(format!("Invalid pair {}, {}", metric_type, unit)) + } + } + } +} + +#[derive(Deserialize)] pub struct DateQuery { pub date: Option<NaiveDate>, pub from: Option<NaiveDate>, pub to: Option<NaiveDate>, } +#[derive(Deserialize)] +pub struct AllQuery { + pub limit: Option<i64>, + pub reverse: Option<bool>, +} + #[cfg(test)] mod tests { use super::*; |
