gold-melt-value 0.1.0

Compute precious-metal melt value by karat, weight, and live spot price (gold, silver).
Documentation
//! # gold-melt-value
//!
//! Compute precious-metal **melt value** from karat (purity), weight, and a live
//! spot price. Pure, dependency-free math — the same engine behind the
//! [GoldGramPrice](https://goldgramprice.com/) live gold calculator.
//!
//! ## Quick example
//! ```
//! use gold_melt_value::{melt_value_grams, purity};
//!
//! let spot_per_oz = 3983.30;          // USD per troy ounce
//! let grams = 10.0;                    // a 10 g chain
//! let karat = 14;
//!
//! let usd = melt_value_grams(grams, karat, spot_per_oz);
//! // 10 g of 14k contains ~5.83 g pure gold → melt ≈ $747.05
//! assert!((usd - 747.05).abs() < 0.05);
//! assert_eq!(purity(14), 14.0 / 24.0);
//! ```

/// Grams in one troy ounce (1 oz t = 31.1034768 g).
pub const GRAMS_PER_TROY_OZ: f64 = 31.1034768;

/// Decimal purity for a karat value (karat / 24).
///
/// `purity(24) == 1.0` (pure), `purity(18) == 0.75`, `purity(14) ≈ 0.5833`.
#[inline]
pub fn purity(karat: u32) -> f64 {
    karat as f64 / 24.0
}

/// Spot price per **gram** of pure metal, derived from a per-troy-ounce quote.
#[inline]
pub fn spot_per_gram(spot_per_troy_oz: f64) -> f64 {
    spot_per_troy_oz / GRAMS_PER_TROY_OZ
}

/// Melt value (in the spot-price currency) for a given **weight in grams**,
/// `karat`, and `spot_per_troy_oz`.
///
/// Melt = grams × purity × (spot / 31.1034768).
pub fn melt_value_grams(grams: f64, karat: u32, spot_per_troy_oz: f64) -> f64 {
    grams * purity(karat) * spot_per_gram(spot_per_troy_oz)
}

/// Melt value for a weight in **pennyweight** (dwt). 1 dwt = 1/20 troy oz.
pub fn melt_value_dwt(dwt: f64, karat: u32, spot_per_troy_oz: f64) -> f64 {
    let troy_oz = dwt / 20.0;
    troy_oz * purity(karat) * spot_per_troy_oz
}

/// Melt value for a weight in **troy ounces** (already in troy units).
pub fn melt_value_troy_oz(troy_oz: f64, karat: u32, spot_per_troy_oz: f64) -> f64 {
    troy_oz * purity(karat) * spot_per_troy_oz
}

/// Common karat purities used in jewelry (US).
pub mod karats {
    pub const K24: u32 = 24;
    pub const K22: u32 = 22;
    pub const K18: u32 = 18;
    pub const K14: u32 = 14;
    pub const K10: u32 = 10;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn pure_gold_one_gram_at_spot() {
        // 1 g of 24k at $3983.30/oz ≈ $128.066
        let v = melt_value_grams(1.0, 24, 3983.30);
        assert!((v - 128.066).abs() < 0.001);
    }

    #[test]
    fn ten_grams_14k() {
        // 10 g of 14k at $3983.30/oz ≈ $747.05
        let v = melt_value_grams(10.0, 14, 3983.30);
        assert!((v - 747.05).abs() < 0.05);
    }

    #[test]
    fn pennyweight_matches_troy() {
        let spot = 3983.30;
        // 20 dwt == 1 troy oz of 24k
        let from_dwt = melt_value_dwt(20.0, 24, spot);
        let from_oz = melt_value_troy_oz(1.0, 24, spot);
        assert!((from_dwt - from_oz).abs() < 1e-6);
    }

    #[test]
    fn purity_table() {
        assert_eq!(purity(24), 1.0);
        assert!((purity(18) - 0.75).abs() < 1e-9);
        assert!((purity(14) - 0.5833333).abs() < 1e-6);
    }
}