Expand description
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, unroundedRates 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 blockingUpdaterthat fetches newly published periods, with an on-disk cache.serde: compact string forms ("2026-07","USD","monthly").cli: thehmrc-ratesbinary.
The core is no_std + alloc
with only bundled enabled the crate builds on wasm32-unknown-unknown.
Structs§
- Currency
- A three-letter currency code as published by HMRC.
- Parse
Year Month Error - The error returned when parsing a
YearMonthfrom a string fails. - Rate
- A resolved HMRC rate: currency units per £1, with exact
Decimalarithmetic. - Rates
- All HMRC rate tables: bundled data plus (with the
httpfeature) fetched periods. - Table
- A borrowed view of one period’s table — resolve once, convert many times.
- YearEnd
- A spot/average rate period: HMRC publishes these only for years ending 31 March or 31 December, so other dates are unrepresentable.
- Year
Month - A calendar month, the key of HMRC monthly rate tables.
Enums§
- Lookup
Error - Why a rate lookup failed.
- Period
- The period a
Rateor table applies to. - Rate
Type - The four rate series HMRC has published.