Current section
Files
Jump to
Current section
Files
src/gl_gtin.erl
-module(gl_gtin).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gl_gtin.gleam").
-export([validate/1, generate/1, gs1_prefix_country/1, normalize/1, from_string/1, to_string/1, format/1]).
-export_type([gtin_format/0, gtin_error/0, gtin/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" A production-ready Gleam library for validating and generating GTIN (Global Trade Item Number) codes.\n"
"\n"
" This library provides type-safe, idiomatic Gleam implementations of GTIN validation,\n"
" check digit generation, GS1 prefix lookup, and GTIN normalization according to the\n"
" GS1 specification.\n"
"\n"
" # Quick Start\n"
"\n"
" ```gleam\n"
" import gl_gtin\n"
"\n"
" // Validate a GTIN code\n"
" case gl_gtin.validate(\"6291041500213\") {\n"
" Ok(format) -> io.println(\"Valid GTIN-13\")\n"
" Error(err) -> io.println(\"Invalid GTIN\")\n"
" }\n"
"\n"
" // Generate a GTIN with check digit\n"
" case gl_gtin.generate(\"629104150021\") {\n"
" Ok(complete_gtin) -> io.println(complete_gtin)\n"
" Error(_) -> io.println(\"Generation failed\")\n"
" }\n"
"\n"
" // Look up country from GS1 prefix\n"
" case gl_gtin.gs1_prefix_country(\"6291041500213\") {\n"
" Ok(country) -> io.println(\"Country: \" <> country)\n"
" Error(_) -> io.println(\"Prefix not found\")\n"
" }\n"
" ```\n"
).
-type gtin_format() :: gtin8 | gtin12 | gtin13 | gtin14.
-type gtin_error() :: {invalid_length, integer()} |
invalid_check_digit |
invalid_characters |
no_gs1_prefix_found |
invalid_format.
-opaque gtin() :: {gtin, binary(), gtin_format()}.
-file("src/gl_gtin.gleam", 90).
?DOC(
" Validate a GTIN code string.\n"
"\n"
" Checks that the input is a valid GTIN (8, 12, 13, or 14 digits) with a correct check digit.\n"
" Automatically trims leading and trailing whitespace before validation.\n"
"\n"
" # Examples\n"
"\n"
" ```gleam\n"
" validate(\"6291041500213\")\n"
" // -> Ok(Gtin13)\n"
"\n"
" validate(\"012345678905\")\n"
" // -> Ok(Gtin12)\n"
"\n"
" validate(\"invalid\")\n"
" // -> Error(InvalidCharacters)\n"
"\n"
" validate(\"123\")\n"
" // -> Error(InvalidLength(got: 3))\n"
" ```\n"
).
-spec validate(binary()) -> {ok, gtin_format()} | {error, gtin_error()}.
validate(Code) ->
_pipe = gl_gtin@validation:validate(Code),
_pipe@1 = gleam@result:map(_pipe, fun(Fmt) -> case Fmt of
gtin8 ->
gtin8;
gtin12 ->
gtin12;
gtin13 ->
gtin13;
gtin14 ->
gtin14
end end),
gleam@result:map_error(_pipe@1, fun(Err) -> case Err of
{invalid_length, Got} ->
{invalid_length, Got};
invalid_check_digit ->
invalid_check_digit;
invalid_characters ->
invalid_characters;
invalid_format ->
invalid_format
end end).
-file("src/gl_gtin.gleam", 127).
?DOC(
" Generate a complete GTIN with calculated check digit.\n"
"\n"
" Takes an incomplete GTIN (7, 11, 12, or 13 digits) and calculates the check digit\n"
" to produce a complete GTIN (8, 12, 13, or 14 digits respectively).\n"
"\n"
" # Examples\n"
"\n"
" ```gleam\n"
" generate(\"629104150021\")\n"
" // -> Ok(\"6291041500213\")\n"
"\n"
" generate(\"123456789012\")\n"
" // -> Ok(\"1234567890128\")\n"
"\n"
" generate(\"invalid\")\n"
" // -> Error(InvalidCharacters)\n"
" ```\n"
).
-spec generate(binary()) -> {ok, binary()} | {error, gtin_error()}.
generate(Code) ->
_pipe = gl_gtin@check_digit:generate(Code),
gleam@result:map_error(_pipe, fun(Err) -> case Err of
{invalid_length, Got} ->
{invalid_length, Got};
invalid_characters ->
invalid_characters
end end).
-file("src/gl_gtin.gleam", 154).
?DOC(
" Look up the country of origin from a GTIN code's GS1 prefix.\n"
"\n"
" Checks the first 2-3 digits of the GTIN against the GS1 prefix database.\n"
" Checks 3-digit prefixes first, then 2-digit prefixes.\n"
"\n"
" # Examples\n"
"\n"
" ```gleam\n"
" gs1_prefix_country(\"6291041500213\")\n"
" // -> Ok(\"GS1 Emirates\")\n"
"\n"
" gs1_prefix_country(\"012345678905\")\n"
" // -> Ok(\"GS1 US\")\n"
"\n"
" gs1_prefix_country(\"999999999999\")\n"
" // -> Error(NoGs1PrefixFound)\n"
" ```\n"
).
-spec gs1_prefix_country(binary()) -> {ok, binary()} | {error, gtin_error()}.
gs1_prefix_country(Code) ->
_pipe = gl_gtin@gs1_prefix:lookup(Code),
gleam@result:map_error(_pipe, fun(_) -> no_gs1_prefix_found end).
-file("src/gl_gtin.gleam", 173).
?DOC(
" Convert a GTIN-13 to GTIN-14 format.\n"
"\n"
" Prepends the indicator digit \"1\" and recalculates the check digit.\n"
" Only works with GTIN-13 codes; other formats return an error.\n"
"\n"
" # Examples\n"
"\n"
" ```gleam\n"
" normalize(\"6291041500213\")\n"
" // -> Ok(\"16291041500214\")\n"
"\n"
" normalize(\"012345678905\")\n"
" // -> Error(InvalidFormat)\n"
" ```\n"
).
-spec normalize(binary()) -> {ok, binary()} | {error, gtin_error()}.
normalize(Code) ->
_pipe = gl_gtin@validation:normalize(Code),
gleam@result:map_error(_pipe, fun(Err) -> case Err of
{invalid_length, Got} ->
{invalid_length, Got};
invalid_check_digit ->
invalid_check_digit;
invalid_characters ->
invalid_characters;
invalid_format ->
invalid_format
end end).
-file("src/gl_gtin.gleam", 199).
?DOC(
" Create an opaque Gtin value from a validated string.\n"
"\n"
" This function validates the input and wraps it in the opaque Gtin type.\n"
" Only valid GTINs can be wrapped.\n"
"\n"
" # Examples\n"
"\n"
" ```gleam\n"
" from_string(\"6291041500213\")\n"
" // -> Ok(Gtin(...))\n"
"\n"
" from_string(\"invalid\")\n"
" // -> Error(InvalidCharacters)\n"
" ```\n"
).
-spec from_string(binary()) -> {ok, gtin()} | {error, gtin_error()}.
from_string(Code) ->
gleam@result:'try'(
validate(Code),
fun(Format) -> {ok, {gtin, Code, Format}} end
).
-file("src/gl_gtin.gleam", 213).
?DOC(
" Extract the string value from a Gtin.\n"
"\n"
" # Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(gtin) = from_string(\"6291041500213\")\n"
" to_string(gtin)\n"
" // -> \"6291041500213\"\n"
" ```\n"
).
-spec to_string(gtin()) -> binary().
to_string(Gtin) ->
{gtin, Value, _} = Gtin,
Value.
-file("src/gl_gtin.gleam", 227).
?DOC(
" Get the format of a Gtin.\n"
"\n"
" # Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(gtin) = from_string(\"6291041500213\")\n"
" format(gtin)\n"
" // -> Gtin13\n"
" ```\n"
).
-spec format(gtin()) -> gtin_format().
format(Gtin) ->
{gtin, _, Fmt} = Gtin,
Fmt.