Module Bantorra.Router

Routers.

Types

type param = Marshal.value

The type of parameters to routers.

type t = param -> FilePath.t

The type of library routers. A router is a function from JSON parameters to file paths.

type pipe = param -> param

The type of parameter transformers.

type table = (Marshal.value, Marshal.value) Stdlib.Hashtbl.t

The type of parameter rewrite tables. The invariant is that the keys should be normalized.

Algebraic Effects

val get_version : unit -> string

Get the format version string used by the library manager.

val get_starting_dir : unit -> FilePath.t option

Get the starting directory of the resolution, usually the root of the library mounting the current route. That is, if a library X is mounting library Y, the starting directory is usually the root of X when locating the library Y. That said, an application can explicitly specify the starting directory when locating a library.

val run : version:string -> ?starting_dir:FilePath.t -> (unit -> 'a) -> 'a

Handle the algebraic effects generated by get_starting_dir.

Built-in Routers and Utility Functions

Router Combinators

val dispatch : (string -> t option) -> t

dispatch lookup accepts JSON arrays of the form [name, arg] and runs the router lookup name with the JSON parameter arg

val rewrite : ?mode:[ `TryOnce | `ErrOnMissing | `Recursively of int ] -> (param -> param option) -> pipe

rewrite lookup rewrites the JSON parameter param to param' if lookup param is Some param'. Otherwise, if lookup param is None, the param is returned unchanged.

  • parameter mode

    `Recursively t means applying lookup until it returns None, and then the parameter before reaching None is returned. `ErrOnMissing means erring when lookup param is None (instead of returning the original parameter) when lookup param is None.

val fix : ?hop_limit:int -> (t -> t) -> t

fix f gives the fixed point of f.

  • parameter hop_limit

    The maximum depth of recursive routing. 0 means no recursive calls and 1 means recursion at most once. The default value is 255.

Base Routers

val file : ?relative_to:FilePath.t -> expanding_tilde:bool -> t

file accepts a JSON string path and return the path as a file path.

  • parameter relative_to

    The base directory to turn relative paths to absolute paths. Without setting this argument, relative paths will be rejected.

  • parameter expanding_tilde

    Whether to expand the tilde prefix in a path. (Recommended in most cases.)

val git : ?err_on_failed_fetch:bool -> FilePath.t -> t

git ~crate accepts JSON parameters in one of the following formats:

{ "url": "git@github.com:RedPRL/bantorra.git" }
{
  "url": "git@github.com:RedPRL/bantorra.git",
  "ref": "main"
}
{
  "url": "git@github.com:RedPRL/bantorra.git",
  "path": "src/library/"
}
{
  "url": "git@github.com:RedPRL/bantorra.git",
  "ref": "main",
  "path": "src/library/"
}

The ref field can be a commit hash (object name), a branch name, a tag name, or essentially anything accepted by git fetch. (The older git before year 2015 would not accept commit IDs, but please upgrade it already.) The path field is the relative path pointing to the root of the library. If the path field is missing, then the tool assumes the library is at the root of the repository. If the ref field is missing, then "HEAD" is used, which points to the tip of the default branch in the remote repository.

Different URLs pointing to the "same" git repository are treated as different repositories. Therefore, git@github.com:RedPRL/bantorra.git and https://github.com/RedPRL/bantorra.git are treated as two distinct git repositories. For the same repository, the commits in use must be identical during the program execution; one can use different branch names or tag names, but they must point to the same commit. The resolution would fail if there is an attempt to use different commits of the same repository.

Configuration Files

Format of the configuration files:

{
  "format": "1.0.0",
  "rewrite": [ ["stdlib", "~/coollib/stdlib"] ]
}

rewrite is an array of pairs of JSON values. If the property rewrite is missing, it is understood as the empty array. The array will be parsed as a rewrite table. The table is intended to be used with rewrite as follows:

rewrite (lookup_table (read_table ~version:"1.0.0" "file"))

Note: the format version string of the configuration files should match that used by the library manager.

val lookup_table : table -> param -> param option

lookup_table table param looks up the (normalized) param in table.

val parse_table : string -> table

parse_table str parse str as a table.

val read_table : FilePath.t -> table

read_table path is parse_table ~version (File.read path).

val get_web_table : string -> table

get_web_table path is parse_table ~version (Web.get url).

val write_table : FilePath.t -> table -> unit

write_table path table writes table to the file at path.