use serde::{Deserialize, Serialize};
use super::common::{RepRange, SetType, flexible_f64};
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RoutineSet {
#[serde(default)]
pub index: u32,
#[serde(rename = "type", default)]
pub r#type: String,
#[serde(default)]
pub weight_kg: Option<f64>,
#[serde(default)]
pub reps: Option<f64>,
#[serde(default)]
pub rep_range: Option<RepRange>,
#[serde(default)]
pub distance_meters: Option<f64>,
#[serde(default)]
pub duration_seconds: Option<f64>,
#[serde(default)]
pub rpe: Option<f64>,
#[serde(default)]
pub custom_metric: Option<f64>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RoutineExercise {
#[serde(default)]
pub index: u32,
#[serde(default)]
pub title: String,
#[serde(default, deserialize_with = "flexible_f64")]
pub rest_seconds: Option<f64>,
#[serde(default)]
pub notes: Option<String>,
#[serde(default)]
pub exercise_template_id: String,
#[serde(default)]
pub supersets_id: Option<u32>,
#[serde(default)]
pub sets: Vec<RoutineSet>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct Routine {
pub id: String,
#[serde(default)]
pub title: String,
#[serde(default)]
pub folder_id: Option<i64>,
#[serde(default)]
pub updated_at: String,
#[serde(default)]
pub created_at: String,
#[serde(default)]
pub exercises: Vec<RoutineExercise>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RoutinesPage {
pub page: u32,
pub page_count: u32,
#[serde(default)]
pub routines: Vec<Routine>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub(crate) struct RoutineEnvelope {
pub routine: Routine,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RoutineSetInput {
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub r#type: Option<SetType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub weight_kg: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reps: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub distance_meters: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duration_seconds: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_metric: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rep_range: Option<RepRange>,
}
impl RoutineSetInput {
pub fn normal(weight_kg: f64, reps: i64) -> Self {
Self {
r#type: Some(SetType::Normal),
weight_kg: Some(weight_kg),
reps: Some(reps),
..Default::default()
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RoutineExerciseInput {
pub exercise_template_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub superset_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rest_seconds: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub notes: Option<String>,
pub sets: Vec<RoutineSetInput>,
}
impl RoutineExerciseInput {
pub fn new(exercise_template_id: impl Into<String>) -> Self {
Self {
exercise_template_id: exercise_template_id.into(),
superset_id: None,
rest_seconds: None,
notes: None,
sets: Vec::new(),
}
}
pub fn with_set(mut self, set: RoutineSetInput) -> Self {
self.sets.push(set);
self
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct NewRoutine {
pub title: String,
#[serde(default)]
pub folder_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub notes: Option<String>,
pub exercises: Vec<RoutineExerciseInput>,
}
impl NewRoutine {
pub fn new(title: impl Into<String>) -> Self {
Self {
title: title.into(),
folder_id: None,
notes: None,
exercises: Vec::new(),
}
}
pub fn with_exercise(mut self, exercise: RoutineExerciseInput) -> Self {
self.exercises.push(exercise);
self
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct CreateRoutineRequest {
pub routine: NewRoutine,
}
impl CreateRoutineRequest {
pub fn new(routine: NewRoutine) -> Self {
Self { routine }
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct UpdatedRoutine {
pub title: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub notes: Option<String>,
pub exercises: Vec<RoutineExerciseInput>,
}
impl UpdatedRoutine {
pub fn new(title: impl Into<String>) -> Self {
Self {
title: title.into(),
notes: None,
exercises: Vec::new(),
}
}
pub fn with_exercise(mut self, exercise: RoutineExerciseInput) -> Self {
self.exercises.push(exercise);
self
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct UpdateRoutineRequest {
pub routine: UpdatedRoutine,
}
impl UpdateRoutineRequest {
pub fn new(routine: UpdatedRoutine) -> Self {
Self { routine }
}
}