hevy 0.1.0

An async Rust client library for the Hevy public API (https://api.hevyapp.com/docs/)
Documentation
use serde::{Deserialize, Serialize};

/// A body measurement entry for a given date.
///
/// Used both as the response type for measurement endpoints and as the request
/// body for `POST /v1/body_measurements`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct BodyMeasurement {
    /// The date of the measurement (`YYYY-MM-DD`).
    pub date: String,
    /// Body weight in kilograms.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub weight_kg: Option<f64>,
    /// Lean mass in kilograms.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub lean_mass_kg: Option<f64>,
    /// Body fat percentage.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub fat_percent: Option<f64>,
    /// Neck circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub neck_cm: Option<f64>,
    /// Shoulder circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub shoulder_cm: Option<f64>,
    /// Chest circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub chest_cm: Option<f64>,
    /// Left bicep circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub left_bicep_cm: Option<f64>,
    /// Right bicep circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub right_bicep_cm: Option<f64>,
    /// Left forearm circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub left_forearm_cm: Option<f64>,
    /// Right forearm circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub right_forearm_cm: Option<f64>,
    /// Abdomen circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub abdomen: Option<f64>,
    /// Waist circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub waist: Option<f64>,
    /// Hip circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub hips: Option<f64>,
    /// Left thigh circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub left_thigh: Option<f64>,
    /// Right thigh circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub right_thigh: Option<f64>,
    /// Left calf circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub left_calf: Option<f64>,
    /// Right calf circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub right_calf: Option<f64>,
}

impl BodyMeasurement {
    /// Creates a new, otherwise-empty body measurement for the given date.
    pub fn new(date: impl Into<String>) -> Self {
        Self {
            date: date.into(),
            ..Default::default()
        }
    }
}

/// A page of [`BodyMeasurement`]s, as returned by
/// [`crate::HevyClient::list_body_measurements`].
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct BodyMeasurementsPage {
    /// The current page number.
    pub page: u32,
    /// The total number of pages available.
    pub page_count: u32,
    /// The body measurements on this page.
    #[serde(default)]
    pub body_measurements: Vec<BodyMeasurement>,
}

/// The fields accepted when updating an existing body measurement entry.
///
/// All fields are overwritten; omitted fields are set to `null` by the API.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct UpdateBodyMeasurement {
    /// Body weight in kilograms.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub weight_kg: Option<f64>,
    /// Lean mass in kilograms.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub lean_mass_kg: Option<f64>,
    /// Body fat percentage.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub fat_percent: Option<f64>,
    /// Neck circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub neck_cm: Option<f64>,
    /// Shoulder circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub shoulder_cm: Option<f64>,
    /// Chest circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub chest_cm: Option<f64>,
    /// Left bicep circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub left_bicep_cm: Option<f64>,
    /// Right bicep circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub right_bicep_cm: Option<f64>,
    /// Left forearm circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub left_forearm_cm: Option<f64>,
    /// Right forearm circumference in centimeters.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub right_forearm_cm: Option<f64>,
    /// Abdomen circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub abdomen: Option<f64>,
    /// Waist circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub waist: Option<f64>,
    /// Hip circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub hips: Option<f64>,
    /// Left thigh circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub left_thigh: Option<f64>,
    /// Right thigh circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub right_thigh: Option<f64>,
    /// Left calf circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub left_calf: Option<f64>,
    /// Right calf circumference.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub right_calf: Option<f64>,
}