gl_gtin

A production-ready Gleam library for validating and generating GTIN (Global Trade Item Number) codes.

This library provides type-safe, idiomatic Gleam implementations of GTIN validation, check digit generation, GS1 prefix lookup, and GTIN normalization according to the GS1 specification.

Quick Start

import gl_gtin

// Validate a GTIN code
case gl_gtin.validate("6291041500213") {
  Ok(format) -> io.println("Valid GTIN-13")
  Error(err) -> io.println("Invalid GTIN")
}

// Generate a GTIN with check digit
case gl_gtin.generate("629104150021") {
  Ok(complete_gtin) -> io.println(complete_gtin)
  Error(_) -> io.println("Generation failed")
}

// Look up country from GS1 prefix
case gl_gtin.gs1_prefix_country("6291041500213") {
  Ok(country) -> io.println("Country: " <> country)
  Error(_) -> io.println("Prefix not found")
}

Types

The supported GS1 identification keys.

Each variant selects a key kind for validate_key/generate_key and is associated with its length and format rules internally, so two keys sharing the same digit length (e.g. Sscc and Gsrn, both 18 digits) are distinguished by their Gs1Key value rather than by length alone.

Note: the Gtin variant shares its name with the opaque Gtin type. In Gleam types and value constructors live in separate namespaces, so this is unambiguous — the variant is the key kind, the type is the validated-GTIN value.

pub type Gs1Key {
  Gtin
  Gln
  Sscc
  Gsin
  Grai
  Giai
  Gsrn
  Gdti
  Gcn
}

Constructors

  • Gtin
  • Gln
  • Sscc
  • Gsin
  • Grai
  • Giai
  • Gsrn
  • Gdti
  • Gcn

A validated GTIN code.

This is an opaque type that can only be constructed through validation. This ensures that any Gtin value in your code is guaranteed to be valid.

pub opaque type Gtin

Errors that can occur when working with GTIN codes.

This is a re-export of gl_gtin/gtin_types.GtinError. Import the variants from the owning module — e.g. import gl_gtin/gtin_types.{InvalidFormat, InvalidLength} — to construct or pattern-match on them.

pub type GtinError =
  gtin_types.GtinError

Supported GTIN formats based on digit count.

This is a re-export of gl_gtin/gtin_types.GtinFormat. Import the variants from the owning module — import gl_gtin/gtin_types.{Gtin8, Gtin12, Gtin13, Gtin14} — to construct or pattern-match on them.

pub type GtinFormat =
  gtin_types.GtinFormat

Structured decomposition of a validated GTIN code.

This is a re-export of gl_gtin/parse.GtinInfo. Import the record constructor from the owning module — import gl_gtin/parse.{GtinInfo} — to construct or pattern-match on it.

pub type GtinInfo =
  parse.GtinInfo

Values

pub fn format(gtin: Gtin) -> gtin_types.GtinFormat

Get the format of a Gtin.

Examples

let assert Ok(gtin) = from_string("6291041500213")
format(gtin)
// -> Gtin13
pub fn from_string(
  code: String,
) -> Result(Gtin, gtin_types.GtinError)

Create an opaque Gtin value from a validated string.

This function validates the input and wraps it in the opaque Gtin type. Only valid GTINs can be wrapped.

Examples

from_string("6291041500213")
// -> Ok(Gtin(...))

from_string("invalid")
// -> Error(InvalidCharacters)
pub fn generate(
  code: String,
) -> Result(String, gtin_types.GtinError)

Generate a complete GTIN with calculated check digit.

Takes an incomplete GTIN (7, 11, 12, or 13 digits) and calculates the check digit to produce a complete GTIN (8, 12, 13, or 14 digits respectively).

Examples

generate("629104150021")
// -> Ok("6291041500213")

generate("123456789012")
// -> Ok("1234567890128")

generate("invalid")
// -> Error(InvalidCharacters)
pub fn gs1_prefix_country(
  code: String,
) -> Result(String, gtin_types.GtinError)

Look up the country of origin from a GTIN code’s GS1 prefix.

Checks the first 2-3 digits of the GTIN against the GS1 prefix database. Checks 3-digit prefixes first, then 2-digit prefixes.

Examples

gs1_prefix_country("6291041500213")
// -> Ok("GS1 Emirates")

gs1_prefix_country("012345678905")
// -> Ok("GS1 US")

gs1_prefix_country("999999999999")
// -> Error(NoGs1PrefixFound)
pub fn normalize(
  code: String,
) -> Result(String, gtin_types.GtinError)

Convert a GTIN-13 to GTIN-14 format.

Prepends the indicator digit “1” and recalculates the check digit. Only works with GTIN-13 codes; other formats return an error.

Examples

normalize("6291041500213")
// -> Ok("16291041500210")

normalize("012345678905")
// -> Error(InvalidFormat)
pub fn normalize_with_indicator(
  code: String,
  indicator: Int,
) -> Result(String, gtin_types.GtinError)

Convert a GTIN-13 to GTIN-14 format with an explicit indicator digit.

Prepends the given indicator digit (0 through 9) and recalculates the check digit. Only works with GTIN-13 codes; other formats or an out-of-range indicator return an error.

Examples

normalize_with_indicator("6291041500213", 2)
// -> Ok("26291041500217")

normalize_with_indicator("6291041500213", 10)
// -> Error(InvalidFormat)
pub fn parse(
  code: String,
) -> Result(parse.GtinInfo, gtin_types.GtinError)

Decompose a validated GTIN into a structured GtinInfo record.

This is a thin pass-through to gl_gtin/parse.parse, which already works in the public GtinError type. The input is trimmed and validated first (length, then characters, then check digit); an invalid code returns the corresponding GtinError and never a partially populated GtinInfo. See that module for the full field-derivation and GS1 company-prefix rules.

Examples

parse("6291041500213")
// -> Ok(GtinInfo(
//   format: Gtin13,
//   digits: "6291041500213",
//   indicator: Error(Nil),
//   gs1_prefix: "629",
//   gs1_region: Ok("GS1 Emirates"),
//   check_digit: 3,
// ))

parse("invalid")
// -> Error(InvalidCharacters)
pub fn partition(
  codes: List(String),
) -> #(List(String), List(String))

Partition a batch of GTIN code strings into valid and invalid groups.

Returns a #(valid, invalid) 2-tuple: the first list holds every element for which validate returns Ok, the second holds every element for which it returns Error. Each element is stored as the byte-for-byte original string (untrimmed), relative order is preserved within each list, duplicates are kept, and the two lists together contain every input element exactly once. This helper is total — a malformed element is routed to the invalid list rather than causing a crash.

Examples

partition(["6291041500213", "6291041500214"])
// -> #(["6291041500213"], ["6291041500214"])
pub fn to_gtin12(
  code: String,
) -> Result(String, gtin_types.GtinError)

Convert a GTIN-14 with indicator digit 0 to its base GTIN-12 (UPC-A).

Requires a valid GTIN-14 (14 digits, correct check digit) whose base code is a UPC-A padded with an implicit leading zero (both leading digits are 0). When so, both leading zeros are dropped to yield the 12-digit UPC-A, preserving the existing check digit. A non-zero indicator or a base code that cannot be represented as a GTIN-12 returns Error(InvalidFormat). Leading and trailing whitespace is trimmed before validation.

Examples

to_gtin12("00042100005264")
// -> Ok("042100005264")

to_gtin12("16291041500210")
// -> Error(InvalidFormat)
pub fn to_gtin13(
  code: String,
) -> Result(String, gtin_types.GtinError)

Convert a GTIN-14 with indicator digit 0 to its base GTIN-13.

Requires a valid GTIN-14 (14 digits, correct check digit). When the leading indicator digit is 0, the leading 0 is dropped and the existing check digit is preserved, yielding a 13-digit string. A non-zero indicator returns Error(InvalidFormat). Leading and trailing whitespace is trimmed before validation.

Examples

to_gtin13("06291041500213")
// -> Ok("6291041500213")

to_gtin13("16291041500210")
// -> Error(InvalidFormat)
pub fn to_string(gtin: Gtin) -> String

Extract the string value from a Gtin.

Examples

let assert Ok(gtin) = from_string("6291041500213")
to_string(gtin)
// -> "6291041500213"
pub fn upca_to_upce(
  code: String,
) -> Result(String, gtin_types.GtinError)

Compress a full 12-digit UPC-A code to its 8-digit UPC-E form when possible.

This is a thin pass-through to gl_gtin/upc.upca_to_upce, which already works in the public GtinError type. See that module for the full zero-suppression compression rules and validation ordering.

Examples

upca_to_upce("042100005264")
// -> Ok("04252614")

upca_to_upce("012345678905")
// -> Error(InvalidFormat)
pub fn upce_to_upca(
  code: String,
) -> Result(String, gtin_types.GtinError)

Expand a compressed 8-digit UPC-E code to its full 12-digit UPC-A form.

This is a thin pass-through to gl_gtin/upc.upce_to_upca, which already works in the public GtinError type. See that module for the full zero-suppression expansion rules and validation ordering.

Examples

upce_to_upca("04252614")
// -> Ok("042100005264")

upce_to_upca("24252614")
// -> Error(InvalidFormat)
pub fn validate(
  code: String,
) -> Result(gtin_types.GtinFormat, gtin_types.GtinError)

Validate a GTIN code string.

Checks that the input is a valid GTIN (8, 12, 13, or 14 digits) with a correct check digit. Automatically trims leading and trailing whitespace before validation.

Examples

validate("6291041500213")
// -> Ok(Gtin13)

validate("012345678905")
// -> Ok(Gtin12)

validate("invalid")
// -> Error(InvalidCharacters)

validate("123")
// -> Error(InvalidLength(got: 3))
pub fn validate_all(
  codes: List(String),
) -> List(
  #(String, Result(gtin_types.GtinFormat, gtin_types.GtinError)),
)

Validate a batch of GTIN code strings, pairing each original input with its validation result.

Applies validate to every element and returns a list of #(original_code, result) pairs in the same order as the input. The tuple key is the byte-for-byte original string (untrimmed); duplicates and empty lists are preserved. This helper is total — a malformed element yields an Error(...) pair rather than a crash.

Examples

validate_all(["6291041500213", "6291041500214"])
// -> [#("6291041500213", Ok(Gtin13)), #("6291041500214", Error(InvalidCheckDigit))]
✨ Search Document