recipe-ratio 0.1.2

Baker's percentages, dough hydration, and recipe scaling by flour weight.
Documentation
//! # recipe-ratio
//!
//! Baker's percentages, dough hydration, and recipe scaling by flour weight. Pure math,
//! no deps. The same ratios behind the [IngredientCalculator](https://ingredientcalculator.com/)
//! [the cups-to-grams page](https://ingredientcalculator.com/cups-to-grams/).
//!
//! ```
//! use recipe_ratio::{baker_percent, hydration, scale};
//! assert!((baker_percent(300.0, 500.0) - 60.0).abs() < 1e-9);  // 300 g water / 500 g flour
//! assert!((hydration(300.0, 500.0) - 60.0).abs() < 1e-9);
//! assert!((scale(300.0, 500.0, 1000.0) - 600.0).abs() < 1e-9); // scale water to 1 kg flour
//! ```

/// Baker's percentage for an ingredient relative to flour weight (flour = 100%).
pub fn baker_percent(ingredient_grams: f64, flour_grams: f64) -> f64 {
    if flour_grams <= 0.0 { 0.0 } else { ingredient_grams / flour_grams * 100.0 }
}

/// Dough hydration = water weight / flour weight * 100 (baker's % of water).
pub fn hydration(water_grams: f64, flour_grams: f64) -> f64 {
    baker_percent(water_grams, flour_grams)
}

/// Scale an ingredient weight when flour changes from `from_flour` to `to_flour`.
pub fn scale(ingredient_grams: f64, from_flour: f64, to_flour: f64) -> f64 {
    if from_flour <= 0.0 { 0.0 } else { ingredient_grams * (to_flour / from_flour) }
}

/// Total dough weight = sum of ingredient weights (flour + water + salt + ...).
pub fn dough_weight(ingredient_grams: &[f64]) -> f64 {
    ingredient_grams.iter().sum()
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn baker_percent_basic() { assert!((baker_percent(300.0, 500.0) - 60.0).abs() < 1e-9); }
    #[test]
    fn flour_is_100() { assert!((baker_percent(500.0, 500.0) - 100.0).abs() < 1e-9); }
    #[test]
    fn salt_typical() {
        // 10 g salt to 500 g flour = 2%
        assert!((baker_percent(10.0, 500.0) - 2.0).abs() < 1e-9);
    }
    #[test]
    fn scale_doubles() { assert!((scale(300.0, 500.0, 1000.0) - 600.0).abs() < 1e-9); }
    #[test]
    fn dough_weight_sums() { assert!((dough_weight(&[500.0, 300.0, 10.0]) - 810.0).abs() < 1e-9); }
}