1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! HMRC exchange rates with bundled history and exact GBP conversion.
//!
//! One [`Rates`] value holds all four series HMRC has published:
//! monthly customs/VAT rates (from 2014-02),
//! spot and yearly-average rates for years ending 31 March / 31 December (from 2010-12),
//! and the discontinued 2014–2016 weekly amendments.
//!
//! ```
//! use hmrc_rates::{Rates, YearMonth};
//! use rust_decimal::Decimal;
//!
//! let rates = Rates::new(); // free: the tables are compiled-in statics
//! let rate = rates.monthly_rate("USD", YearMonth::new(2025, 8).unwrap())?;
//! let gbp = rate.to_gbp(Decimal::from(100)); // exact, unrounded
//! # Ok::<(), hmrc_rates::LookupError>(())
//! ```
//!
//! Rates are HMRC's figures, i.e. currency units per £1.
//! Conversion divides exactly, and the crate never rounds.
//!
//! Lookups are strict.
//! An unpublished period is an error, never a silently substituted older rate.
//! Fallback is explicit, see [`Rates::monthly_rate_or_earlier`].
//!
//! # Features
//!
//! - `std`, `bundled` (default): the full history compiled in,
//! no parsing or I/O at startup, ~450 KB of read-only data.
//! - `http`: a blocking `Updater` that fetches newly published periods,
//! with an on-disk cache.
//! - `serde`: compact string forms (`"2026-07"`, `"USD"`, `"monthly"`).
//! - `cli`: the `hmrc-rates` binary.
//!
//! The core is `no_std` + `alloc`
//! with only `bundled` enabled the crate builds on `wasm32-unknown-unknown`.
extern crate alloc;
pub use LookupError;
pub use Rate;
pub use ;
pub use ;
pub use ;