Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: Standard library

Standard library

Commerce, travel and health codes

On this page

These are the codes trade, transport and healthcare use: barcodes, ISBNs, container numbers, delivery terms, airport codes, blood types, diagnosis codes. Each is checked by its standard's pattern or check digit, and the closed lists are enums.

Here a till scans a product's barcode, a supplier's order names its delivery term in whatever case its system writes, and a dock prints each container's number as its side is painted:

example
type ScannedText = Text {}type NotAProductCode = Failure {    kind: FailureKind.invalid_value}type UnknownTradeTerm = Failure {    kind: FailureKind.invalid_value}/// The product a till's scanner read: 13 digits, the last GS1's check/// digit.function scanned_product(raw: ScannedText) fails NotAProductCode -> Ean13 {    var till_scan: Ean13 = attempt Ean13(raw) {        format: NotAProductCode    }    return till_scan}/// The delivery term a supplier's order names, by its Incoterms code.function agreed_term(raw: ScannedText) fails UnknownTradeTerm -> Incoterm {    var trade_term: Incoterm = attempt text.parse(raw, as: Incoterm) {        malformed: UnknownTradeTerm    }    return trade_term}/// A container on the dock's manifest, as its side is painted.function container_label(shipped_in: ContainerNumber, viewer: Locale) -> PresentationText {    return text.format(shipped_in, locale: viewer)}
example
test "a code is checked by its check digit as it is built" {    var till_scan: Ean13 = attempt scanned_product("4006381333931")    assert till_scan == Ean13("4006381333931")    assert scanned_product("4006381333932") fails NotAProductCode    assert scanned_product("400638133393") fails NotAProductCode    assert container_label(ContainerNumber("CSQU3054383"), Locale.en_gb) == "CSQU 305438 3"    assert text.format(UnNumber("UN1203"), locale: Locale.en_gb) == "UN 1203"}test "a closed list reads its codes in either case" {    var trade_term: Incoterm = attempt agreed_term("fob")    assert trade_term == Incoterm.fob    assert agreed_term("Free On Board") fails UnknownTradeTerm    assert text.from(BloodType.o_negative) == "O-"    assert text.format(CabinClass.premium_economy, locale: Locale.fr_fr) == "Premium economy"    assert list.count(Incoterm.all) == 11    assert list.count(Allergen.all) == 14}

Codes held as text

The codes are held as text, as the payment numbers are. Each is a pattern and, where the table under Groups with the baseline only names one, a named validator. Its canonical text is the value, in upper case where the standard writes it so and never read in another case. None is ordered.

Check digits

Where each check comes from:

  • GS1's mod 10 (General Specifications 7.9) for Ean13, UpcA, Sscc and Isbn. An ISBN is its 13 digits with the prefix 978 or 979 and no hyphens, because where the hyphens go depends on the ISBN agency's ranges.
  • ISO 6346's for ContainerNumber.
  • ISO 7064 MOD 11-2 for Orcid.
  • Verhoeff's for SnomedConcept, with a concept's partition identifier (00, or 10 in an extension), so a description's identifier is refused.
  • Elexon's primes for an Mpan core.
  • A Vin's check digit is checked where 49 CFR 565 requires it: for a manufacturer whose identifier starts 1 to 5, in North America. Elsewhere ISO 3779 leaves the ninth character to the manufacturer, and European VINs often don't carry a check digit, so checking every VIN would refuse real ones.

Patterns only

  • a Sku is 1 to 64 characters with no space or control character, kept as written;
  • a LotNumber and a SerialNumber are 1 to 20 characters of GS1's character set 82 (Application Identifiers 10 and 21);
  • an HsCode, a customs tariff code, is six to ten digits from chapter 01, as a tariff writes it without dots;
  • a Carrier is its Standard Carrier Alpha Code, two to four capitals;
  • an Icd10Code is its letter, two digits and, after the dot, up to four more, which covers ICD-10-CM;
  • an IataAirline is two letters, or a letter and a digit;
  • a BookingReference is six capitals and digits;
  • a UnNumber, which names a dangerous good, is UN and four digits;
  • an Mprn, a UK gas supply's number, is 6 to 10 digits.

Lists that aren't shipped

IATA's airport and airline codes and ICAO's location indicators are sold under licence. WHO's ICD-10 may be used, but not redistributed in software without its permission. So IataAirport, IcaoAirport, IataAirline and Icd10Code are checked by pattern only, as UnLocode is. An application that holds a licence checks against its own copy.

A SNOMED CT concept's term belongs to its release, under SNOMED International's licence, so SnomedConcept is its identifier alone, without a term.

Shown to people

A container number is shown as its side is painted, CSQU 305438 3, and a UN number as a transport document writes it, UN 1203. The rest are shown as their canonical text.

The closed lists

Each of these is a built-in enum, sorted by its code. Its code is read ignoring case and stored as written (O-, FOB):

  • Incoterm: Incoterms 2020's eleven delivery terms, with DAT, DAF, DES, DEQ and DDU from earlier editions retired;
  • BloodType: ABO and RhD, A+ to O-, whose variants spell the sign out, BloodType.o_negative;
  • Allergen: the 14 that the UK's Food Information Regulations 2014 and the EU's Regulation 1169/2011 name, without regional additions;
  • CabinClass: economy, premium economy, business and first;
  • CefrLevel: language levels A1 to C2;
  • EpcRating: energy performance bands A to G, without a score;
  • Tenure: freehold, leasehold and commonhold, as HM Land Registry registers land in England and Wales; a share of a freehold is a leasehold with a share;
  • LawfulBasis: GDPR Article 6(1)'s six lawful bases.

Where codes are words (premium_economy), each variant's code is its own name, as Continent's are.

Shown by code or by the authority's wording. CLDR names none of these lists. A list whose codes are written the same in every language (FOB, B2, O-, C) is shown by its code. A list whose codes are words is shown by its authority's English wording in every locale (FormatKey::Names, as a card brand is), just as a subdivision is shown by its English name: "Premium economy", "Cereals containing gluten", "Legitimate interests". To show them in another language, word them in your app's own messages.

None is ordered, not even CefrLevel and EpcRating. A match can say their order. The contract orders only what it lists.

Personal data and test values

Personal data: an Icd10Code, a SnomedConcept and a BloodType are health; an Orcid is identifying, as a username is; an Mpan and an Mprn are contact, as a Uprn is, because each names a home's supply. An Allergen isn't personal data: a menu's allergens describe food, and a person's allergy is your application's own field, which you mark.

Test values are published ones where a standard publishes them: GS1's, the ISBN Users' Manual's, NHTSA's, ISO 6346's, ORCID's, SNOMED CT's, and UPS's sample tracking number. Where a standard publishes none, they are made up to the rules. Each type's entry says which.

Markdown for agents: /docs/commerce-travel-and-health-codes.md.Built from Jadpo main at a707efb.