// @generated by jacquard-lexicon. DO NOT EDIT.
//
// Lexicon: app.fitsky.workout
//
// This file was automatically generated from Lexicon schemas.
// Any manual changes will be overwritten on the next regeneration.

#[allow(unused_imports)]
use alloc::collections::BTreeMap;

#[allow(unused_imports)]
use core::marker::PhantomData;
use jacquard_common::{CowStr, BosStr, DefaultStr, FromStaticStr};

#[allow(unused_imports)]
use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
use jacquard_common::deps::smol_str::SmolStr;
use jacquard_common::types::blob::BlobRef;
use jacquard_common::types::collection::{Collection, RecordError};
use jacquard_common::types::string::{AtUri, Cid, Datetime};
use jacquard_common::types::uri::{RecordUri, UriError};
use jacquard_common::types::value::Data;
use jacquard_common::xrpc::XrpcResp;
use jacquard_derive::{IntoStatic, lexicon, open_union};
use jacquard_lexicon::lexicon::LexiconDoc;
use jacquard_lexicon::schema::LexiconSchema;

#[allow(unused_imports)]
use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
use serde::{Serialize, Deserialize};
use crate::app_fitsky::workout;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct CardioDetails<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub calories: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cardio_zones: Option<workout::CardioZoneData<S>>,
    ///Distance in meters
    #[serde(skip_serializing_if = "Option::is_none")]
    pub distance_meters: Option<i64>,
    ///Elevation gain in meters
    #[serde(skip_serializing_if = "Option::is_none")]
    pub elevation_gain_meters: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate: Option<workout::HeartRateData<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate_samples: Option<Vec<workout::HeartRateSample<S>>>,
    ///Pace in seconds per kilometer
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pace_seconds_per_km: Option<i64>,
    ///GPS route points recorded during the workout
    #[serde(skip_serializing_if = "Option::is_none")]
    pub route_points: Option<Vec<workout::RoutePoint<S>>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub steps: Option<i64>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// Time in seconds spent in each heart rate zone

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct CardioZoneData<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub zone1_rest: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub zone2_easy: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub zone3_aerobic: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub zone4_threshold: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub zone5_max: Option<i64>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct Exercise<S: BosStr = DefaultStr> {
    pub name: S,
    pub sets: Vec<workout::ExerciseSet<S>>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct ExerciseSet<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub reps: Option<i64>,
    ///Weight in grams
    #[serde(skip_serializing_if = "Option::is_none")]
    pub weight_grams: Option<i64>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct FlexibilityDetails<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub calories: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cardio_zones: Option<workout::CardioZoneData<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate: Option<workout::HeartRateData<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate_samples: Option<Vec<workout::HeartRateSample<S>>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub intensity: Option<FlexibilityDetailsIntensity<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub movements: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub steps: Option<i64>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum FlexibilityDetailsIntensity<S: BosStr = DefaultStr> {
    Light,
    Moderate,
    Intense,
    Other(S),
}

impl<S: BosStr> FlexibilityDetailsIntensity<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Light => "light",
            Self::Moderate => "moderate",
            Self::Intense => "intense",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "light" => Self::Light,
            "moderate" => Self::Moderate,
            "intense" => Self::Intense,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for FlexibilityDetailsIntensity<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for FlexibilityDetailsIntensity<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for FlexibilityDetailsIntensity<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de>
for FlexibilityDetailsIntensity<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for FlexibilityDetailsIntensity<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for FlexibilityDetailsIntensity<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = FlexibilityDetailsIntensity<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            FlexibilityDetailsIntensity::Light => FlexibilityDetailsIntensity::Light,
            FlexibilityDetailsIntensity::Moderate => {
                FlexibilityDetailsIntensity::Moderate
            }
            FlexibilityDetailsIntensity::Intense => FlexibilityDetailsIntensity::Intense,
            FlexibilityDetailsIntensity::Other(v) => {
                FlexibilityDetailsIntensity::Other(v.into_static())
            }
        }
    }
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct HeartRateData<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avg: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub min: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub resting: Option<i64>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct HeartRateSample<S: BosStr = DefaultStr> {
    pub bpm: i64,
    pub timestamp: Datetime,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct HiitSportsDetails<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub calories: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cardio_zones: Option<workout::CardioZoneData<S>>,
    ///Distance in meters
    #[serde(skip_serializing_if = "Option::is_none")]
    pub distance_meters: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate: Option<workout::HeartRateData<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate_samples: Option<Vec<workout::HeartRateSample<S>>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub intensity: Option<HiitSportsDetailsIntensity<S>>,
    ///Pace in seconds per kilometer
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pace_seconds_per_km: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rounds: Option<i64>,
    ///GPS route points recorded during the workout
    #[serde(skip_serializing_if = "Option::is_none")]
    pub route_points: Option<Vec<workout::RoutePoint<S>>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sport: Option<S>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub steps: Option<i64>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum HiitSportsDetailsIntensity<S: BosStr = DefaultStr> {
    Light,
    Moderate,
    Intense,
    Other(S),
}

impl<S: BosStr> HiitSportsDetailsIntensity<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Light => "light",
            Self::Moderate => "moderate",
            Self::Intense => "intense",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "light" => Self::Light,
            "moderate" => Self::Moderate,
            "intense" => Self::Intense,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for HiitSportsDetailsIntensity<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for HiitSportsDetailsIntensity<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for HiitSportsDetailsIntensity<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de>
for HiitSportsDetailsIntensity<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for HiitSportsDetailsIntensity<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for HiitSportsDetailsIntensity<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = HiitSportsDetailsIntensity<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            HiitSportsDetailsIntensity::Light => HiitSportsDetailsIntensity::Light,
            HiitSportsDetailsIntensity::Moderate => HiitSportsDetailsIntensity::Moderate,
            HiitSportsDetailsIntensity::Intense => HiitSportsDetailsIntensity::Intense,
            HiitSportsDetailsIntensity::Other(v) => {
                HiitSportsDetailsIntensity::Other(v.into_static())
            }
        }
    }
}

/// A fitness workout record

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(
    rename_all = "camelCase",
    rename = "app.fitsky.workout",
    tag = "$type",
    bound(deserialize = "S: Deserialize<'de> + BosStr")
)]
pub struct Workout<S: BosStr = DefaultStr> {
    pub created_at: Datetime,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub details: Option<WorkoutDetails<S>>,
    ///Duration in seconds
    pub duration: i64,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub ended_at: Option<Datetime>,
    ///Progress milestones for linear workouts
    #[serde(skip_serializing_if = "Option::is_none")]
    pub milestones: Option<Vec<workout::Milestone<S>>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub notes: Option<S>,
    ///Open Graph preview image for social sharing
    #[serde(skip_serializing_if = "Option::is_none")]
    pub og_image: Option<BlobRef<S>>,
    ///Reference to the workoutPlan used, if any
    #[serde(skip_serializing_if = "Option::is_none")]
    pub plan_uri: Option<AtUri<S>>,
    pub started_at: Datetime,
    ///Whether the workout is in progress or finished. Omitted for legacy workouts (treat as completed).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<WorkoutStatus<S>>,
    pub title: S,
    pub r#type: WorkoutType<S>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub visibility: Option<workout::VisibilitySettings<S>>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[open_union]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub enum WorkoutDetails<S: BosStr = DefaultStr> {
    #[serde(rename = "app.fitsky.workout#cardioDetails")]
    CardioDetails(Box<workout::CardioDetails<S>>),
    #[serde(rename = "app.fitsky.workout#strengthDetails")]
    StrengthDetails(Box<workout::StrengthDetails<S>>),
    #[serde(rename = "app.fitsky.workout#flexibilityDetails")]
    FlexibilityDetails(Box<workout::FlexibilityDetails<S>>),
    #[serde(rename = "app.fitsky.workout#hiitSportsDetails")]
    HiitSportsDetails(Box<workout::HiitSportsDetails<S>>),
}

/// Whether the workout is in progress or finished. Omitted for legacy workouts (treat as completed).

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum WorkoutStatus<S: BosStr = DefaultStr> {
    Active,
    Completed,
    Other(S),
}

impl<S: BosStr> WorkoutStatus<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Active => "active",
            Self::Completed => "completed",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "active" => Self::Active,
            "completed" => Self::Completed,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for WorkoutStatus<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for WorkoutStatus<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for WorkoutStatus<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for WorkoutStatus<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for WorkoutStatus<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for WorkoutStatus<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = WorkoutStatus<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            WorkoutStatus::Active => WorkoutStatus::Active,
            WorkoutStatus::Completed => WorkoutStatus::Completed,
            WorkoutStatus::Other(v) => WorkoutStatus::Other(v.into_static()),
        }
    }
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum WorkoutType<S: BosStr = DefaultStr> {
    Running,
    Cycling,
    Swimming,
    Walking,
    Weightlifting,
    Bodyweight,
    Yoga,
    Hiit,
    Sports,
    Stretching,
    Hiking,
    Other(S),
}

impl<S: BosStr> WorkoutType<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Running => "running",
            Self::Cycling => "cycling",
            Self::Swimming => "swimming",
            Self::Walking => "walking",
            Self::Weightlifting => "weightlifting",
            Self::Bodyweight => "bodyweight",
            Self::Yoga => "yoga",
            Self::Hiit => "hiit",
            Self::Sports => "sports",
            Self::Stretching => "stretching",
            Self::Hiking => "hiking",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "running" => Self::Running,
            "cycling" => Self::Cycling,
            "swimming" => Self::Swimming,
            "walking" => Self::Walking,
            "weightlifting" => Self::Weightlifting,
            "bodyweight" => Self::Bodyweight,
            "yoga" => Self::Yoga,
            "hiit" => Self::Hiit,
            "sports" => Self::Sports,
            "stretching" => Self::Stretching,
            "hiking" => Self::Hiking,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for WorkoutType<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for WorkoutType<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for WorkoutType<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for WorkoutType<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for WorkoutType<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for WorkoutType<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = WorkoutType<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            WorkoutType::Running => WorkoutType::Running,
            WorkoutType::Cycling => WorkoutType::Cycling,
            WorkoutType::Swimming => WorkoutType::Swimming,
            WorkoutType::Walking => WorkoutType::Walking,
            WorkoutType::Weightlifting => WorkoutType::Weightlifting,
            WorkoutType::Bodyweight => WorkoutType::Bodyweight,
            WorkoutType::Yoga => WorkoutType::Yoga,
            WorkoutType::Hiit => WorkoutType::Hiit,
            WorkoutType::Sports => WorkoutType::Sports,
            WorkoutType::Stretching => WorkoutType::Stretching,
            WorkoutType::Hiking => WorkoutType::Hiking,
            WorkoutType::Other(v) => WorkoutType::Other(v.into_static()),
        }
    }
}

/// Typed wrapper for GetRecord response with this collection's record type.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct WorkoutGetRecordOutput<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cid: Option<Cid<S>>,
    pub uri: AtUri<S>,
    pub value: Workout<S>,
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct Milestone<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub note: Option<S>,
    pub timestamp: Datetime,
    pub r#type: MilestoneType<S>,
    ///Milestone value in meters
    #[serde(skip_serializing_if = "Option::is_none")]
    pub value_meters: Option<i64>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MilestoneType<S: BosStr = DefaultStr> {
    Distance,
    Lap,
    Note,
    Other(S),
}

impl<S: BosStr> MilestoneType<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Distance => "distance",
            Self::Lap => "lap",
            Self::Note => "note",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "distance" => Self::Distance,
            "lap" => Self::Lap,
            "note" => Self::Note,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for MilestoneType<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for MilestoneType<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for MilestoneType<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for MilestoneType<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for MilestoneType<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for MilestoneType<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = MilestoneType<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            MilestoneType::Distance => MilestoneType::Distance,
            MilestoneType::Lap => MilestoneType::Lap,
            MilestoneType::Note => MilestoneType::Note,
            MilestoneType::Other(v) => MilestoneType::Other(v.into_static()),
        }
    }
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct RoutePoint<S: BosStr = DefaultStr> {
    ///Latitude in microdegrees (degrees * 1,000,000)
    pub lat_e6: i64,
    ///Longitude in microdegrees (degrees * 1,000,000)
    pub lng_e6: i64,
    pub timestamp: Datetime,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct StrengthDetails<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub calories: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cardio_zones: Option<workout::CardioZoneData<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub exercises: Option<Vec<workout::Exercise<S>>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate: Option<workout::HeartRateData<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate_samples: Option<Vec<workout::HeartRateSample<S>>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub steps: Option<i64>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// Controls which fields are visible to other users in the Fitsky UI. Note: ATProto repos are public — this is UI-level privacy only.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct VisibilitySettings<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub calories: Option<VisibilitySettingsCalories<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cardio_zones: Option<VisibilitySettingsCardioZones<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub details: Option<VisibilitySettingsDetails<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub heart_rate: Option<VisibilitySettingsHeartRate<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub notes: Option<VisibilitySettingsNotes<S>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub steps: Option<VisibilitySettingsSteps<S>>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisibilitySettingsCalories<S: BosStr = DefaultStr> {
    Public,
    Private,
    Other(S),
}

impl<S: BosStr> VisibilitySettingsCalories<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Public => "public",
            Self::Private => "private",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "public" => Self::Public,
            "private" => Self::Private,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for VisibilitySettingsCalories<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for VisibilitySettingsCalories<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for VisibilitySettingsCalories<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de>
for VisibilitySettingsCalories<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for VisibilitySettingsCalories<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for VisibilitySettingsCalories<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = VisibilitySettingsCalories<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            VisibilitySettingsCalories::Public => VisibilitySettingsCalories::Public,
            VisibilitySettingsCalories::Private => VisibilitySettingsCalories::Private,
            VisibilitySettingsCalories::Other(v) => {
                VisibilitySettingsCalories::Other(v.into_static())
            }
        }
    }
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisibilitySettingsCardioZones<S: BosStr = DefaultStr> {
    Public,
    Private,
    Other(S),
}

impl<S: BosStr> VisibilitySettingsCardioZones<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Public => "public",
            Self::Private => "private",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "public" => Self::Public,
            "private" => Self::Private,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for VisibilitySettingsCardioZones<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for VisibilitySettingsCardioZones<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for VisibilitySettingsCardioZones<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de>
for VisibilitySettingsCardioZones<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for VisibilitySettingsCardioZones<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for VisibilitySettingsCardioZones<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = VisibilitySettingsCardioZones<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            VisibilitySettingsCardioZones::Public => {
                VisibilitySettingsCardioZones::Public
            }
            VisibilitySettingsCardioZones::Private => {
                VisibilitySettingsCardioZones::Private
            }
            VisibilitySettingsCardioZones::Other(v) => {
                VisibilitySettingsCardioZones::Other(v.into_static())
            }
        }
    }
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisibilitySettingsDetails<S: BosStr = DefaultStr> {
    Public,
    Private,
    Other(S),
}

impl<S: BosStr> VisibilitySettingsDetails<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Public => "public",
            Self::Private => "private",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "public" => Self::Public,
            "private" => Self::Private,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for VisibilitySettingsDetails<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for VisibilitySettingsDetails<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for VisibilitySettingsDetails<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de>
for VisibilitySettingsDetails<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for VisibilitySettingsDetails<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for VisibilitySettingsDetails<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = VisibilitySettingsDetails<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            VisibilitySettingsDetails::Public => VisibilitySettingsDetails::Public,
            VisibilitySettingsDetails::Private => VisibilitySettingsDetails::Private,
            VisibilitySettingsDetails::Other(v) => {
                VisibilitySettingsDetails::Other(v.into_static())
            }
        }
    }
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisibilitySettingsHeartRate<S: BosStr = DefaultStr> {
    Public,
    Private,
    Other(S),
}

impl<S: BosStr> VisibilitySettingsHeartRate<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Public => "public",
            Self::Private => "private",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "public" => Self::Public,
            "private" => Self::Private,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for VisibilitySettingsHeartRate<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for VisibilitySettingsHeartRate<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for VisibilitySettingsHeartRate<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de>
for VisibilitySettingsHeartRate<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for VisibilitySettingsHeartRate<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for VisibilitySettingsHeartRate<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = VisibilitySettingsHeartRate<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            VisibilitySettingsHeartRate::Public => VisibilitySettingsHeartRate::Public,
            VisibilitySettingsHeartRate::Private => VisibilitySettingsHeartRate::Private,
            VisibilitySettingsHeartRate::Other(v) => {
                VisibilitySettingsHeartRate::Other(v.into_static())
            }
        }
    }
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisibilitySettingsNotes<S: BosStr = DefaultStr> {
    Public,
    Private,
    Other(S),
}

impl<S: BosStr> VisibilitySettingsNotes<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Public => "public",
            Self::Private => "private",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "public" => Self::Public,
            "private" => Self::Private,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for VisibilitySettingsNotes<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for VisibilitySettingsNotes<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for VisibilitySettingsNotes<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for VisibilitySettingsNotes<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for VisibilitySettingsNotes<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for VisibilitySettingsNotes<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = VisibilitySettingsNotes<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            VisibilitySettingsNotes::Public => VisibilitySettingsNotes::Public,
            VisibilitySettingsNotes::Private => VisibilitySettingsNotes::Private,
            VisibilitySettingsNotes::Other(v) => {
                VisibilitySettingsNotes::Other(v.into_static())
            }
        }
    }
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisibilitySettingsSteps<S: BosStr = DefaultStr> {
    Public,
    Private,
    Other(S),
}

impl<S: BosStr> VisibilitySettingsSteps<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Public => "public",
            Self::Private => "private",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "public" => Self::Public,
            "private" => Self::Private,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for VisibilitySettingsSteps<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for VisibilitySettingsSteps<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<S: BosStr> Serialize for VisibilitySettingsSteps<S> {
    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
    where
        Ser: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for VisibilitySettingsSteps<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for VisibilitySettingsSteps<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for VisibilitySettingsSteps<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = VisibilitySettingsSteps<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            VisibilitySettingsSteps::Public => VisibilitySettingsSteps::Public,
            VisibilitySettingsSteps::Private => VisibilitySettingsSteps::Private,
            VisibilitySettingsSteps::Other(v) => {
                VisibilitySettingsSteps::Other(v.into_static())
            }
        }
    }
}

impl<S: BosStr> Workout<S> {
    pub fn uri(uri: S) -> Result<RecordUri<S, WorkoutRecord>, UriError> {
        RecordUri::try_from_uri(AtUri::new(uri)?)
    }
}

impl<S: BosStr> LexiconSchema for CardioDetails<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "cardioDetails"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.distance_meters {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("distance_meters"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        if let Some(ref value) = self.elevation_gain_meters {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("elevation_gain_meters"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        if let Some(ref value) = self.pace_seconds_per_km {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("pace_seconds_per_km"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for CardioZoneData<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "cardioZoneData"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for Exercise<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "exercise"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        {
            let value = &self.name;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 128usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("name"),
                    max: 128usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for ExerciseSet<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "exerciseSet"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.weight_grams {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("weight_grams"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for FlexibilityDetails<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "flexibilityDetails"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.intensity {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("intensity"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for HeartRateData<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "heartRateData"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for HeartRateSample<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "heartRateSample"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for HiitSportsDetails<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "hiitSportsDetails"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.distance_meters {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("distance_meters"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        if let Some(ref value) = self.intensity {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("intensity"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.pace_seconds_per_km {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("pace_seconds_per_km"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        if let Some(ref value) = self.sport {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 128usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("sport"),
                    max: 128usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

/// Marker type for deserializing records from this collection.

#[derive(Debug, Serialize, Deserialize)]
pub struct WorkoutRecord;
impl XrpcResp for WorkoutRecord {
    const NSID: &'static str = "app.fitsky.workout";
    const ENCODING: &'static str = "application/json";
    type Output<S: BosStr> = WorkoutGetRecordOutput<S>;
    type Err = RecordError;
}

impl<S: BosStr> From<WorkoutGetRecordOutput<S>> for Workout<S> {
    fn from(output: WorkoutGetRecordOutput<S>) -> Self {
        output.value
    }
}

impl<S: BosStr> Collection for Workout<S> {
    const NSID: &'static str = "app.fitsky.workout";
    type Record = WorkoutRecord;
}

impl Collection for WorkoutRecord {
    const NSID: &'static str = "app.fitsky.workout";
    type Record = WorkoutRecord;
}

impl<S: BosStr> LexiconSchema for Workout<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "main"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        {
            let value = &self.duration;
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("duration"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        if let Some(ref value) = self.notes {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 2048usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("notes"),
                    max: 2048usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.og_image {
            {
                let size = value.blob().size;
                if size > 1000000usize {
                    return Err(ConstraintError::BlobTooLarge {
                        path: ValidationPath::from_field("og_image"),
                        max: 1000000usize,
                        actual: size,
                    });
                }
            }
        }
        if let Some(ref value) = self.og_image {
            {
                let mime = value.blob().mime_type.as_str();
                let accepted: &[&str] = &["image/png", "image/jpeg", "image/webp"];
                let matched = accepted
                    .iter()
                    .any(|pattern| {
                        if *pattern == "*/*" {
                            true
                        } else if pattern.ends_with("/*") {
                            let prefix = &pattern[..pattern.len() - 2];
                            mime.starts_with(prefix)
                                && mime.as_bytes().get(prefix.len()) == Some(&b'/')
                        } else {
                            mime == *pattern
                        }
                    });
                if !matched {
                    return Err(ConstraintError::BlobMimeTypeNotAccepted {
                        path: ValidationPath::from_field("og_image"),
                        accepted: vec![
                            "image/png".to_string(), "image/jpeg".to_string(),
                            "image/webp".to_string()
                        ],
                        actual: mime.to_string(),
                    });
                }
            }
        }
        if let Some(ref value) = self.status {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("status"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        {
            let value = &self.title;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 256usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("title"),
                    max: 256usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        {
            let value = &self.r#type;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("type"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for Milestone<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "milestone"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.note {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 512usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("note"),
                    max: 512usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        {
            let value = &self.r#type;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("type"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.value_meters {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("value_meters"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for RoutePoint<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "routePoint"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for StrengthDetails<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "strengthDetails"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for VisibilitySettings<S> {
    fn nsid() -> &'static str {
        "app.fitsky.workout"
    }
    fn def_name() -> &'static str {
        "visibilitySettings"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_app_fitsky_workout()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.calories {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("calories"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.cardio_zones {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("cardio_zones"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.details {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("details"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.heart_rate {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("heart_rate"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.notes {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("notes"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.steps {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 64usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("steps"),
                    max: 64usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

fn lexicon_doc_app_fitsky_workout() -> LexiconDoc<'static> {
    #[allow(unused_imports)]
    use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
    use jacquard_lexicon::lexicon::*;
    use alloc::collections::BTreeMap;
    LexiconDoc {
        lexicon: Lexicon::Lexicon1,
        id: CowStr::new_static("app.fitsky.workout"),
        defs: {
            let mut map = BTreeMap::new();
            map.insert(
                SmolStr::new_static("cardioDetails"),
                LexUserType::Object(LexObject {
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("calories"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("cardioZones"),
                            LexObjectProperty::Ref(LexRef {
                                r#ref: CowStr::new_static("#cardioZoneData"),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("distanceMeters"),
                            LexObjectProperty::Integer(LexInteger {
                                minimum: Some(0i64),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("elevationGainMeters"),
                            LexObjectProperty::Integer(LexInteger {
                                minimum: Some(0i64),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRate"),
                            LexObjectProperty::Ref(LexRef {
                                r#ref: CowStr::new_static("#heartRateData"),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRateSamples"),
                            LexObjectProperty::Array(LexArray {
                                items: LexArrayItem::Ref(LexRef {
                                    r#ref: CowStr::new_static("#heartRateSample"),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("paceSecondsPerKm"),
                            LexObjectProperty::Integer(LexInteger {
                                minimum: Some(0i64),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("routePoints"),
                            LexObjectProperty::Array(LexArray {
                                description: Some(
                                    CowStr::new_static(
                                        "GPS route points recorded during the workout",
                                    ),
                                ),
                                items: LexArrayItem::Ref(LexRef {
                                    r#ref: CowStr::new_static("#routePoint"),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("steps"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("cardioZoneData"),
                LexUserType::Object(LexObject {
                    description: Some(
                        CowStr::new_static(
                            "Time in seconds spent in each heart rate zone",
                        ),
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("zone1Rest"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("zone2Easy"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("zone3Aerobic"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("zone4Threshold"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("zone5Max"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("exercise"),
                LexUserType::Object(LexObject {
                    required: Some(
                        vec![SmolStr::new_static("name"), SmolStr::new_static("sets")],
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("name"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(128usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("sets"),
                            LexObjectProperty::Array(LexArray {
                                items: LexArrayItem::Ref(LexRef {
                                    r#ref: CowStr::new_static("#exerciseSet"),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("exerciseSet"),
                LexUserType::Object(LexObject {
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("reps"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("weightGrams"),
                            LexObjectProperty::Integer(LexInteger {
                                minimum: Some(0i64),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("flexibilityDetails"),
                LexUserType::Object(LexObject {
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("calories"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("cardioZones"),
                            LexObjectProperty::Ref(LexRef {
                                r#ref: CowStr::new_static("#cardioZoneData"),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRate"),
                            LexObjectProperty::Ref(LexRef {
                                r#ref: CowStr::new_static("#heartRateData"),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRateSamples"),
                            LexObjectProperty::Array(LexArray {
                                items: LexArrayItem::Ref(LexRef {
                                    r#ref: CowStr::new_static("#heartRateSample"),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("intensity"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("movements"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("steps"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("heartRateData"),
                LexUserType::Object(LexObject {
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("avg"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("max"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("min"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("resting"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("heartRateSample"),
                LexUserType::Object(LexObject {
                    required: Some(
                        vec![
                            SmolStr::new_static("timestamp"), SmolStr::new_static("bpm")
                        ],
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("bpm"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("timestamp"),
                            LexObjectProperty::String(LexString {
                                format: Some(LexStringFormat::Datetime),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("hiitSportsDetails"),
                LexUserType::Object(LexObject {
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("calories"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("cardioZones"),
                            LexObjectProperty::Ref(LexRef {
                                r#ref: CowStr::new_static("#cardioZoneData"),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("distanceMeters"),
                            LexObjectProperty::Integer(LexInteger {
                                minimum: Some(0i64),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRate"),
                            LexObjectProperty::Ref(LexRef {
                                r#ref: CowStr::new_static("#heartRateData"),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRateSamples"),
                            LexObjectProperty::Array(LexArray {
                                items: LexArrayItem::Ref(LexRef {
                                    r#ref: CowStr::new_static("#heartRateSample"),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("intensity"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("paceSecondsPerKm"),
                            LexObjectProperty::Integer(LexInteger {
                                minimum: Some(0i64),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("rounds"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("routePoints"),
                            LexObjectProperty::Array(LexArray {
                                description: Some(
                                    CowStr::new_static(
                                        "GPS route points recorded during the workout",
                                    ),
                                ),
                                items: LexArrayItem::Ref(LexRef {
                                    r#ref: CowStr::new_static("#routePoint"),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("sport"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(128usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("steps"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("main"),
                LexUserType::Record(LexRecord {
                    description: Some(CowStr::new_static("A fitness workout record")),
                    key: Some(CowStr::new_static("tid")),
                    record: LexRecordRecord::Object(LexObject {
                        required: Some(
                            vec![
                                SmolStr::new_static("type"), SmolStr::new_static("title"),
                                SmolStr::new_static("startedAt"),
                                SmolStr::new_static("duration"),
                                SmolStr::new_static("createdAt")
                            ],
                        ),
                        properties: {
                            #[allow(unused_mut)]
                            let mut map = BTreeMap::new();
                            map.insert(
                                SmolStr::new_static("createdAt"),
                                LexObjectProperty::String(LexString {
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("details"),
                                LexObjectProperty::Union(LexRefUnion {
                                    refs: vec![
                                        CowStr::new_static("#cardioDetails"),
                                        CowStr::new_static("#strengthDetails"),
                                        CowStr::new_static("#flexibilityDetails"),
                                        CowStr::new_static("#hiitSportsDetails")
                                    ],
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("duration"),
                                LexObjectProperty::Integer(LexInteger {
                                    minimum: Some(0i64),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("endedAt"),
                                LexObjectProperty::String(LexString {
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("milestones"),
                                LexObjectProperty::Array(LexArray {
                                    description: Some(
                                        CowStr::new_static(
                                            "Progress milestones for linear workouts",
                                        ),
                                    ),
                                    items: LexArrayItem::Ref(LexRef {
                                        r#ref: CowStr::new_static("#milestone"),
                                        ..Default::default()
                                    }),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("notes"),
                                LexObjectProperty::String(LexString {
                                    max_length: Some(2048usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("ogImage"),
                                LexObjectProperty::Blob(LexBlob { ..Default::default() }),
                            );
                            map.insert(
                                SmolStr::new_static("planUri"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Reference to the workoutPlan used, if any",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::AtUri),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("startedAt"),
                                LexObjectProperty::String(LexString {
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("status"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Whether the workout is in progress or finished. Omitted for legacy workouts (treat as completed).",
                                        ),
                                    ),
                                    max_length: Some(64usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("title"),
                                LexObjectProperty::String(LexString {
                                    max_length: Some(256usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("type"),
                                LexObjectProperty::String(LexString {
                                    max_length: Some(64usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("visibility"),
                                LexObjectProperty::Ref(LexRef {
                                    r#ref: CowStr::new_static("#visibilitySettings"),
                                    ..Default::default()
                                }),
                            );
                            map
                        },
                        ..Default::default()
                    }),
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("milestone"),
                LexUserType::Object(LexObject {
                    required: Some(
                        vec![
                            SmolStr::new_static("type"), SmolStr::new_static("timestamp")
                        ],
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("note"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(512usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("timestamp"),
                            LexObjectProperty::String(LexString {
                                format: Some(LexStringFormat::Datetime),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("type"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("valueMeters"),
                            LexObjectProperty::Integer(LexInteger {
                                minimum: Some(0i64),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("routePoint"),
                LexUserType::Object(LexObject {
                    required: Some(
                        vec![
                            SmolStr::new_static("latE6"), SmolStr::new_static("lngE6"),
                            SmolStr::new_static("timestamp")
                        ],
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("latE6"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("lngE6"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("timestamp"),
                            LexObjectProperty::String(LexString {
                                format: Some(LexStringFormat::Datetime),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("strengthDetails"),
                LexUserType::Object(LexObject {
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("calories"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("cardioZones"),
                            LexObjectProperty::Ref(LexRef {
                                r#ref: CowStr::new_static("#cardioZoneData"),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("exercises"),
                            LexObjectProperty::Array(LexArray {
                                items: LexArrayItem::Ref(LexRef {
                                    r#ref: CowStr::new_static("#exercise"),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRate"),
                            LexObjectProperty::Ref(LexRef {
                                r#ref: CowStr::new_static("#heartRateData"),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRateSamples"),
                            LexObjectProperty::Array(LexArray {
                                items: LexArrayItem::Ref(LexRef {
                                    r#ref: CowStr::new_static("#heartRateSample"),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("steps"),
                            LexObjectProperty::Integer(LexInteger {
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("visibilitySettings"),
                LexUserType::Object(LexObject {
                    description: Some(
                        CowStr::new_static(
                            "Controls which fields are visible to other users in the Fitsky UI. Note: ATProto repos are public — this is UI-level privacy only.",
                        ),
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("calories"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("cardioZones"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("details"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("heartRate"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("notes"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("steps"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map
        },
        ..Default::default()
    }
}

pub mod exercise_state {

    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
    #[allow(unused)]
    use ::core::marker::PhantomData;
    mod sealed {
        pub trait Sealed {}
    }
    /// State trait tracking which required fields have been set
    pub trait State: sealed::Sealed {
        type Name;
        type Sets;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type Name = Unset;
        type Sets = Unset;
    }
    ///State transition - sets the `name` field to Set
    pub struct SetName<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetName<St> {}
    impl<St: State> State for SetName<St> {
        type Name = Set<members::name>;
        type Sets = St::Sets;
    }
    ///State transition - sets the `sets` field to Set
    pub struct SetSets<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetSets<St> {}
    impl<St: State> State for SetSets<St> {
        type Name = St::Name;
        type Sets = Set<members::sets>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `name` field
        pub struct name(());
        ///Marker type for the `sets` field
        pub struct sets(());
    }
}

/// Builder for constructing an instance of this type.
pub struct ExerciseBuilder<St: exercise_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (Option<S>, Option<Vec<workout::ExerciseSet<S>>>),
    _type: PhantomData<fn() -> S>,
}

impl Exercise<DefaultStr> {
    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
    pub fn new() -> ExerciseBuilder<exercise_state::Empty, DefaultStr> {
        ExerciseBuilder::new()
    }
}

impl<S: BosStr> Exercise<S> {
    /// Create a new builder for this type
    pub fn builder() -> ExerciseBuilder<exercise_state::Empty, S> {
        ExerciseBuilder::builder()
    }
}

impl ExerciseBuilder<exercise_state::Empty, DefaultStr> {
    /// Create a new builder with all fields unset, using the default string type, if needed
    pub fn new() -> Self {
        ExerciseBuilder {
            _state: PhantomData,
            _fields: (None, None),
            _type: PhantomData,
        }
    }
}

impl<S: BosStr> ExerciseBuilder<exercise_state::Empty, S> {
    /// Create a new builder with all fields unset
    pub fn builder() -> Self {
        ExerciseBuilder {
            _state: PhantomData,
            _fields: (None, None),
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> ExerciseBuilder<St, S>
where
    St: exercise_state::State,
    St::Name: exercise_state::IsUnset,
{
    /// Set the `name` field (required)
    pub fn name(
        mut self,
        value: impl Into<S>,
    ) -> ExerciseBuilder<exercise_state::SetName<St>, S> {
        self._fields.0 = Option::Some(value.into());
        ExerciseBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> ExerciseBuilder<St, S>
where
    St: exercise_state::State,
    St::Sets: exercise_state::IsUnset,
{
    /// Set the `sets` field (required)
    pub fn sets(
        mut self,
        value: impl Into<Vec<workout::ExerciseSet<S>>>,
    ) -> ExerciseBuilder<exercise_state::SetSets<St>, S> {
        self._fields.1 = Option::Some(value.into());
        ExerciseBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> ExerciseBuilder<St, S>
where
    St: exercise_state::State,
    St::Name: exercise_state::IsSet,
    St::Sets: exercise_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> Exercise<S> {
        Exercise {
            name: self._fields.0.unwrap(),
            sets: self._fields.1.unwrap(),
            extra_data: Default::default(),
        }
    }
    /// Build the final struct with custom extra_data.
    pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Exercise<S> {
        Exercise {
            name: self._fields.0.unwrap(),
            sets: self._fields.1.unwrap(),
            extra_data: Some(extra_data),
        }
    }
}

pub mod heart_rate_sample_state {

    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
    #[allow(unused)]
    use ::core::marker::PhantomData;
    mod sealed {
        pub trait Sealed {}
    }
    /// State trait tracking which required fields have been set
    pub trait State: sealed::Sealed {
        type Bpm;
        type Timestamp;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type Bpm = Unset;
        type Timestamp = Unset;
    }
    ///State transition - sets the `bpm` field to Set
    pub struct SetBpm<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetBpm<St> {}
    impl<St: State> State for SetBpm<St> {
        type Bpm = Set<members::bpm>;
        type Timestamp = St::Timestamp;
    }
    ///State transition - sets the `timestamp` field to Set
    pub struct SetTimestamp<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetTimestamp<St> {}
    impl<St: State> State for SetTimestamp<St> {
        type Bpm = St::Bpm;
        type Timestamp = Set<members::timestamp>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `bpm` field
        pub struct bpm(());
        ///Marker type for the `timestamp` field
        pub struct timestamp(());
    }
}

/// Builder for constructing an instance of this type.
pub struct HeartRateSampleBuilder<
    St: heart_rate_sample_state::State,
    S: BosStr = DefaultStr,
> {
    _state: PhantomData<fn() -> St>,
    _fields: (Option<i64>, Option<Datetime>),
    _type: PhantomData<fn() -> S>,
}

impl HeartRateSample<DefaultStr> {
    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
    pub fn new() -> HeartRateSampleBuilder<heart_rate_sample_state::Empty, DefaultStr> {
        HeartRateSampleBuilder::new()
    }
}

impl<S: BosStr> HeartRateSample<S> {
    /// Create a new builder for this type
    pub fn builder() -> HeartRateSampleBuilder<heart_rate_sample_state::Empty, S> {
        HeartRateSampleBuilder::builder()
    }
}

impl HeartRateSampleBuilder<heart_rate_sample_state::Empty, DefaultStr> {
    /// Create a new builder with all fields unset, using the default string type, if needed
    pub fn new() -> Self {
        HeartRateSampleBuilder {
            _state: PhantomData,
            _fields: (None, None),
            _type: PhantomData,
        }
    }
}

impl<S: BosStr> HeartRateSampleBuilder<heart_rate_sample_state::Empty, S> {
    /// Create a new builder with all fields unset
    pub fn builder() -> Self {
        HeartRateSampleBuilder {
            _state: PhantomData,
            _fields: (None, None),
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> HeartRateSampleBuilder<St, S>
where
    St: heart_rate_sample_state::State,
    St::Bpm: heart_rate_sample_state::IsUnset,
{
    /// Set the `bpm` field (required)
    pub fn bpm(
        mut self,
        value: impl Into<i64>,
    ) -> HeartRateSampleBuilder<heart_rate_sample_state::SetBpm<St>, S> {
        self._fields.0 = Option::Some(value.into());
        HeartRateSampleBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> HeartRateSampleBuilder<St, S>
where
    St: heart_rate_sample_state::State,
    St::Timestamp: heart_rate_sample_state::IsUnset,
{
    /// Set the `timestamp` field (required)
    pub fn timestamp(
        mut self,
        value: impl Into<Datetime>,
    ) -> HeartRateSampleBuilder<heart_rate_sample_state::SetTimestamp<St>, S> {
        self._fields.1 = Option::Some(value.into());
        HeartRateSampleBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> HeartRateSampleBuilder<St, S>
where
    St: heart_rate_sample_state::State,
    St::Bpm: heart_rate_sample_state::IsSet,
    St::Timestamp: heart_rate_sample_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> HeartRateSample<S> {
        HeartRateSample {
            bpm: self._fields.0.unwrap(),
            timestamp: self._fields.1.unwrap(),
            extra_data: Default::default(),
        }
    }
    /// Build the final struct with custom extra_data.
    pub fn build_with_data(
        self,
        extra_data: BTreeMap<SmolStr, Data<S>>,
    ) -> HeartRateSample<S> {
        HeartRateSample {
            bpm: self._fields.0.unwrap(),
            timestamp: self._fields.1.unwrap(),
            extra_data: Some(extra_data),
        }
    }
}

pub mod workout_state {

    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
    #[allow(unused)]
    use ::core::marker::PhantomData;
    mod sealed {
        pub trait Sealed {}
    }
    /// State trait tracking which required fields have been set
    pub trait State: sealed::Sealed {
        type CreatedAt;
        type Duration;
        type StartedAt;
        type Title;
        type Type;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type CreatedAt = Unset;
        type Duration = Unset;
        type StartedAt = Unset;
        type Title = Unset;
        type Type = Unset;
    }
    ///State transition - sets the `created_at` field to Set
    pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetCreatedAt<St> {}
    impl<St: State> State for SetCreatedAt<St> {
        type CreatedAt = Set<members::created_at>;
        type Duration = St::Duration;
        type StartedAt = St::StartedAt;
        type Title = St::Title;
        type Type = St::Type;
    }
    ///State transition - sets the `duration` field to Set
    pub struct SetDuration<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetDuration<St> {}
    impl<St: State> State for SetDuration<St> {
        type CreatedAt = St::CreatedAt;
        type Duration = Set<members::duration>;
        type StartedAt = St::StartedAt;
        type Title = St::Title;
        type Type = St::Type;
    }
    ///State transition - sets the `started_at` field to Set
    pub struct SetStartedAt<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetStartedAt<St> {}
    impl<St: State> State for SetStartedAt<St> {
        type CreatedAt = St::CreatedAt;
        type Duration = St::Duration;
        type StartedAt = Set<members::started_at>;
        type Title = St::Title;
        type Type = St::Type;
    }
    ///State transition - sets the `title` field to Set
    pub struct SetTitle<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetTitle<St> {}
    impl<St: State> State for SetTitle<St> {
        type CreatedAt = St::CreatedAt;
        type Duration = St::Duration;
        type StartedAt = St::StartedAt;
        type Title = Set<members::title>;
        type Type = St::Type;
    }
    ///State transition - sets the `type` field to Set
    pub struct SetType<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetType<St> {}
    impl<St: State> State for SetType<St> {
        type CreatedAt = St::CreatedAt;
        type Duration = St::Duration;
        type StartedAt = St::StartedAt;
        type Title = St::Title;
        type Type = Set<members::r#type>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `created_at` field
        pub struct created_at(());
        ///Marker type for the `duration` field
        pub struct duration(());
        ///Marker type for the `started_at` field
        pub struct started_at(());
        ///Marker type for the `title` field
        pub struct title(());
        ///Marker type for the `type` field
        pub struct r#type(());
    }
}

/// Builder for constructing an instance of this type.
pub struct WorkoutBuilder<St: workout_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (
        Option<Datetime>,
        Option<WorkoutDetails<S>>,
        Option<i64>,
        Option<Datetime>,
        Option<Vec<workout::Milestone<S>>>,
        Option<S>,
        Option<BlobRef<S>>,
        Option<AtUri<S>>,
        Option<Datetime>,
        Option<WorkoutStatus<S>>,
        Option<S>,
        Option<WorkoutType<S>>,
        Option<workout::VisibilitySettings<S>>,
    ),
    _type: PhantomData<fn() -> S>,
}

impl Workout<DefaultStr> {
    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
    pub fn new() -> WorkoutBuilder<workout_state::Empty, DefaultStr> {
        WorkoutBuilder::new()
    }
}

impl<S: BosStr> Workout<S> {
    /// Create a new builder for this type
    pub fn builder() -> WorkoutBuilder<workout_state::Empty, S> {
        WorkoutBuilder::builder()
    }
}

impl WorkoutBuilder<workout_state::Empty, DefaultStr> {
    /// Create a new builder with all fields unset, using the default string type, if needed
    pub fn new() -> Self {
        WorkoutBuilder {
            _state: PhantomData,
            _fields: (
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
            ),
            _type: PhantomData,
        }
    }
}

impl<S: BosStr> WorkoutBuilder<workout_state::Empty, S> {
    /// Create a new builder with all fields unset
    pub fn builder() -> Self {
        WorkoutBuilder {
            _state: PhantomData,
            _fields: (
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
            ),
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> WorkoutBuilder<St, S>
where
    St: workout_state::State,
    St::CreatedAt: workout_state::IsUnset,
{
    /// Set the `createdAt` field (required)
    pub fn created_at(
        mut self,
        value: impl Into<Datetime>,
    ) -> WorkoutBuilder<workout_state::SetCreatedAt<St>, S> {
        self._fields.0 = Option::Some(value.into());
        WorkoutBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: workout_state::State, S: BosStr> WorkoutBuilder<St, S> {
    /// Set the `details` field (optional)
    pub fn details(mut self, value: impl Into<Option<WorkoutDetails<S>>>) -> Self {
        self._fields.1 = value.into();
        self
    }
    /// Set the `details` field to an Option value (optional)
    pub fn maybe_details(mut self, value: Option<WorkoutDetails<S>>) -> Self {
        self._fields.1 = value;
        self
    }
}

impl<St, S: BosStr> WorkoutBuilder<St, S>
where
    St: workout_state::State,
    St::Duration: workout_state::IsUnset,
{
    /// Set the `duration` field (required)
    pub fn duration(
        mut self,
        value: impl Into<i64>,
    ) -> WorkoutBuilder<workout_state::SetDuration<St>, S> {
        self._fields.2 = Option::Some(value.into());
        WorkoutBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: workout_state::State, S: BosStr> WorkoutBuilder<St, S> {
    /// Set the `endedAt` field (optional)
    pub fn ended_at(mut self, value: impl Into<Option<Datetime>>) -> Self {
        self._fields.3 = value.into();
        self
    }
    /// Set the `endedAt` field to an Option value (optional)
    pub fn maybe_ended_at(mut self, value: Option<Datetime>) -> Self {
        self._fields.3 = value;
        self
    }
}

impl<St: workout_state::State, S: BosStr> WorkoutBuilder<St, S> {
    /// Set the `milestones` field (optional)
    pub fn milestones(
        mut self,
        value: impl Into<Option<Vec<workout::Milestone<S>>>>,
    ) -> Self {
        self._fields.4 = value.into();
        self
    }
    /// Set the `milestones` field to an Option value (optional)
    pub fn maybe_milestones(
        mut self,
        value: Option<Vec<workout::Milestone<S>>>,
    ) -> Self {
        self._fields.4 = value;
        self
    }
}

impl<St: workout_state::State, S: BosStr> WorkoutBuilder<St, S> {
    /// Set the `notes` field (optional)
    pub fn notes(mut self, value: impl Into<Option<S>>) -> Self {
        self._fields.5 = value.into();
        self
    }
    /// Set the `notes` field to an Option value (optional)
    pub fn maybe_notes(mut self, value: Option<S>) -> Self {
        self._fields.5 = value;
        self
    }
}

impl<St: workout_state::State, S: BosStr> WorkoutBuilder<St, S> {
    /// Set the `ogImage` field (optional)
    pub fn og_image(mut self, value: impl Into<Option<BlobRef<S>>>) -> Self {
        self._fields.6 = value.into();
        self
    }
    /// Set the `ogImage` field to an Option value (optional)
    pub fn maybe_og_image(mut self, value: Option<BlobRef<S>>) -> Self {
        self._fields.6 = value;
        self
    }
}

impl<St: workout_state::State, S: BosStr> WorkoutBuilder<St, S> {
    /// Set the `planUri` field (optional)
    pub fn plan_uri(mut self, value: impl Into<Option<AtUri<S>>>) -> Self {
        self._fields.7 = value.into();
        self
    }
    /// Set the `planUri` field to an Option value (optional)
    pub fn maybe_plan_uri(mut self, value: Option<AtUri<S>>) -> Self {
        self._fields.7 = value;
        self
    }
}

impl<St, S: BosStr> WorkoutBuilder<St, S>
where
    St: workout_state::State,
    St::StartedAt: workout_state::IsUnset,
{
    /// Set the `startedAt` field (required)
    pub fn started_at(
        mut self,
        value: impl Into<Datetime>,
    ) -> WorkoutBuilder<workout_state::SetStartedAt<St>, S> {
        self._fields.8 = Option::Some(value.into());
        WorkoutBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: workout_state::State, S: BosStr> WorkoutBuilder<St, S> {
    /// Set the `status` field (optional)
    pub fn status(mut self, value: impl Into<Option<WorkoutStatus<S>>>) -> Self {
        self._fields.9 = value.into();
        self
    }
    /// Set the `status` field to an Option value (optional)
    pub fn maybe_status(mut self, value: Option<WorkoutStatus<S>>) -> Self {
        self._fields.9 = value;
        self
    }
}

impl<St, S: BosStr> WorkoutBuilder<St, S>
where
    St: workout_state::State,
    St::Title: workout_state::IsUnset,
{
    /// Set the `title` field (required)
    pub fn title(
        mut self,
        value: impl Into<S>,
    ) -> WorkoutBuilder<workout_state::SetTitle<St>, S> {
        self._fields.10 = Option::Some(value.into());
        WorkoutBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> WorkoutBuilder<St, S>
where
    St: workout_state::State,
    St::Type: workout_state::IsUnset,
{
    /// Set the `type` field (required)
    pub fn r#type(
        mut self,
        value: impl Into<WorkoutType<S>>,
    ) -> WorkoutBuilder<workout_state::SetType<St>, S> {
        self._fields.11 = Option::Some(value.into());
        WorkoutBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: workout_state::State, S: BosStr> WorkoutBuilder<St, S> {
    /// Set the `visibility` field (optional)
    pub fn visibility(
        mut self,
        value: impl Into<Option<workout::VisibilitySettings<S>>>,
    ) -> Self {
        self._fields.12 = value.into();
        self
    }
    /// Set the `visibility` field to an Option value (optional)
    pub fn maybe_visibility(
        mut self,
        value: Option<workout::VisibilitySettings<S>>,
    ) -> Self {
        self._fields.12 = value;
        self
    }
}

impl<St, S: BosStr> WorkoutBuilder<St, S>
where
    St: workout_state::State,
    St::CreatedAt: workout_state::IsSet,
    St::Duration: workout_state::IsSet,
    St::StartedAt: workout_state::IsSet,
    St::Title: workout_state::IsSet,
    St::Type: workout_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> Workout<S> {
        Workout {
            created_at: self._fields.0.unwrap(),
            details: self._fields.1,
            duration: self._fields.2.unwrap(),
            ended_at: self._fields.3,
            milestones: self._fields.4,
            notes: self._fields.5,
            og_image: self._fields.6,
            plan_uri: self._fields.7,
            started_at: self._fields.8.unwrap(),
            status: self._fields.9,
            title: self._fields.10.unwrap(),
            r#type: self._fields.11.unwrap(),
            visibility: self._fields.12,
            extra_data: Default::default(),
        }
    }
    /// Build the final struct with custom extra_data.
    pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Workout<S> {
        Workout {
            created_at: self._fields.0.unwrap(),
            details: self._fields.1,
            duration: self._fields.2.unwrap(),
            ended_at: self._fields.3,
            milestones: self._fields.4,
            notes: self._fields.5,
            og_image: self._fields.6,
            plan_uri: self._fields.7,
            started_at: self._fields.8.unwrap(),
            status: self._fields.9,
            title: self._fields.10.unwrap(),
            r#type: self._fields.11.unwrap(),
            visibility: self._fields.12,
            extra_data: Some(extra_data),
        }
    }
}

pub mod milestone_state {

    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
    #[allow(unused)]
    use ::core::marker::PhantomData;
    mod sealed {
        pub trait Sealed {}
    }
    /// State trait tracking which required fields have been set
    pub trait State: sealed::Sealed {
        type Timestamp;
        type Type;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type Timestamp = Unset;
        type Type = Unset;
    }
    ///State transition - sets the `timestamp` field to Set
    pub struct SetTimestamp<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetTimestamp<St> {}
    impl<St: State> State for SetTimestamp<St> {
        type Timestamp = Set<members::timestamp>;
        type Type = St::Type;
    }
    ///State transition - sets the `type` field to Set
    pub struct SetType<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetType<St> {}
    impl<St: State> State for SetType<St> {
        type Timestamp = St::Timestamp;
        type Type = Set<members::r#type>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `timestamp` field
        pub struct timestamp(());
        ///Marker type for the `type` field
        pub struct r#type(());
    }
}

/// Builder for constructing an instance of this type.
pub struct MilestoneBuilder<St: milestone_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (Option<S>, Option<Datetime>, Option<MilestoneType<S>>, Option<i64>),
    _type: PhantomData<fn() -> S>,
}

impl Milestone<DefaultStr> {
    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
    pub fn new() -> MilestoneBuilder<milestone_state::Empty, DefaultStr> {
        MilestoneBuilder::new()
    }
}

impl<S: BosStr> Milestone<S> {
    /// Create a new builder for this type
    pub fn builder() -> MilestoneBuilder<milestone_state::Empty, S> {
        MilestoneBuilder::builder()
    }
}

impl MilestoneBuilder<milestone_state::Empty, DefaultStr> {
    /// Create a new builder with all fields unset, using the default string type, if needed
    pub fn new() -> Self {
        MilestoneBuilder {
            _state: PhantomData,
            _fields: (None, None, None, None),
            _type: PhantomData,
        }
    }
}

impl<S: BosStr> MilestoneBuilder<milestone_state::Empty, S> {
    /// Create a new builder with all fields unset
    pub fn builder() -> Self {
        MilestoneBuilder {
            _state: PhantomData,
            _fields: (None, None, None, None),
            _type: PhantomData,
        }
    }
}

impl<St: milestone_state::State, S: BosStr> MilestoneBuilder<St, S> {
    /// Set the `note` field (optional)
    pub fn note(mut self, value: impl Into<Option<S>>) -> Self {
        self._fields.0 = value.into();
        self
    }
    /// Set the `note` field to an Option value (optional)
    pub fn maybe_note(mut self, value: Option<S>) -> Self {
        self._fields.0 = value;
        self
    }
}

impl<St, S: BosStr> MilestoneBuilder<St, S>
where
    St: milestone_state::State,
    St::Timestamp: milestone_state::IsUnset,
{
    /// Set the `timestamp` field (required)
    pub fn timestamp(
        mut self,
        value: impl Into<Datetime>,
    ) -> MilestoneBuilder<milestone_state::SetTimestamp<St>, S> {
        self._fields.1 = Option::Some(value.into());
        MilestoneBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> MilestoneBuilder<St, S>
where
    St: milestone_state::State,
    St::Type: milestone_state::IsUnset,
{
    /// Set the `type` field (required)
    pub fn r#type(
        mut self,
        value: impl Into<MilestoneType<S>>,
    ) -> MilestoneBuilder<milestone_state::SetType<St>, S> {
        self._fields.2 = Option::Some(value.into());
        MilestoneBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: milestone_state::State, S: BosStr> MilestoneBuilder<St, S> {
    /// Set the `valueMeters` field (optional)
    pub fn value_meters(mut self, value: impl Into<Option<i64>>) -> Self {
        self._fields.3 = value.into();
        self
    }
    /// Set the `valueMeters` field to an Option value (optional)
    pub fn maybe_value_meters(mut self, value: Option<i64>) -> Self {
        self._fields.3 = value;
        self
    }
}

impl<St, S: BosStr> MilestoneBuilder<St, S>
where
    St: milestone_state::State,
    St::Timestamp: milestone_state::IsSet,
    St::Type: milestone_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> Milestone<S> {
        Milestone {
            note: self._fields.0,
            timestamp: self._fields.1.unwrap(),
            r#type: self._fields.2.unwrap(),
            value_meters: self._fields.3,
            extra_data: Default::default(),
        }
    }
    /// Build the final struct with custom extra_data.
    pub fn build_with_data(
        self,
        extra_data: BTreeMap<SmolStr, Data<S>>,
    ) -> Milestone<S> {
        Milestone {
            note: self._fields.0,
            timestamp: self._fields.1.unwrap(),
            r#type: self._fields.2.unwrap(),
            value_meters: self._fields.3,
            extra_data: Some(extra_data),
        }
    }
}

pub mod route_point_state {

    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
    #[allow(unused)]
    use ::core::marker::PhantomData;
    mod sealed {
        pub trait Sealed {}
    }
    /// State trait tracking which required fields have been set
    pub trait State: sealed::Sealed {
        type LatE6;
        type LngE6;
        type Timestamp;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type LatE6 = Unset;
        type LngE6 = Unset;
        type Timestamp = Unset;
    }
    ///State transition - sets the `lat_e6` field to Set
    pub struct SetLatE6<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetLatE6<St> {}
    impl<St: State> State for SetLatE6<St> {
        type LatE6 = Set<members::lat_e6>;
        type LngE6 = St::LngE6;
        type Timestamp = St::Timestamp;
    }
    ///State transition - sets the `lng_e6` field to Set
    pub struct SetLngE6<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetLngE6<St> {}
    impl<St: State> State for SetLngE6<St> {
        type LatE6 = St::LatE6;
        type LngE6 = Set<members::lng_e6>;
        type Timestamp = St::Timestamp;
    }
    ///State transition - sets the `timestamp` field to Set
    pub struct SetTimestamp<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetTimestamp<St> {}
    impl<St: State> State for SetTimestamp<St> {
        type LatE6 = St::LatE6;
        type LngE6 = St::LngE6;
        type Timestamp = Set<members::timestamp>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `lat_e6` field
        pub struct lat_e6(());
        ///Marker type for the `lng_e6` field
        pub struct lng_e6(());
        ///Marker type for the `timestamp` field
        pub struct timestamp(());
    }
}

/// Builder for constructing an instance of this type.
pub struct RoutePointBuilder<St: route_point_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (Option<i64>, Option<i64>, Option<Datetime>),
    _type: PhantomData<fn() -> S>,
}

impl RoutePoint<DefaultStr> {
    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
    pub fn new() -> RoutePointBuilder<route_point_state::Empty, DefaultStr> {
        RoutePointBuilder::new()
    }
}

impl<S: BosStr> RoutePoint<S> {
    /// Create a new builder for this type
    pub fn builder() -> RoutePointBuilder<route_point_state::Empty, S> {
        RoutePointBuilder::builder()
    }
}

impl RoutePointBuilder<route_point_state::Empty, DefaultStr> {
    /// Create a new builder with all fields unset, using the default string type, if needed
    pub fn new() -> Self {
        RoutePointBuilder {
            _state: PhantomData,
            _fields: (None, None, None),
            _type: PhantomData,
        }
    }
}

impl<S: BosStr> RoutePointBuilder<route_point_state::Empty, S> {
    /// Create a new builder with all fields unset
    pub fn builder() -> Self {
        RoutePointBuilder {
            _state: PhantomData,
            _fields: (None, None, None),
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> RoutePointBuilder<St, S>
where
    St: route_point_state::State,
    St::LatE6: route_point_state::IsUnset,
{
    /// Set the `latE6` field (required)
    pub fn lat_e6(
        mut self,
        value: impl Into<i64>,
    ) -> RoutePointBuilder<route_point_state::SetLatE6<St>, S> {
        self._fields.0 = Option::Some(value.into());
        RoutePointBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> RoutePointBuilder<St, S>
where
    St: route_point_state::State,
    St::LngE6: route_point_state::IsUnset,
{
    /// Set the `lngE6` field (required)
    pub fn lng_e6(
        mut self,
        value: impl Into<i64>,
    ) -> RoutePointBuilder<route_point_state::SetLngE6<St>, S> {
        self._fields.1 = Option::Some(value.into());
        RoutePointBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> RoutePointBuilder<St, S>
where
    St: route_point_state::State,
    St::Timestamp: route_point_state::IsUnset,
{
    /// Set the `timestamp` field (required)
    pub fn timestamp(
        mut self,
        value: impl Into<Datetime>,
    ) -> RoutePointBuilder<route_point_state::SetTimestamp<St>, S> {
        self._fields.2 = Option::Some(value.into());
        RoutePointBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> RoutePointBuilder<St, S>
where
    St: route_point_state::State,
    St::LatE6: route_point_state::IsSet,
    St::LngE6: route_point_state::IsSet,
    St::Timestamp: route_point_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> RoutePoint<S> {
        RoutePoint {
            lat_e6: self._fields.0.unwrap(),
            lng_e6: self._fields.1.unwrap(),
            timestamp: self._fields.2.unwrap(),
            extra_data: Default::default(),
        }
    }
    /// Build the final struct with custom extra_data.
    pub fn build_with_data(
        self,
        extra_data: BTreeMap<SmolStr, Data<S>>,
    ) -> RoutePoint<S> {
        RoutePoint {
            lat_e6: self._fields.0.unwrap(),
            lng_e6: self._fields.1.unwrap(),
            timestamp: self._fields.2.unwrap(),
            extra_data: Some(extra_data),
        }
    }
}