Sign in

    moonbitstack/moonapi/schema does not have a README file

    ToSchema

    pub(open) trait ToSchema {
    fn to_schema(Self) -> Schema
    }

    The impl-able version of a type's descriptor. A user struct implements it — the value is ignored; it exists so descriptor-carrying code can be generic over "a type that knows its own schema". The primary, mctl-friendly shape is still a plain associated function T::schema() -> Schema (no instance needed, mirroring FastAPI referencing the model class); this trait bridges to it.

    Constraint

    pub(all) enum Constraint {
    Minimum(Double)
    Maximum(Double)
    ExclusiveMinimum(Double)
    ExclusiveMaximum(Double)
    MultipleOf(Double)
    MinLength(Int)
    MaxLength(Int)
    Pattern(String)
    MinItems(Int)
    MaxItems(Int)
    } derive(Eq,
    Debug
    )

    A value constraint on a field (JSON-Schema keyword ↔ Pydantic argument).

    Constraint::equal

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

    Constraint::not_equal

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

    Field

    pub(all) struct Field {
    name : String
    schema : Schema
    required : Bool
    description : String
    constraints : Array[Constraint]
    default : Json?
    } derive(Eq,
    Debug
    )

    One field of an object schema: its name, its schema, whether it is required, an optional description, its value constraints, and the default that stands in when a body leaves it out.

    Field::equal

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

    Field::is_required

    fn Field::is_required(self : Field) -> Bool

    Whether a body must carry this field. A field with a default never must — its absence is answered by the default, exactly as a Python default argument is, so it is left out of the emitted required list and not reported missing.

    Field::new

    fn Field::new(name : String, schema : Schema, required? : Bool, description? : String, constraints? : Array[Constraint], default? : Json) -> Field

    Build a field. required defaults to true (FastAPI treats a field without a default as required). constraints are the Pydantic-style value constraints (ge/le/min_length/pattern/…) that are both emitted into the field's OpenAPI schema and enforced when validating an inbound value. default is emitted into the schema and makes the field optional, since a value that has one is never missing.

    Field::not_equal

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

    Field::to_repr

    ObjectSchema

    pub(all) struct ObjectSchema {
    name : String
    fields : Array[Field]
    description : String
    } derive(Eq,
    Debug
    )

    The body of an object schema: its component name (empty = an anonymous inline object; non-empty = hoisted to components/schemas and referenced), its ordered fields, and an optional description.

    ObjectSchema::equal

    ObjectSchema::not_equal

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

    OpenApiVersion

    pub(all) enum OpenApiVersion {
    Swagger20
    OpenApi30
    OpenApi31
    } derive(Eq)

    Target OpenAPI / Swagger document version. moonapi emits every mainstream version from the same route descriptors — a "good FastAPI" is not pinned to one spec version.

    OpenApiVersion::equal

    OpenApiVersion::not_equal

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

    Schema

    pub(all) enum Schema {
    SStr
    SInt
    SFloat
    SBool
    SNull
    SArray(Schema)
    SObject(ObjectSchema)
    SEnum(Schema, Array[Json])
    SNullable(Schema)
    SMap(Schema)
    SAny
    SFormat(Schema, String)
    SJson(Json)
    } derive(Eq,
    Debug
    )

    A JSON-Schema type descriptor — the runtime, first-class value that stands in for FastAPI's from-signature reflection. One Schema tree is walked once to (a) emit a complete OpenAPI request/response body schema — objects, arrays and scalars, with required, and named objects hoisted under components/schemas and referenced by $ref — and (b) drive validation of an inbound JSON value. This is the explicit, MoonBit-idiomatic equivalent of pydantic's type-driven magic (cf. Rust serde + macros, Go struct tags + codegen). A named object carries its fields inline, so the same tree is fully self-describing for validation; the name is used only to deduplicate it into components on emit.

    Schema::array

    fn Schema::array(item : Schema) -> Schema

    An array schema whose elements all conform to item.

    Schema::binary

    fn Schema::binary() -> Schema

    The schema of file content: a string with OpenAPI's binary format — what an upload is described as, and what a multipart file field carries.

    Schema::equal

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

    Schema::format

    fn Schema::format(base : Schema, format : String) -> Schema

    base refined by an OpenAPI format. The format is documentation: it tells a reader and a client generator what the string holds, and validation still checks only base, which is what pydantic does for a format it has no validator for.

    Schema::json

    fn Schema::json(document : Json) -> Schema

    A schema written as JSON Schema itself (2020-12, which is what OpenAPI 3.1 is). Use it for what the other constructors cannot say; it goes into the document unchanged.

    Schema::map

    fn Schema::map(value : Schema) -> Schema

    An object with no declared fields whose values all conform to value (← dict[str, T]). Schema::map(SAny) is the free-form object.

    Schema::not_equal

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

    Schema::nullable

    fn Schema::nullable(inner : Schema) -> Schema

    A schema that also admits null (← Optional[T]). Wrapping rather than a flag because the three dialects express it three different ways.

    Schema::object

    fn Schema::object(name : String, fields : Array[Field]) -> Schema

    A named object schema: hoisted to components/schemas under name and referenced by $ref wherever it is used.

    Schema::of_model

    A moonmodel description as a schema.

    One description, written once, drives request validation and the OpenAPI document here, and the DDL and the SDL in their own libraries. known is where a Ref is looked up: a reference to a model that is not in it, or one that leads back to a model already being written, is reported instead — a schema is a finite value, so a cycle cannot be written out, and the name alone does not say what the thing looks like.

    Schema::to_repr

    Unresolved

    pub(all) struct Unresolved {
    field : String
    model : String
    why : String
    } derive(Eq)

    A reference that could not be written into the schema, and why.

    Reported rather than dropped or guessed at: a body schema silently missing a field is a validation hole that shows up as accepted-but-wrong data.

    Unresolved::equal

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

    Unresolved::not_equal

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

    ValidationError

    pub(all) struct ValidationError {
    loc : Array[String]
    msg : String
    kind : String
    }

    One entry in a 422 response's detail array, mirroring FastAPI / pydantic v2: where the error is (loc, e.g. ["query", "q"]), a human msg, and a machine kind (serialised as the JSON key type).

    ValidationError::missing

    fn ValidationError::missing(loc : Array[String]) -> ValidationError

    The canonical "a required parameter was not supplied" error located at loc, matching FastAPI's {"type": "missing", "msg": "Field required"}.

    ValidationError::to_json

    fn ValidationError::to_json(self : ValidationError) -> Json

    Render one validation error as its JSON object.

    ValidationError::type_error

    fn ValidationError::type_error(loc : Array[String], kind : String, msg : String) -> ValidationError

    A type/parse error located at loc, e.g. kind = "int_parsing" with the matching pydantic message — the shape FastAPI reports for a value of the wrong type.

    check_constraints

    fn check_constraints(value : Json, constraints : Array[Constraint], loc : Array[String], errs : Array[ValidationError]) -> Unit

    Enforce the constraints on an inbound value, appending a Pydantic-shaped ValidationError (located at loc) for each violation. A constraint that does not apply to the value's kind (a length bound on a number, say) is simply skipped, as pydantic does.

    emit_schema

    fn emit_schema(schema : Schema, defs : Map[String, Json], version : OpenApiVersion) -> Json

    Emit schema as inline OpenAPI JSON, hoisting every named object into defs (keyed by name) and referencing it by $ref. Recursion-safe: a name is reserved in defs before its body is built, so a self-referential schema terminates instead of looping.

    enum_expected

    fn enum_expected(values : Array[Json]) -> String

    The Pydantic-style "expected one of" fragment for an enum error: string members quoted, comma-separated, with a final or before the last.

    enum_member

    fn enum_member(values : Array[Json], v : Json) -> Bool

    Whether v is one of the allowed enum values.

    filter_response

    fn filter_response(model : Schema, value : Json) -> Result[Json, Array[ValidationError]]

    Validate value against model and, if it conforms, return it filtered down to the model's declared fields (extras dropped, nested objects and arrays projected too). On a mismatch return the located ValidationErrors under ["response"] — the same shape request validation produces. This is FastAPI's response_model: the outgoing shape is the model, not whatever the handler happened to build.

    json_model

    fn json_model(status : Int, model : Schema, value : Json) ->
    Response

    A JSON response whose body is value filtered through model. On success a status response carrying only the model's declared fields; on a model mismatch a 500 whose body lists the response-validation errors — the return value didn't match what the route promised, which is a server-side fault.

    parse_int

    fn parse_int(s : String) -> Int?

    Parse a base-10 integer, None if s is not a well-formed integer literal (optional leading +/-, then one or more ASCII digits, nothing else).

    Not core's @strconv.parse_int: that one also takes 0x prefixes and underscores, which a query or path parameter must not quietly accept.

    query_limits

    How much of a query string is a query string.

    A thousand parameters is what qs allows Express by default, and far past anything a link carries; sixty-four kilobytes for one value is well past the eight the common servers allow a whole request line. Beyond either, the request is an attempt to make the server allocate.

    An endpoint that genuinely takes more says so: ctx.query("tag", limits=@mime.Limits::new(parts=100000)).

    schema_of

    fn[T : ToSchema] schema_of(x : T) -> Schema

    The schema of any ToSchema type, without needing a value of it materialised at the call site beyond the one handed in — the generic entry point.

    unprocessable

    A 422 Unprocessable Entity response whose application/json body lists the validation errors, exactly as FastAPI reports a failed request.

    validate_schema

    fn validate_schema(schema : Schema, value : Json, loc : Array[String], errs : Array[ValidationError]) -> Unit

    Validate a JSON value against the descriptor schema, appending FastAPI-shaped errors to errs (located at loc). This is what "the descriptor drives validation" means: the very tree that emits the OpenAPI body schema also decides whether an inbound body conforms — one source of truth, exactly as pydantic derives both from one model. A named object is validated against its inline fields, so no $ref resolution is needed here.

    validation_error_body

    fn validation_error_body(errors : Array[ValidationError]) -> Json

    The {"detail": [ ... ]} body FastAPI returns when request validation fails, built from a list of ValidationErrors.

    with_constraints

    fn with_constraints(j : Json, constraints : Array[Constraint], version : OpenApiVersion) -> Json

    Merge the constraints into a scalar/array schema object for OpenAPI emission. exclusiveMinimum / exclusiveMaximum are numeric under OpenAPI 3.1 (JSON-Schema 2020-12) but a boolean flag alongside minimum / maximum under Swagger 2.0 and OpenAPI 3.0, so the form is version-aware.

    with_description

    fn with_description(j : Json, desc : String) -> Json

    Return j with a description sibling added (legal beside $ref in OpenAPI 3.1 / JSON-Schema 2020-12).

    with_key

    fn with_key(j : Json, key : String, value : Json) -> Json

    Return j with key set to value. Builds a fresh object so nothing shared mutates; a non-object is returned untouched, since there is nothing to set on it.