moonbitstack/moonconf/expand does not have a README file

    Refused

    pub(all) suberror Refused {
    Unclosed(at~ : At)
    BadName(at~ : At, got~ : String)
    BadOperator(at~ : At, got~ : String)
    Undefined(name~ : String, at~ : At)
    ReadOnly(name~ : String, at~ : At)
    Required(name~ : String, why~ : String, at~ : At)
    TooDeep(at~ : At, limit~ : Int)
    }

    Why a text was refused.
    impl Show for Refused

    Refused::output

    fn Refused::output(self : Refused, logger : &Logger) -> Unit

    Refused::to_string

    fn Refused::to_string(self : Refused) -> String

    pub(all) struct At {
    at : Int
    line : Int
    column : Int
    } derive(Eq,
    Debug
    )

    Where in the text something went wrong.

    At::equal

    fn At::equal(At, At) -> Bool

    At::not_equal

    fn At::not_equal(x : At, y : At) -> Bool

    At::to_repr

    Knobs

    pub(all) struct Knobs {
    unset : Unset
    } derive(Eq,
    Debug
    )

    How far to expand.

    Knobs::equal

    fn Knobs::equal(Knobs, Knobs) -> Bool

    Knobs::not_equal

    fn Knobs::not_equal(x : Knobs, y : Knobs) -> Bool

    Knobs::to_repr

    Unset

    pub(all) enum Unset {
    Fail
    Empty
    Keep
    } derive(Eq,
    Debug
    )

    What a reference to a variable that has no value means.

    Unset::equal

    fn Unset::equal(Unset, Unset) -> Bool

    Unset::not_equal

    fn Unset::not_equal(x : Unset, y : Unset) -> Bool

    Unset::to_repr

    Vars

    pub(all) struct Vars {
    get : (String) -> String?
    set : (String, String) -> Unit?
    }

    The variables a text may refer to, and where ${A:=b} writes.

    Reading is one function and writing is another rather than a map, because the thing a caller has is usually not a map: the process environment cannot be written, a layered configuration writes to its override layer, and a test writes to a small table. A Vars with no set is read-only, and an assignment through it is refused rather than dropped.

    Vars::lookup

    fn Vars::lookup(self : Vars, name : String) -> String?

    The value of name, or nothing.

    Vars::none

    fn Vars::none() -> Vars

    No variables at all.

    Vars::of

    fn Vars::of(get : (String) -> String?) -> Vars

    The variables of a function, which cannot be assigned to.

    Vars::of_map

    fn Vars::of_map(entries : Map[String, String]) -> Vars

    The entries of a map, which an assignment updates.

    Vars::write

    fn Vars::write(self : Vars, name : String, value : String) -> Bool

    Write name, answering whether there was anywhere to write it.

    Vars::writing

    fn Vars::writing(get : (String) -> String?, set : (String, String) -> Unit) -> Vars

    The variables of a function, which an assignment also updates.

    deferred

    let deferred : Knobs

    A reference to an unset variable is left as written.

    depth

    let depth : Int

    The limit on nested forms. ${A:-${B:-${C}}} is three; a text that nests itself a thousand times is a mistake, and the recursion has to stop somewhere short of the stack.

    expand

    fn expand(text : StringView, vars : Vars, knobs? : Knobs) -> String raise Refused

    Expand a text in the POSIX shell's parameter syntax.

    ${A}, $A, ${A:-b}, ${A-b}, ${A:=b}, ${A=b}, ${A:?msg}, ${A?msg}, ${A:+b}, ${A+b} and ${#A}, with \ escaping $, \, " and a backtick, and the word inside any of the forms expanded in turn. The colon forms also treat an empty value as missing, as the shell does.

    A variable with no value is an error by default: a caller who knows an empty string is meant asks for [lenient], and one that expands in two passes asks for { unset: Keep }.

    lenient

    let lenient : Knobs

    A reference to an unset variable reads as empty.

    strict

    let strict : Knobs

    A reference to an unset variable is an error.