Skip to main content

regit_identifiers/
lib.rs

1// Copyright 2026 Regit.io — Nicolas Koenig
2// SPDX-License-Identifier: Apache-2.0
3
4//! Securities identifier validation in pure Rust — `#![no_std]`, no `alloc`,
5//! zero dependencies.
6//!
7//! `regit-identifiers` parses, validates, and converts the identifiers that
8//! name a security or a market: ISIN, CUSIP / CINS, SEDOL, LEI, BIC, MIC,
9//! FIGI, CFI, and the national numbers WKN and VALOR.
10//!
11//! An identifier is the primary key of a security: a trade is routed, a
12//! position is settled, and a holding is reported to a regulator against it.
13//! If a malformed or mistyped identifier is accepted as valid, every one of
14//! those operations is wrong. This crate's first duty is therefore to never
15//! certify a bad identifier as good. For every identifier that carries a
16//! check digit, the digit is recomputed from its governing standard and
17//! verified — never trusted. Structural rules are enforced exactly as the
18//! standard specifies.
19//!
20//! The crate is `#![no_std]` and allocation-free: every identifier is a
21//! fixed-size byte array, every algorithm is hand-rolled integer arithmetic,
22//! and there is no runtime dependency. The same audited logic runs in a
23//! backend service, a WASM bundle, or on an embedded device.
24//!
25//! # Quick start
26//!
27//! ```
28//! use regit_identifiers::checkdigit;
29//!
30//! // Recompute the check digit of Apple's ISIN body — never trust the
31//! // digit you were given.
32//! assert_eq!(checkdigit::isin_check_digit("US037833100").unwrap(), '5');
33//!
34//! // A securities identifier is, at its core, a check-digit scheme over an
35//! // alphanumeric alphabet — that core is exposed directly.
36//! assert_eq!(checkdigit::cusip_check_digit("03783310").unwrap(), '0');
37//! assert_eq!(checkdigit::sedol_check_digit("026349").unwrap(), '4');
38//! assert_eq!(checkdigit::figi_check_digit("BBG000BLNNH").unwrap(), '6');
39//! ```
40//!
41//! # Architecture
42//!
43//! ```text
44//! errors       typed errors — ValidationError, ConversionError
45//! charset      ASCII alphabet primitives (internal)
46//! checkdigit   check-digit algorithms — ISIN, CUSIP, SEDOL, LEI, FIGI
47//! country      ISO 3166-1 alpha-2 codes and ISIN prefix rules
48//!
49//! isin         ISIN  — ISO 6166         cusip   CUSIP / CINS — ANSI X9.6
50//! sedol        SEDOL — LSE Masterfile   lei     LEI   — ISO 17442
51//! figi         FIGI  — ANSI X9.145      bic     BIC   — ISO 9362
52//! mic          MIC   — ISO 10383        cfi     CFI   — ISO 10962
53//! wkn          WKN   — national (DE)    valor   VALOR — national (CH)
54//!
55//! convert      cross-identifier conversions (ISIN ⇄ CUSIP / SEDOL / VALOR)
56//! detect       SecurityId — unified type + auto-detection
57//! mic_registry embedded ISO 10383 registry  (feature `mic-registry`)
58//! ```
59//!
60//! Every rule is traced to a citable standard — ISO 6166, ISO 17442,
61//! ISO 9362, ISO 10383, ISO 10962, ISO 7064, and the CUSIP, SEDOL, and FIGI
62//! specifications — in the doc comment of the module that implements it.
63//!
64//! Part of [Regit OS](https://www.regit.io) — the operating system for
65//! investment products. From Luxembourg.
66
67#![no_std]
68#![forbid(unsafe_code)]
69
70mod charset;
71
72#[cfg(test)]
73mod test_support;
74
75pub mod bic;
76pub mod cfi;
77pub mod checkdigit;
78pub mod convert;
79pub mod country;
80pub mod cusip;
81pub mod detect;
82pub mod errors;
83pub mod figi;
84pub mod isin;
85pub mod lei;
86pub mod mic;
87pub mod sedol;
88pub mod valor;
89pub mod wkn;
90
91/// Embedded snapshot of the ISO 10383 Market Identifier Code registry.
92/// Enabled by the default `mic-registry` feature.
93#[cfg(feature = "mic-registry")]
94pub mod mic_registry;
95
96pub use bic::Bic;
97pub use cfi::Cfi;
98pub use cusip::Cusip;
99pub use detect::{IdentifierKind, SecurityId};
100pub use errors::{ConversionError, ValidationError};
101pub use figi::Figi;
102pub use isin::Isin;
103pub use lei::Lei;
104pub use mic::Mic;
105pub use sedol::Sedol;
106pub use valor::Valor;
107pub use wkn::Wkn;
108
109/// `MicEntry` and `MicStatus` are re-exported at the crate root for
110/// ergonomic access — both originate in [`mic_registry`] and travel with the
111/// `mic-registry` feature.
112#[cfg(feature = "mic-registry")]
113pub use mic::{MicEntry, MicStatus};