Skip to main content

gold_melt_value/
lib.rs

1//! # gold-melt-value
2//!
3//! Compute precious-metal **melt value** from karat (purity), weight, and a live
4//! spot price. Pure, dependency-free math — the same engine behind the
5//! [GoldGramPrice](https://goldgramprice.com/) live gold calculator.
6//!
7//! ## Quick example
8//! ```
9//! use gold_melt_value::{melt_value_grams, purity};
10//!
11//! let spot_per_oz = 3983.30;          // USD per troy ounce
12//! let grams = 10.0;                    // a 10 g chain
13//! let karat = 14;
14//!
15//! let usd = melt_value_grams(grams, karat, spot_per_oz);
16//! // 10 g of 14k contains ~5.83 g pure gold → melt ≈ $747.05
17//! assert!((usd - 747.05).abs() < 0.05);
18//! assert_eq!(purity(14), 14.0 / 24.0);
19//! ```
20
21/// Grams in one troy ounce (1 oz t = 31.1034768 g).
22pub const GRAMS_PER_TROY_OZ: f64 = 31.1034768;
23
24/// Decimal purity for a karat value (karat / 24).
25///
26/// `purity(24) == 1.0` (pure), `purity(18) == 0.75`, `purity(14) ≈ 0.5833`.
27#[inline]
28pub fn purity(karat: u32) -> f64 {
29    karat as f64 / 24.0
30}
31
32/// Spot price per **gram** of pure metal, derived from a per-troy-ounce quote.
33#[inline]
34pub fn spot_per_gram(spot_per_troy_oz: f64) -> f64 {
35    spot_per_troy_oz / GRAMS_PER_TROY_OZ
36}
37
38/// Melt value (in the spot-price currency) for a given **weight in grams**,
39/// `karat`, and `spot_per_troy_oz`.
40///
41/// Melt = grams × purity × (spot / 31.1034768).
42pub fn melt_value_grams(grams: f64, karat: u32, spot_per_troy_oz: f64) -> f64 {
43    grams * purity(karat) * spot_per_gram(spot_per_troy_oz)
44}
45
46/// Melt value for a weight in **pennyweight** (dwt). 1 dwt = 1/20 troy oz.
47pub fn melt_value_dwt(dwt: f64, karat: u32, spot_per_troy_oz: f64) -> f64 {
48    let troy_oz = dwt / 20.0;
49    troy_oz * purity(karat) * spot_per_troy_oz
50}
51
52/// Melt value for a weight in **troy ounces** (already in troy units).
53pub fn melt_value_troy_oz(troy_oz: f64, karat: u32, spot_per_troy_oz: f64) -> f64 {
54    troy_oz * purity(karat) * spot_per_troy_oz
55}
56
57/// Common karat purities used in jewelry (US).
58pub mod karats {
59    pub const K24: u32 = 24;
60    pub const K22: u32 = 22;
61    pub const K18: u32 = 18;
62    pub const K14: u32 = 14;
63    pub const K10: u32 = 10;
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn pure_gold_one_gram_at_spot() {
72        // 1 g of 24k at $3983.30/oz ≈ $128.066
73        let v = melt_value_grams(1.0, 24, 3983.30);
74        assert!((v - 128.066).abs() < 0.001);
75    }
76
77    #[test]
78    fn ten_grams_14k() {
79        // 10 g of 14k at $3983.30/oz ≈ $747.05
80        let v = melt_value_grams(10.0, 14, 3983.30);
81        assert!((v - 747.05).abs() < 0.05);
82    }
83
84    #[test]
85    fn pennyweight_matches_troy() {
86        let spot = 3983.30;
87        // 20 dwt == 1 troy oz of 24k
88        let from_dwt = melt_value_dwt(20.0, 24, spot);
89        let from_oz = melt_value_troy_oz(1.0, 24, spot);
90        assert!((from_dwt - from_oz).abs() < 1e-6);
91    }
92
93    #[test]
94    fn purity_table() {
95        assert_eq!(purity(24), 1.0);
96        assert!((purity(18) - 0.75).abs() < 1e-9);
97        assert!((purity(14) - 0.5833333).abs() < 1e-6);
98    }
99}