hmrc-rates
Official HMRC exchange rates as a Rust library.
The full published history is compiled into your binary (~450 KB of read-only data), so Rates::new() is free and infallible — no parsing, no I/O, no startup cost.
Conversions use exact rust_decimal arithmetic and are never rounded.
Install
[]
= "0.2"
= "1"
Quick start
use ;
use Decimal;
Rates are HMRC's rateNew figures — currency units per £1; to_gbp divides.
"GBP" always resolves to the identity rate.
Data coverage
One Rates value holds all four series HMRC has published:
| Series | Coverage | Lookup |
|---|---|---|
| Monthly customs/VAT | 2014-02 - present, no gaps | monthly_rate(code, month) |
| Spot | Dec 2010 - present, years ending 31 Mar / 31 Dec | spot(YearEnd) |
| Yearly average | Dec 2010 - present, years ending 31 Mar / 31 Dec | average(YearEnd) |
| Weekly amendments | 2014-01 - 2016-04, complete (discontinued by HMRC) | weekly(date) |
Lookups are strict: a period HMRC never published is an error, never a silently substituted older rate. The error says why — unknown currency, period not available (with the loaded range), or currency absent from that period. Fallback is opt-in and visible:
let rate = rates.monthly_rate_or_earlier?;
rate.period // reveals which month was actually used
Currency codes are as published by HMRC, which is not always ISO 4217 — Ecuador appears as ECS.
See docs/data-sources.md for where every rate comes from.
Features
| Feature | Default | Adds |
|---|---|---|
std |
yes | — |
bundled |
yes | the compiled-in history and Rates::new() |
http |
no | blocking Updater (ureq) with an on-disk cache |
serde |
no | compact string forms: "2026-07", "USD", "monthly" |
cli |
no | the hmrc-rates binary |
The core is no_std + alloc: default-features = false, features = ["bundled"] builds on wasm32-unknown-unknown.
Fresh rates (http)
Updater fetches whatever HMRC has published since the crate release and caches the files verbatim in the system cache directory.
Past periods are served from disk forever; amendable periods get a 24-hour TTL.
use Updater;
let updater = new;
// Offline fallback is explicit: stale rates should be a visible choice
let rates = updater.refreshed.unwrap_or_else;
Documentation
- API reference: docs.rs/hmrc-rates
- Data provenance: docs/data-sources.md
- Runnable examples:
examples/convert.rs,examples/fresh.rs(--features http)
MSRV and licence
Rust 1.85. Licensed under MIT.