Library API

Every public value, type and error in the library, package by package: what it takes, what it returns, and what it can raise.

Generated from the interfaces

scripts/gen_api_reference.py reads each src/*/pkg.generated.mbti — the interface moon info writes and moon check holds the source to — and the /// block above each declaration. Change a signature and this page changes with it; CI regenerates it and fails on a diff. An entry without prose has none in the source either, and is left bare rather than given a sentence invented to fill the space.

Using it #

The library is pure: a string in, a string out. Add the module, import the package, and call it from a build step, a test or a page.

main.mbt
let spec = @moonctl.parse(source)
let code = @moonctl.generate(spec)       // a moonapi scaffold, as text
let tree = @moonctl.generate_tree(spec)  // the layered project, file by file

The root package re-exports the types the other packages declare, so a caller can name @moonctl.Spec, @moonctl.Route and @moonctl.Template without importing anything else. Each re-exported type is listed under the package that owns it.

Packages #

Each package has one job. The table gives their weight, sorted by import path; the sections below give their surface.

Import pathPackageItems
moonbitstack/moonctlmoonctl92
moonbitstack/moonctl/agentagent1
moonbitstack/moonctl/apiapi25
moonbitstack/moonctl/clicli33
moonbitstack/moonctl/clientclient4
moonbitstack/moonctl/docdoc6
moonbitstack/moonctl/gengen8
moonbitstack/moonctl/gqlgql1
moonbitstack/moonctl/modelmodel19
moonbitstack/moonctl/pluginplugin11
moonbitstack/moonctl/protoproto19
moonbitstack/moonctl/scaffoldscaffold16
moonbitstack/moonctl/stylestyle2
moonbitstack/moonctl/templatetemplate5

moonctl #

moonbitstack/moonctl92 public items, 40 re-exported types

Values

pub fn bug_report(String, String, Array[(String, String)]) -> String
pub fn cache_file_name(String) -> String
pub fn client_file(@api.Spec, @client.Lang) -> (String, String)
pub fn client_file_name(@client.Lang, String) -> String
pub fn command_names() -> Array[String]
pub fn commands() -> Array[@cli.Command]
pub fn completion(String) -> String
pub fn config_get(@cli.Config, String) -> String?
pub fn config_keys() -> Array[String]
pub fn config_set(@cli.Config, String, String) -> @cli.Config
pub fn config_text(@cli.Config) -> String
pub fn default_config() -> @cli.Config
pub fn default_routes(@proto.Proto) -> Array[@proto.GatewayRoute]
pub fn deps(String, from? : String) -> Array[String]
pub fn env_report(String, Array[(String, String)]) -> String
pub fn find_template(String) -> @cli.TemplateEntry?
pub fn format(String) -> String
pub fn gateway_file_name(String) -> String
pub fn gen_files_to_json(Array[@plugin.GenFile]) -> Json
pub fn generate(@api.Spec, template? : String) -> String raise @template.TemplateError
pub fn generate_agent(@api.Spec) -> String
pub fn generate_cached(@api.Spec) -> String
pub fn generate_client(@api.Spec, @client.Lang) -> String
pub fn generate_crud(Array[@model.DdlTable]) -> String
pub fn generate_crud_from_ddl(String) -> String
pub fn generate_crud_from_reflection(Array[@model.ReflectedColumn]) -> String
pub fn generate_doc(@api.Spec, version? : @doc.DocVersion, title? : String, api_version? : String) -> String
pub fn generate_gateway(@proto.Proto, Array[@proto.GatewayRoute]) -> String
pub fn generate_gql(@api.Spec) -> String
pub fn generate_gql_tree(@api.Spec, style? : @style.Style, dir? : String) -> Array[@scaffold.TreeFile]
pub fn generate_grpc(@proto.Proto) -> String
pub fn generate_markdown(@api.Spec, title? : String) -> String
pub fn generate_mcp_tree(String, style? : @style.Style, dir? : String) -> Array[@scaffold.TreeFile]
pub fn generate_migrations(@api.Spec) -> String
pub fn generate_model(@api.Spec) -> String
pub fn generate_mongo(@api.Spec) -> String
pub fn generate_rpc_tree(@proto.Proto, style? : @style.Style, dir? : String) -> Array[@scaffold.TreeFile]
pub fn generate_tree(@api.Spec, style? : @style.Style, dir? : String) -> Array[@scaffold.TreeFile]
pub fn generate_with(@api.Spec, String) -> String raise @template.TemplateError
pub fn has_errors(Array[@api.Diagnostic]) -> Bool
pub fn has_method(@proto.Proto, String) -> Bool
pub fn markdown_file_name(String) -> String
pub fn migrate_config(String) -> (String, Array[String])
pub fn migrate_file_name(String) -> String
pub fn mod_pins(String) -> Array[(String, String)]
pub fn mongo_file_name(String) -> String
pub fn openapi_document(@api.Spec, version? : @doc.DocVersion, title? : String, api_version? : String) -> Json
pub fn parse(String) -> @api.Spec raise @api.SpecError
pub fn parse_all(String, Map[String, String], from? : String) -> @api.Spec raise @api.SpecError
pub fn parse_config(String) -> @cli.Config
pub fn parse_ddl(String) -> Array[@model.DdlTable]
pub fn parse_dsn(String) -> @model.DataSource raise @model.DataSourceError
pub fn parse_gen_files(Json) -> Array[@plugin.GenFile]
pub fn parse_lenient(String) -> @api.Spec
pub fn parse_proto(String) -> @proto.Proto
pub fn parse_route_map(@proto.Proto, String) -> (Array[@proto.GatewayRoute], Array[String])
pub fn pin_module(String, String, String) -> (String, String?)
pub fn pinned_version(String, String) -> String?
pub let pins : Map[String, String]
pub fn plugin_argv(String) -> (String, Array[String])
pub fn plugin_from_json(Json) -> @plugin.Plugin
pub fn plugin_plan(Array[@plugin.GenFile]) -> (Array[@plugin.GenFile], Array[String])
pub fn plugin_request(@api.Spec, api_file_path? : String, style? : String, dir? : String) -> String
pub let port : Int32
pub fn proto_reserved_conflicts(@proto.ProtoMessage) -> Array[String]
pub fn render(String, @template.Value) -> String raise @template.TemplateError
pub fn resolve_import(String, String) -> String
pub fn safe_path(String) -> Bool
pub fn scaffold_api(String) -> Array[@plugin.GenFile]
pub fn scaffold_docker(String, port? : Int32) -> Array[@plugin.GenFile]
pub fn scaffold_gql(String) -> Array[@plugin.GenFile]
pub fn scaffold_kube(String, port? : Int32, replicas? : Int32) -> Array[@plugin.GenFile]
pub fn scaffold_mcp(String) -> Array[@plugin.GenFile]
pub fn scaffold_model(String) -> Array[@plugin.GenFile]
pub fn scaffold_rpc(String) -> Array[@plugin.GenFile]
pub fn spec_from_json(Json) -> @api.Spec
pub fn spec_to_json(@api.Spec) -> Json
pub fn spec_to_value(@api.Spec) -> @template.Value
pub fn subcommands(String) -> Array[String]
pub fn swagger_ui_stub(spec_url? : String, title? : String) -> String
pub fn tables_from_reflection(Array[@model.ReflectedColumn]) -> Array[@model.DdlTable]
pub fn template_detail(@cli.TemplateEntry) -> String
pub fn template_table() -> String
pub fn templates() -> Array[@cli.TemplateEntry]
pub fn templates_of(String) -> Array[@cli.TemplateEntry]
pub fn tree_plan(Array[@scaffold.TreeFile], (String) -> Bool) -> Array[@plugin.GenFile]
pub fn upgrade_pins(String, Array[String], String) -> (String, Array[String])
pub fn usage_text(String) -> String
pub fn validate(@api.Spec) -> Array[@api.Diagnostic]
pub fn validate_files(String, Map[String, String], from? : String) -> Array[@api.Diagnostic]
pub fn validate_source(String) -> Array[@api.Diagnostic]

Aliases

pub type FuncFn = (Array[@template.Value]) -> @template.Value raise @template.TemplateError

Re-exported types

TypeComes from
Bindapi
Commandcli
Configcli
DataSourcemodel
DataSourceErrormodel
DdlColumnmodel
DdlTablemodel
Diagnosticapi
DocVersiondoc
Fieldapi
GatewayRouteproto
GenFileplugin
Groupapi
Labelproto
Langclient
PgTargetmodel
Pluginplugin
Protoproto
ProtoEnumproto
ProtoEnumValueproto
ProtoFieldproto
ProtoMessageproto
ProtoOneofproto
ProtoServiceproto
Rangeapi
ReflectedColumnmodel
Regenscaffold
Routeapi
Rpcproto
Severityapi
Specapi
SpecErrorapi
Stylestyle
StyleErrorstyle
Templatetemplate
TemplateEntrycli
TemplateErrortemplate
TreeFilescaffold
TypeDefapi
Valuetemplate

agent #

moonbitstack/moonctl/agent1 public item

Values

pub fn generate_agent(@api.Spec) -> String

Generate a moonkoog agent scaffold from spec. Every route becomes a Tool whose descriptor advertises the operation (a single string input parameter to fill out) and whose execute_raw is a stub, and build_agent assembles them into an AIAgent with the service's name in its system prompt. The output compiles against moonbitstack/moonkoog; fill in each execute_raw to make it run.

api #

moonbitstack/moonctl/api25 public items

Values

pub fn deps(String, from? : String) -> Array[String]

The files source imports, each resolved against from — the path source itself was read from. A caller that can read files walks a multi-file spec with this: read a file, follow its deps, and hand everything it collected to parse_all.

pub fn find_type(Array[TypeDef], String) -> TypeDef?

The TypeDef named name, or None when the spec declared no such block.

pub fn flat_fields(TypeDef, Array[TypeDef]) -> Array[Field]

Every field a type block carries with its inline embeds folded in first, which is both the shape an embedded Go struct serialises to and the only one MoonBit can spell — a MoonBit struct has no embedding. An embed naming a block that is not in types, and one that leads back to a block already folded in, contribute nothing.

pub fn format(String) -> String

Format an .api source. Nesting is read off braces and off the two blocks that open with a parenthesis — a multi-line @server ( and a type ( group; blank lines collapse to one; the result ends in exactly one newline. Comments and struct tags survive verbatim, and the function is idempotent: formatting an already formatted spec returns it unchanged.

pub fn has_errors(Array[Diagnostic]) -> Bool

Whether any finding is an Error — what makes mctl api validate exit non-zero.

pub fn index_of(String, UInt16, Int32) -> Int32

Index of the first ch in s at or after from, or -1 if absent.

pub fn parse(String) -> Spec raise SpecError

Read a goctl-style .api description into a Spec. Grammar (one statement per line):

syntax = "v1"

info (
  title:   "greet"
  version: "v2"
)

type LoginReq {
  name: string
}

@server (
  group:      user
  prefix:     /api/v1
  middleware: Log
)
service greet {
  @doc "health check"
  @handler ping
  get /ping

  @handler login
  post /login (LoginReq) returns (LoginResp)

  get /legacy legacy_handler "the inline form"
}

A type block declares a message schema (its fields become a MoonBit struct); field types use goctl's Go spellings (string, int64, []T, map[K]V, …). An @server( … ) block annotates every route of the service block that follows it: the routes carry its prefix in their paths and its Group on their group. Verbs are lower-cased, blank lines and // comments are dropped.

Any other line raises a SpecError naming it — a misspelt verb or a missing brace would otherwise generate a quietly truncated program. Use parse_lenient for a best-effort read of a spec that is still being written.

pub fn parse_all(String, Map[String, String], from? : String) -> Spec raise SpecError

Parse source — the spec at from — together with everything it imports, taken from files (a map from resolved path to source, the shape deps resolves to). What the imports describe is merged in first, in the order they were declared, then the importing file's own: types, routes and @server groups all end up in one Spec. A file is scanned once however many times it is imported, so a cycle terminates.

The service name is the last one declared, so the importing file's own service block wins and a spec that does nothing but import still takes the name from what it imported.

An import naming a file that is not in files raises Missing; a file that does not parse raises its first complaint the way parse does, with the file it came from named alongside the line.

pub fn parse_lenient(String) -> Spec

parse without the diagnostics: a line the parser cannot read is skipped and whatever the spec does describe is returned. For a caller that generates from a half-written spec on every keystroke; anything that reports to a user should call parse.

pub fn resolve_import(String, String) -> String

An import path resolved against the file that declared it: taken relative to that file's directory, with ./.. folded away. An already-absolute path is left where it points.

pub fn to_i64(String) -> Int64?

s read as a non-negative decimal, or None when it is not one.

pub fn tokens(String) -> Array[String]

Whitespace-split a line into tokens, keeping a "quoted string" as one token (with the quotes stripped).

pub fn validate(Spec) -> Array[Diagnostic]

Check a parsed spec: the routes, the types and the places one names the other. Findings come in spec order — routes first, then types — so a report reads the way the file does.

pub fn validate_files(String, Map[String, String], from? : String) -> Array[Diagnostic]

Validate one file of a spec together with everything it imports, files being every source the walk has read keyed by the path it was read from. Without this a spec that embeds a type from another file is told that the type does not exist — true of the file on its own, false of the spec it belongs to.

pub fn validate_source(String) -> Array[Diagnostic]

Validate a spec given as source. A spec the parser cannot read is reported as the one finding it is — syntax, naming the line — rather than raising, so a caller checks a file the same way whether it is broken or merely wrong.

Errors

pub suberror SpecError

A spec the parser could not read: Syntax is the 1-based line and what went wrong there, Missing an import whose path was not among the files handed to parse_all.

  • Syntax(line~ : Int32, msg~ : String)
  • Missing(file~ : String, path~ : String)

Types

pub(all) enum Bind derive(Eq)

Where a field's value is bound from (← goctl's struct tags): the request body (json:, and an untagged field), the query string (form:), a URL segment (path:), or a request header (header:).

  • Body
  • Query
  • Path
  • Header

Methods

pub fn Bind::equal(Self, Self) -> Bool
pub fn Bind::not_equal(Self, Self) -> Bool

pub(all) struct Diagnostic

One finding of validate: how bad it is, the rule that produced it, the at — the route, type or field it is about — and a sentence saying what is wrong.

FieldType
severitySeverity
ruleString
atString
messageString
  • pub impl Show for Diagnostic

Methods

pub fn Diagnostic::output(Self, &Logger) -> Unit
pub fn Diagnostic::to_string(Self) -> String

pub(all) struct Field

One field of a type block: its name, the (already MoonBit-mapped) type, and the raw back-tick struct tag (json:"…"/path/form/header, empty when absent) that carries the wire name and binding location.

FieldType
nameString
type_String
tagString

Methods

pub fn Field::bind(Self) -> Bind

Where this field's value is bound from: form: off the query string, path: out of a URL segment, header: off a request header, and everything else — an untagged field included — out of the request body.

pub fn Field::default_(Self) -> String?

The default= this field's tag declared, written the way the spec wrote it, or None when it declared none.

pub fn Field::json_name(Self) -> String

The name this field is carried under on the wire: the one its binding tag gives (json:"user_name" → user_name, form:"page" → page, path:"region" → region), with the options after it stripped, falling back to the field's own name when it carries no tag.

pub fn Field::mbt_name(Self) -> String

The MoonBit spelling of this field: snake_case, because a MoonBit struct field has to start lower-case — UserName is not one. Every generator that emits MoonBit names the field with this, so the struct, the row decoder and the column projection all agree; json_name is the wire side of the same field.

pub fn Field::optional(Self) -> Bool

Whether the tag marked this field optional (or Go's omitempty): it may be absent, which is what keeps it out of a schema's required list.

pub fn Field::options(Self) -> Array[String]

The values an options=a|b|c tag allows this field to take, empty when the tag declared no such list.

pub fn Field::range(Self) -> Range?

The range=[lo:hi] bounds this field's tag declared, or None when it declared none. Either bound may be empty, which leaves that end open.

pub(all) struct Group

The @server( … ) annotations governing a block of routes (← goctl's route group): the name under which its routes are grouped, the path prefix already folded into their paths, the jwt claim type, the middleware chain, the max_bytes request cap (0 when unset), the request timeout, and whether the group's requests are signed. extra keeps every other annotation the block carried, in order — goctl lets a spec invent its own, and dropping them would lose what the author wrote.

FieldType
nameString
prefixString
jwtString
middlewareArray[String]
max_bytesInt64
timeoutString
signatureBool
extraArray[(String, String)]

pub(all) struct Range derive(Eq)

A range= constraint, e.g. range=[1:120] or range=(0:]. Each bound is written as the spec wrote it and is empty when that end is open; lo_inc / hi_inc say whether the bracket was inclusive ([ ]) or exclusive (( )).

FieldType
loString
hiString
lo_incBool
hi_incBool

Methods

pub fn Range::equal(Self, Self) -> Bool
pub fn Range::not_equal(Self, Self) -> Bool

pub(all) struct Route

One route in a service spec: HTTP verb (lower-cased), path pattern (with its group's prefix applied), handler name, an optional summary, and the @server group it was declared under. A modern goctl route (verb /path (Req) returns (Resp)) also carries its request/response type names (its @doc fills summary); both are empty for the legacy inline form (verb /path handler "summary").

FieldType
verbString
pathString
handlerString
summaryString
reqString
respString
groupGroup?

pub(all) enum Severity derive(Eq)

How bad a finding is: Error means the generated code would not compile or would not match the spec, Warning means it would compile but probably is not what the author meant.

  • Error
  • Warning

Methods

pub fn Severity::equal(Self, Self) -> Bool
pub fn Severity::not_equal(Self, Self) -> Bool

pub(all) struct Spec

A parsed .api service specification. groups lists the @server( … ) blocks in the order they were declared; each route also points at the one it belongs to. imports holds the import paths exactly as the file wrote them — relative to the file itself, so resolving one needs the path it was read from; deps and parse_all do that.

FieldType
serviceString
routesArray[Route]
typesArray[TypeDef]
infoArray[(String, String)]
groupsArray[Group]
importsArray[String]

pub(all) struct TypeDef

A named message schema declared by a type Name { field: Type … } block, generated into a MoonBit struct (goctl's request/response types). embeds names the blocks it inlined — a bare Base line — whose fields belong to it as if they had been written out; an anonymous nested block instead becomes a TypeDef of its own, named after the two blocks, with a field pointing at it.

FieldType
nameString
fieldsArray[Field]
embedsArray[String]

cli #

moonbitstack/moonctl/cli33 public items

Values

pub fn bug_report(String, String, Array[(String, String)]) -> String

mctl bug: a report with the environment filled in and the questions a maintainer would otherwise have to ask. title may be empty, in which case the report asks for one.

pub fn built_binary(String) -> String?

The executable a moon run --build-only built, from what it prints.

pub fn command_names() -> Array[String]

The words a shell should complete at the first position.

pub fn commands() -> Array[Command]

Every command mctl accepts, in the order help prints them: the generators, the scaffolds, the spec tools, then the housekeeping.

pub fn completion(String) -> String

A shell completion script for shell, or "" for a shell mctl has none for. Completion is generated from commands and subcommands, so a new command is completable the moment it is in the table.

pub fn config_get(Config, String) -> String?

The value of one key, or None when mctl has no such key.

pub fn config_keys() -> Array[String]

The keys config get and config set accept.

pub fn config_set(Config, String, String) -> Config

c with one key set. template appends — a config may name several — while a scalar key replaces what was there. An unknown key is returned unchanged, so a caller checks the key against config_keys first.

pub fn config_text(Config) -> String

The configuration as the file it is stored in, with a comment saying what the file is for and where the keys come from.

pub fn default_config() -> Config

The file mctl writes when there is none yet: the bundled library, the default branch, the gozero spelling.

pub fn env_report(String, Array[(String, String)]) -> String

mctl env: one line per setting, then a hint at what to change. rows pairs a setting with its value and, in parentheses, where it came from.

pub fn find_template(String) -> TemplateEntry?

The template called name, or None.

pub fn is_skipped(String) -> Bool

Whether a directory is left out of the walk: what the build itself writes, and anything hidden.

pub fn is_watched(String) -> Bool

Whether a save to this file calls for a rebuild: MoonBit source, or the manifests that say how it is built.

pub fn migrate_config(String) -> (String, Array[String])

A v1 configuration — the uppercase, environment-style keys mctl read before it had a file — rewritten as the current shape. Returns the new text and one line per key that changed, so mctl config migrate can say what it did.

pub fn mod_pins(String) -> Array[(String, String)]

The version strings of mod, as (name, version) pairs: every pin the file carries, in order.

pub fn parse_config(String) -> Config

Read a configuration. A key mctl does not know is kept out of the result rather than refused, so a file written by a newer mctl still loads. An empty or unreadable-text file is the default configuration.

pub fn parse_serve(ArrayView[String]) -> Serve raise

Read mctl serve [package] [--reload] [--reload-dir dir]... [--reload-delay seconds] [-- args]. Everything after -- is the server's own.

pub fn pin_module(String, String, String) -> (String, String?)

mod with name pinned at version, or mod unchanged when it does not pin that name. Returns the new text and the change it made, if any.

pub fn pinned_version(String, String) -> String?

The version name is pinned at in mod, or None when the file does not pin it.

pub let reload_delay : Int32

How long to wait between looks at the sources, in milliseconds (← uvicorn's --reload-delay, 0.25 seconds).

pub let reload_dirs : Array[String]

Which directories are watched when none are named (← uvicorn's --reload-dir, the current directory).

pub fn subcommands(String) -> Array[String]

The second word of a command that takes a sub-command, for a completion script that completes two levels deep.

pub fn template_detail(TemplateEntry) -> String

mctl template show <name>: one entry, and where it sits in the library.

pub fn template_table() -> String

mctl template list: a table a reader scans rather than a paragraph they read.

pub fn templates() -> Array[TemplateEntry]

The bundled library, in the order it is listed.

pub fn templates_of(String) -> Array[TemplateEntry]

The templates of one kind — the ones a gen of that kind may pick.

pub fn upgrade_pins(String, Array[String], String) -> (String, Array[String])

mctl upgrade <version>: every name in modules moved to version, plus one line per name that changed. A name the file does not pin is left alone and reported as skipped — pinning it would be a change the user did not ask for.

pub fn usage_text(String) -> String

The mctl help page: what mctl is, then one line per command, then the flags every generator shares.

Types

pub(all) struct Command

One command: what it is called, the line that shows how to call it, and one sentence saying what it does.

FieldType
nameString
usageString
summaryString

pub(all) struct Config

One configuration: the fields mctl understands. version is the file format, not the mctl version, and it goes up when migrate_config learns a new shape.

FieldType
versionInt32
homeString
remoteString
branchString
styleString
templatesArray[String]

pub(all) struct Serve

What mctl serve was asked to do: the package to build and run, whether to rebuild it on change, where and how often to look, and the arguments that go to the server.

FieldType
pkgString
reloadBool
dirsArray[String]
delayInt32
argsArray[String]

pub(all) struct TemplateEntry

One template: the name a user types, the kind of spec it reads, one sentence on what it produces, and the directory under the template home it lives in.

FieldType
nameString
kindString
descriptionString
pathString

client #

moonbitstack/moonctl/client4 public items

Values

pub fn client_file(@api.Spec, Lang) -> (String, String)

The file name and the source of the client lang for spec, which is what mctl api ts <file.api> writes.

pub fn client_file_name(Lang, String) -> String

The file a client for service lands in: greet_client.ts and friends, named after the service so two specs generated into one directory do not collide.

pub fn generate_client(@api.Spec, Lang) -> String

Generate the client of lang for spec. The result is one file: the models the spec declares, then the client class, in that order, so a reader meets the data before the calls that carry it.

Types

pub(all) enum Lang

The language a client is generated for: the four goctl generates or that the community asks for.

  • TypeScript
  • Dart
  • Kotlin
  • Java

Methods

pub fn Lang::ext(Self) -> String

The file extension a client of this language carries (ts, dart, kt, java).

pub fn Lang::label(Self) -> String

How the language is spelled in a comment, e.g. TypeScript.

doc #

moonbitstack/moonctl/doc6 public items

Values

pub fn generate_doc(@api.Spec, version? : DocVersion, title? : String, api_version? : String) -> String

Generate an OpenAPI / Swagger document from spec, stringified with two-space indentation. version picks the dialect (Swagger 2.0 / OpenAPI 3.0 / 3.1).

pub fn generate_markdown(@api.Spec, title? : String) -> String

The whole reference: the service, a route table, then a table per type. title replaces the service name in the heading for a reader who wants the document to say what the service is for.

pub fn markdown_file_name(String) -> String

The file name a Markdown reference lands in: greet → greet_api.md.

pub fn openapi_document(@api.Spec, version? : DocVersion, title? : String, api_version? : String) -> Json

Build the OpenAPI / Swagger document for spec as a Json value. Routes fold into paths → HTTP method → operation (with operationId, any :name path parameters, and a 200 response); every type block becomes a component schema (definitions in 2.0, components/schemas in 3.x). version selects the document dialect; title/api_version fill the info block.

pub fn swagger_ui_stub(spec_url? : String, title? : String) -> String

A self-contained Swagger UI page for the document served at spec_url. The same stub moonapi ships, so a generated service and a live app render alike.

Types

pub(all) enum DocVersion derive(Eq)

Target OpenAPI / Swagger document version. mctl emits every mainstream version from one .api spec — the same shape moonapi's runtime emitter takes, so a generated service and a hand-built moonapi app document the same way.

  • Swagger20
  • OpenApi30
  • OpenApi31

Methods

pub fn DocVersion::equal(Self, Self) -> Bool
pub fn DocVersion::not_equal(Self, Self) -> Bool

gen #

moonbitstack/moonctl/gen8 public items

Values

pub fn generate(@api.Spec, template? : String) -> String raise @template.TemplateError

Generate compilable moonapi scaffolding from a spec: a MoonBit struct for every type block, a build_app that wires every route to its handler, plus a stub for each handler. The routing part depends only on moonbitstack/moonapi and moonbitstack/moonasgi; the emitted schemas are dependency-free.

Pass template to render the spec through the runtime template engine (see generate_with) instead of the built-in generator; omit it for the default scaffold.

pub fn generate_builtin(@api.Spec) -> String
pub fn generate_with(@api.Spec, String) -> String raise @template.TemplateError

Generate code from a Spec with a caller-supplied template instead of the built-in generator — the runtime-template path goctl exposes for custom scaffolds. Equivalent to render(template_source, spec_to_value(spec)).

pub fn group_note(@api.Group) -> String

A group's annotations spelled the way the spec wrote them, e.g. group: user, prefix: /api/v1, middleware: Log. Empty for a group that carries nothing.

pub fn number_json(String) -> Json

raw as a JSON number, or as a string when it does not read as one — a tag option is text until something asks it to be a number.

pub fn render_structs(Array[@api.TypeDef]) -> String

A MoonBit struct for every type block, in the order the spec declared them, each followed by whatever its tags asked to be checked (see render_checks).

pub fn route_path(String) -> String

A spec path as the route template moonapi reads: each :name segment of the spec becomes {name}.

pub fn spec_to_value(@api.Spec) -> @template.Value

Expose a parsed .api Spec as template Value data: a Dict with service (string), routes (list of {verb, path, handler, summary, hasSummary, group, hasGroup}), types (list of {name, fields:[{name, type}]}), groups (list of the @server blocks) and hasTypes (bool). This is what the template-driven generator ranges over.

gql #

moonbitstack/moonctl/gql1 public item

Values

pub fn generate_gql(@api.Spec) -> String

Generate a moongql code-first schema from spec's type blocks. Each type becomes an object type with its fields mapped to GraphQL types, and the Query root has ping: String! plus a <type>(id: ID!): <Type> lookup per type.

Only the schema is generated: the resolvers are the author's code. A root field needs one; an object field without one reads its parent's member of that name.

model #

moonbitstack/moonctl/model19 public items

Values

pub fn cache_file_name(String) -> String

The file a cached layer lands in: greet → greet_cache.mbt, beside the <service>_model.mbt whose records it caches.

pub fn generate_cached(@api.Spec) -> String

Generate the cached CRUD layer for every table of spec: for a type block with a field to look records up by, the key function plus read-through find, invalidating write, and evict. A block with no single-valued field has no key to cache under, so it gets no layer and the file says why.

The output needs no import and no driver: the record types it names are the ones mctl model generates for the same spec.

pub fn generate_crud(Array[DdlTable]) -> String

Generate a moonorm data-access layer from parsed DDL: for every table, the record struct, its @moonorm.Model (columns + from_row + to_columns), a @moonorm.Table descriptor, an up/down migration pair, and typed CRUD (insert/all, plus find_by_id/update/delete_by_id when the table has a single-column primary key). The output compiles against moonbitstack/moonorm + moonbitstack/moondb; a consuming package imports both. This is the .sql-schema counterpart of goctl's model mysql ddl.

pub fn generate_crud_from_ddl(String) -> String

Parse a SQL DDL script and generate its moonorm data-access layer in one step.

pub fn generate_crud_from_reflection(Array[ReflectedColumn]) -> String

Generate a moonorm data-access layer (models + typed CRUD) straight from a live schema's reflected columns — the in-memory counterpart of generate_crud_from_ddl. The reflect sub-package produces the ReflectedColumns from a real connection.

pub fn generate_migrations(@api.Spec) -> String

The migration file for a spec: one CREATE TABLE per type. service names the file and the header, so two specs migrated into one directory do not look alike.

pub fn generate_model(@api.Spec) -> String

Generate a moonorm data layer for every type block in spec. A block whose fields are all storable yields: the model struct; a <table>_model : @moonorm.Model[T] built with @moonorm.Model::new — declared columns (an id column is the primary key), a from_row decoder, and the to_columns projection an INSERT binds; a <table>_table : @moonorm.Table descriptor; and a <table>_up / <table>_down migration pair (create the table idempotently / drop it). This is the explicit MoonBit stand-in for a SQLAlchemy declarative class plus an Alembic revision, which reflection would otherwise synthesise. A block with a non-storable field (a slice, map, or nested message) still gets its struct and a plain @moonorm.Table descriptor.

The output compiles against moonbitstack/moonorm + moonbitstack/moondb; a consuming package imports both.

pub fn generate_mongo(@api.Spec) -> String

Generate a Mongo document model for every type block of spec: a Doc struct that is the document as stored, and a Repo over the Collection port with insert, all, and — when the spec has a key field — find, replace and delete.

The output compiles against MoonBit core: Json and ToJson are builtin, and the file imports moonbitlang/core/json as @json for from_json. A driver supplies the port; without one, nothing here needs a database to typecheck.

pub fn migrate_file_name(String) -> String

The name a migration file takes: greet → greet_migrate.sql.

pub fn mongo_file_name(String) -> String

The file a document model lands in: greet → greet_mongo.mbt, named after the service so two specs generated into one directory do not collide.

pub fn parse_ddl(String) -> Array[DdlTable]

Parse a SQL DDL script into its CREATE TABLE definitions. Recognises CREATE TABLE [IF NOT EXISTS] name ( … ) (quoted or bare name), skipping any other statement. Column types, primary keys (column- or table-level), NOT NULL and DEFAULT clauses are captured; everything needed to emit a moonorm model.

pub fn parse_dsn(String) -> DataSource raise DataSourceError

Parse a datasource DSN into a DataSource. Recognised forms:

  • SQLite: sqlite:PATH, sqlite://PATH, sqlite3:PATH, file:PATH, the literal :memory:, or a bare path ending in .db / .sqlite / .sqlite3.
  • PostgreSQL: postgres://[user[:password]@]host[:port][/database][?…] (and the postgresql:// spelling). The port defaults to 5432, the user to postgres; the database name is required.

Raises BadDsn on an unrecognised scheme or a PostgreSQL URL missing its host or database.

pub fn tables_from_reflection(Array[ReflectedColumn]) -> Array[DdlTable]

Fold reflected columns into DdlTables, grouping by table in first-seen order and mapping each raw SQL type onto its MoonBit scalar (the leading type keyword drives the mapping, so character varying and VARCHAR(255) both land on String). The result feeds generate_crud, so a live schema and a .sql file reach the same model generator.

Errors

pub suberror DataSourceError

Raised when a DSN string cannot be parsed into a DataSource.

  • BadDsn(String)

Types

pub(all) enum DataSource

A parsed datasource DSN: which backend to read, and how to reach it.

  • Sqlite(String)
  • Postgres(PgTarget)

pub(all) struct DdlColumn

One parsed column of a CREATE TABLE statement: the SQL column name, the MoonBit type_ its SQL type maps to (Int/Int64/String/Double/Bool/ Bytes), whether it is a primary key, whether it accepts NULL, and its literal DEFAULT clause if any (kept as source text — it is emitted into DDL comments, never bound).

FieldType
nameString
type_String
mut primary_keyBool
nullableBool
default_String?

pub(all) struct DdlTable

A parsed CREATE TABLE: the SQL table name and its ordered columns.

FieldType
nameString
columnsArray[DdlColumn]

pub(all) struct PgTarget

A PostgreSQL connection target parsed from a postgres:// DSN.

FieldType
hostString
portInt32
userString
passwordString
databaseString

pub(all) struct ReflectedColumn

One column of a reflected database schema: the table it belongs to, its name, its raw SQL type text (INTEGER, character varying, VARCHAR(255), …), and whether it is a primary key / accepts NULL. This is the neutral shape a live reader (SQLite PRAGMA table_info, PostgreSQL information_schema.columns) produces and tables_from_reflection folds into DdlTables.

FieldType
tableString
nameString
sql_typeString
primary_keyBool
nullableBool

plugin #

moonbitstack/moonctl/plugin11 public items

Values

pub fn gen_files_to_json(Array[GenFile]) -> Json

Serialise a list of generated files into the plugin-reply JSON — the writer a MoonBit plugin uses on its stdout. Emits the {"files": [...]} envelope.

pub fn parse_gen_files(Json) -> Array[GenFile]

Parse a plugin's stdout into the files to write. Two shapes are accepted: a bare array [{path, content}, …], or an object {"files": [ … ]} (goctl-style envelope). An element missing path or content is skipped. The list preserves the plugin's order.

pub fn plugin_argv(String) -> (String, Array[String])

Split a plugin invocation into the program to run and the arguments to run it with, the way goctl reads its -plugin value: the first whitespace-separated word is the executable, the rest are its argv. A quoted word keeps its spaces.

pub fn plugin_from_json(Json) -> Plugin

Read the request a plugin was handed on stdin. Missing members degrade to empty rather than raising, so a hand-written request still parses.

pub fn plugin_plan(Array[GenFile]) -> (Array[GenFile], Array[String])

What a plugin run will actually write: the files whose path is safe, and a note per file that was refused or superseded. A later file for a path an earlier one already claimed is refused rather than silently overwriting it — a plugin that emits the same file twice has a bug, and the report should say so rather than leave a coin-flip in the output.

pub fn plugin_request(@api.Spec, api_file_path? : String, style? : String, dir? : String) -> String

The plugin request as a two-space-indented JSON string, ready to write to the plugin's stdin: goctl's four keys — the spec under Api, plus the file it was read from, the --style template and the output directory, which is everything a plugin needs to decide where its output goes and what to call it.

pub fn safe_path(String) -> Bool

Whether a path a plugin supplies lands inside the directory mctl writes to. A plugin runs as its own process and its reply is arbitrary text, so the one thing mctl must not do is believe it: ../../.ssh/authorized_keys, /etc/passwd and C:/Windows/system32/… are all accepted by a naive writer, and all three write where a code generator has no business writing. Only a relative path with no .. segment is allowed; a path with one is refused and named in the run's report.

pub fn spec_from_json(Json) -> @api.Spec

Reconstruct a Spec from the request JSON — the reader a plugin written in MoonBit uses on its stdin. The whole request ({Api, ApiFilePath, Style, Dir}) and a bare spec are both accepted, so a plugin that wants nothing but the routes need not unwrap the envelope. Missing or mistyped members degrade to empty rather than raising, so a partial request still parses.

pub fn spec_to_json(@api.Spec) -> Json

Serialise a Spec into the plugin request JSON. The shape mirrors the Spec itself — service, routes (verb/path/handler/summary, plus the group the route was declared under), types (name plus fields of name/type) and groups — so a plugin in any language parses it with an ordinary JSON reader. type_ is written as type, the name a caller expects.

Types

pub(all) struct GenFile

One file a plugin asks mctl to write: a destination path (relative to the output directory) and its full content.

FieldType
pathString
contentString

pub(all) struct Plugin

What a plugin is handed on stdin (← goctl's plugin.Plugin): the parsed spec under api, the .api file it was read from, the --style naming template, and the directory the generated tree goes under.

FieldType
api@api.Spec
api_file_pathString
styleString
dirString

proto #

moonbitstack/moonctl/proto19 public items

Values

pub fn commas(Array[String]) -> String

Join parts with ", " — the codegen workhorse for column/argument lists.

pub fn default_routes(Proto) -> Array[GatewayRoute]

Every RPC of proto as the default route: POST /<Service>/<Method> — the gRPC path with its package dropped, because a gateway in front of one package does not need the package repeated in the URL. A POST is the method gRPC itself uses, so the mapping is the one that always works.

pub fn gateway_file_name(String) -> String

The file a gateway lands in: the .proto's own name, without its directory and without its extension — proto/greet.proto → greet_gateway.mbt. A .proto may declare several services, so the file name comes from the file rather than from one of them.

pub fn generate_gateway(Proto, Array[GatewayRoute]) -> String

Generate the gateway for proto with routes: the route table, the gateway itself, and the two entry points — handle, which takes a JSON body already parsed, and handle_text, which parses the body a request carried.

Status codes are the four an HTTP client cares about: 200 for a reply, 400 for a body that is not JSON, 404 for a path no route answers, and 502 for a call the upstream failed. A gRPC status does not leak through: an HTTP client reads it where it is meaningful — in the reply body.

pub fn generate_grpc(Proto) -> String

Generate a moonrpc service stub from a parsed .proto: a MoonBit struct per message, a @moonrpc.Method descriptor per RPC (its gRPC :path is /package.Service/Method), a <Service>Server handler-registration struct (one synchronous-core handler field per RPC, each returning its reply or a gRPC @moonrpc.Status), and a <service>_methods() listing. The output compiles against moonbitstack/moonrpc.

pub fn has_method(Proto, String) -> Bool

Whether proto declares the gRPC method target (/package.Service/Method), so a hand-written route that names a method the spec does not have is caught here rather than at the first request.

pub fn parse_proto(String) -> Proto

Parse a minimal .proto (proto3). Recognises the package declaration, service blocks with their rpc methods (including stream), message blocks with scalar/repeated/map fields, and top-level enum declarations. syntax, import, and option are skipped.

syntax = "proto3";
package greet;
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest { string name = 1; }
message HelloReply   { string message = 1; }
pub fn parse_route_map(Proto, String) -> (Array[GatewayRoute], Array[String])

The routes a mapping file declares, in the order it declares them. A line is VERB /path /package.Service/Method; # starts a comment, and a blank line is skipped. A line naming a method the .proto does not declare, or one that streams, is left out — skipped reports it so the caller can say which.

pub fn proto_reserved_conflicts(ProtoMessage) -> Array[String]

The names of m's fields (oneof members included) that reuse a reserved field number or name — protobuf forbids reusing either, and this surfaces an accidental reuse. Empty when the message is clean.

Types

pub(all) struct GatewayRoute

One HTTP route and the gRPC method behind it: the verb and path the gateway answers, and the fully-qualified method it forwards to.

FieldType
verbString
pathString
rpcString

pub(all) enum Label derive(Eq, @debug.Debug)

Whether a field holds one value, a list, or a map with proto key and value types.

  • Single
  • Repeated
  • MapOf(key~ : String, value~ : String)

Methods

pub fn Label::equal(Self, Self) -> Bool
pub fn Label::not_equal(Self, Self) -> Bool
pub fn Label::to_repr(Self) -> @debug.Repr

pub(all) struct Proto

A parsed .proto file: its package (empty when none) and the services and messages it declares.

FieldType
package_String
servicesArray[ProtoService]
messagesArray[ProtoMessage]
enumsArray[ProtoEnum]

pub(all) struct ProtoEnum

A protobuf enum declaration, generated into a MoonBit enum plus an integer mapping (proto3 enums are int-backed, and the value numbered 0 is the default).

FieldType
nameString
valuesArray[ProtoEnumValue]

pub(all) struct ProtoEnumValue

One value of a protobuf enum: its name and its integer number.

FieldType
nameString
numberInt32

pub(all) struct ProtoField

One field of a protobuf message: its name, its MoonBit type (repeated is Array[T], map<K, V> is Map[K, V]), its proto element type as written, its label and its wire number.

FieldType
nameString
type_String
protoString
labelLabel
numberInt32

pub(all) struct ProtoMessage

A protobuf message declaration, generated into a MoonBit struct. oneof groups are lifted out of fields into oneofs; reserved field numbers and names are recorded so a reused one can be caught.

FieldType
nameString
fieldsArray[ProtoField]
oneofsArray[ProtoOneof]
reserved_numbersArray[Int32]
reserved_namesArray[String]

pub(all) struct ProtoOneof

A protobuf oneof group: its name and the members (exactly one may be set). Generated into a MoonBit enum — the faithful equivalent of the "exactly one" invariant, which flattening to optional fields would lose.

FieldType
nameString
variantsArray[ProtoField]

pub(all) struct ProtoService

A protobuf service declaration and its RPC methods.

FieldType
nameString
rpcsArray[Rpc]

pub(all) struct Rpc

One rpc method of a service: its name, request and response message names, and whether either side is a stream (client/server/bidi streaming).

FieldType
nameString
requestString
responseString
client_streamingBool
server_streamingBool

scaffold #

moonbitstack/moonctl/scaffold16 public items

Values

pub fn generate_gql_tree(@api.Spec, style? : @style.Style, dir? : String) -> Array[TreeFile]

The layered GraphQL tree for spec under dir: internal/schema with build_schema() (rewritten on every run), internal/logic with the resolvers and a test that queries ping, internal/config/internal/svc (seeded once), and the entry point serving graphql_app on 12000.

Hand the result to tree_plan to keep what the author has filled in.

pub fn generate_mcp_tree(String, style? : @style.Style, dir? : String) -> Array[TreeFile]

The MCP server tree for module module_ under dir: the shared module, configuration and context, internal/tools with the annotated functions, their generated registration and a test, and the build rule that keeps the registration in step with the functions.

pub fn generate_rpc_tree(@proto.Proto, style? : @style.Style, dir? : String) -> Array[TreeFile]

The layered gRPC tree goctl writes for a .proto, in MoonBit, under dir: pb/ with the messages, codecs and handler tables (rewritten on every run), internal/logic with one function per RPC and internal/config/internal/svc (seeded once), internal/server wiring the logic into each service, client/ with a typed client per service, and the entry point serving it all on 12000.

Hand the result to tree_plan to keep what the author has filled in.

pub fn generate_tree(@api.Spec, style? : @style.Style, dir? : String) -> Array[TreeFile]

Generate the layered project tree goctl writes, in MoonBit: the service entry point and its moon.mod, etc/<service>.yaml, internal/config, internal/svc, internal/types, internal/handler (the generated routes plus a stub per handler, under internal/handler/<group>/ for a grouped route), internal/logic, internal/middleware for every middleware an @server block named, and a moon.pkg for each of those packages.

style (default gozero) names the files and the handler, logic and middleware entry points inside them. Names the spec itself chose — the type blocks and their fields — are left as written, since a MoonBit type name has to keep its capital. dir puts the whole tree under a directory.

Each file says whether a regeneration may overwrite it; hand the result to tree_plan to apply that.

pub let pins : Map[String, String]

The version of each library generated code imports.

These are the versions this repository's CI scaffolds a project against and builds, so a generated project is promised to compile with them. A project that wants a later release edits its own moon.mod.

pub let port : Int32

The port a scaffolded service listens on.

12000, the one every server in this family defaults to: HTTP, WebSocket and h2c share it because one listener tells them apart, so a generated manifest and a generated configuration name the same number without anyone saying which they meant.

pub fn scaffold_api(String) -> Array[@plugin.GenFile]

Scaffold a moonapi service under <name>/: goctl's api new. The layered tree of generate_tree for a sample spec with GET /ping, a test calling it, and an entry point serving it on mooncat.

pub fn scaffold_docker(String, port? : Int32) -> Array[@plugin.GenFile]

Scaffold container files for a native mctl-generated service: a Dockerfile (a MoonBit build stage that produces the native binary, then a slim runtime stage that runs it) and a .dockerignore. name is the binary/image name, port the port the service listens on. goctl's goctl docker.

pub fn scaffold_gql(String) -> Array[@plugin.GenFile]

Scaffold a moongql service under <name>/: the layered tree of generate_gql_tree for a sample spec, with a ping resolver and a test querying it.

pub fn scaffold_kube(String, port? : Int32, replicas? : Int32) -> Array[@plugin.GenFile]

Scaffold a Kubernetes deployment for the service under deploy/: a Deployment (replicas pods of the <name> image, a container port, and a liveness probe on /ping) and a Service exposing it. goctl's goctl kube deploy.

The manifests are built as values and written by moonyaml, not joined out of string fragments. A generator that joins fragments has the indentation in its string literals, where a missed space is invisible, and quotes nothing — so the first service name with a colon in it emits a file Kubernetes reads as something else.

pub fn scaffold_mcp(String) -> Array[@plugin.GenFile]

Scaffold an MCP server under <name>/: annotated tools, a resource and a prompt, a test calling the tool, and an entry point serving them over Streamable HTTP or, with --stdio, over stdio.

pub fn scaffold_model(String) -> Array[@plugin.GenFile]

Scaffold a moonorm data-layer project under <name>/: a moon.mod (depending on the published moonorm + moondb), a sample schema.sql, its generated models + CRUD in src/model.mbt (through the same generate_crud_from_ddl as gen crud), and a README. goctl's goctl model … new.

pub fn scaffold_rpc(String) -> Array[@plugin.GenFile]

Scaffold a moonrpc service under <name>/: goctl's rpc new. The layered tree of generate_rpc_tree for a sample proto with a Ping that answers pong, and a test serving it and calling it through the typed client.

pub fn tree_plan(Array[TreeFile], (String) -> Bool) -> Array[@plugin.GenFile]

The files of tree a run should actually write, given a way to ask whether a path is already on disk. A file moonctl owns (Always — the routes and the types) is always written; anything else is written only when it is not there yet, so a second run refreshes what follows the spec and leaves every handler and logic body the author has since filled in exactly as it is.

Types

pub(all) enum Regen derive(Eq)

Whether a regeneration may replace a file that is already on disk. Always is for what moonctl owns — the routes and the types, which must follow the spec — and Once for what it only seeds: handlers, logic, configuration, manifests.

  • Always
  • Once

Methods

pub fn Regen::equal(Self, Self) -> Bool
pub fn Regen::not_equal(Self, Self) -> Bool

pub(all) struct TreeFile

One file of a generated project tree: where it goes, what is in it, and whether regenerating the tree is allowed to overwrite it.

FieldType
pathString
contentString
regenRegen

style #

moonbitstack/moonctl/style2 public items

Errors

pub suberror StyleError

A --style template that is not <before>GO<through>ZERO<after>: either a marker is missing (go, zero), they are the wrong way round, or one is cased neither go/GO/Go nor zero/ZERO/Zero (gOZero, goZEro).

  • BadStyle(String)

Types

pub struct Style

A --style naming template (← goctl's --style), ready to spell names with. Build one with Style::parse, apply it with Style::format.

FieldType
beforeString
throughString
afterString
headCase
tailCase

Methods

pub fn Style::format(Self, String) -> String

Spell name in this style. name is split into words on _ and before each capital, the first word takes the GO marker's case and the rest take ZERO's, and they are joined with whatever stood between the markers.

pub fn Style::gozero() -> Self

goctl's default style, gozero: every word lower-cased and run together.

pub fn Style::parse(String) -> Self raise StyleError

Read a --style template. It must contain GO and then ZERO — in any case, with anything before, between and after them:

Style::parse("gozero").format("welcome_to_go_zero")  // welcometogozero
Style::parse("goZero").format("welcome_to_go_zero")  // welcomeToGoZero
Style::parse("go_zero").format("welcome_to_go_zero") // welcome_to_go_zero
Style::parse("Go#zero").format("welcome_to_go_zero") // Welcome#to#go#zero

The GO marker's own casing (go, GO or Go) says how the first word is spelled, ZERO's says how every later word is, and what stands between the two markers is what stands between the words. A template missing a marker (go, zero), holding them in the wrong order, or casing one of them any other way (gOZero, goZEro) raises StyleError.

template #

moonbitstack/moonctl/template5 public items

Values

pub fn render(String, Value) -> String raise TemplateError

Parse and render source against data in one call, with the default function library.

Errors

pub suberror TemplateError

A template parse or execution failure, carrying a human-readable message.

  • ParseError(String)
  • ExecError(String)

Types

pub struct Template

A parsed, reusable template — moonctl's text/template equivalent. Build it with Template::new, register extra functions with func, parse a source with parse, then render it against a Value any number of times. The parsed node tree stays private, captured inside renderer.

FieldType
mut renderer(Value) -> String raise TemplateError
funcsMap[String, (Array[Value]) -> Value raise TemplateError]

Methods

pub fn Template::func(Self, String, (Array[Value]) -> Value raise TemplateError) -> Self

Register (or override) a pipeline function, returning self for chaining — the analogue of Go's Template.Funcs. Register before parse.

pub fn Template::new() -> Self

A fresh template preloaded with the default function library. Rendering before parse yields the empty string.

pub fn Template::parse(Self, String) -> Self raise TemplateError

Parse source into this template's node tree, returning self for chaining. Raises ParseError on a syntax error (unclosed action, dangling {{end}}, …).

pub fn Template::render(Self, Value) -> String raise TemplateError

Render the template against data, producing the output string. Raises ExecError on an execution fault (undefined variable/function, bad range target, …).

pub(all) enum Value

Dynamic template data. .Field lookups resolve against Dict; range iterates List (index/element) or Dict (sorted key/value). This is the explicit stand-in for the arbitrary Go values goctl reflects over.

  • Null
  • Bool(Bool)
  • Int(Int64)
  • Float(Double)
  • Str(String)
  • List(Array[Value])
  • Dict(Map[String, Value])

Aliases

pub type FuncFn = (Array[Value]) -> Value raise TemplateError

A pipeline function: it receives the already-evaluated argument list (with the piped-in value, if any, appended last, mirroring Go) and returns a Value.