private: No


{ lib ? (import <nixpkgs> {}).lib }:

let

  # ord-data.nix is an auto generated nix file
  # which contains single byte strings from
  # 0x01 to 0xff in a list where there index
  # is equal to their byte-value.
  #
  # The string at index 0 is empty because nix
  # apparently thinks a NUL byte is EOF.
  ordData = import ./ord-data.nix;

  inherit (lib)
    stringToCharacters
    concatMapStrings
    ;

  inherit (builtins)
    map
    elemAt
    ;

  elemIndex = e: l:
    let
      tailCall = e: l: i:
        if l == []
        then -1
        else if builtins.head l == e
        then i
        else tailCall e (builtins.tail l) (i + 1);
    in tailCall e l 0;

  ord = char:
    let
      i = elemIndex char ordData;
    in if i == -1 then 0 else i;   # can't have a NUL byte in a string apparently

  chr = i:
    if i < 1 || i > 255
    then throw "chr: only 0x01-0xff is supported"
    else elemAt ordData i;

  stringToIntegers = str:
    map ord (stringToCharacters str);

  integersToString = is: concatMapStrings chr is;

in

{
  inherit
    ord
    chr
    stringToIntegers
    integersToString
    ;
}