OpenRPC document modeling and validation for MoonBit
import { "zmjknn/openrpc" @openrpc }
let source = #|{
#| "openrpc": "1.4.0",
#| "info": {"title": "Inventory", "version": "1.0.0"},
#| "methods": [{"name": "inventory.list"}]
#|}
match @openrpc.Document::parse(source) {
Ok(document) => println(document.methods[0].name)
Err(diagnostics) => {
for diagnostic in diagnostics {
println(diagnostic.path + ": " + diagnostic.message)
}
}
}moon add zmjknn/openrpcmoon run examples/quickstart --target wasm-gcmethod=inventory.get, server=https://dev.inventory.example/rpc, request={"jsonrpc":"2.0","id":7,"method":"inventory.get","params":{"id":"abc"}}let params : Map[String, Json] = {"id": "abc"}
let request = method_value.build_request(7, params)let values : Array[Json] = ["abc"]
let request = method_value.build_positional_request(7, values)let params : Map[String, Json] = {"id": "abc"}
match method_value.validate_named_params(params) {
Ok(_) => println("parameters satisfy the OpenRPC schemas")
Err(diagnostics) => println(diagnostics[0].path + ": " + diagnostics[0].message)
}match document.validate_named_params("inventory.get", {"id": "abc"}) {
Ok(_) => println("parameters satisfy the referenced schemas")
Err(diagnostics) => println(diagnostics[0].path + ": " + diagnostics[0].message)
}match document.find_server("primary") {
Some(server) =>
match server.render_url({"region": "staging"}) {
Ok(url) => println(url)
Err(diagnostics) => println(diagnostics[0].message)
}
None => println("server is not declared")
}let diagnostics = document.lint()
for diagnostic in diagnostics {
println(diagnostic.path + ": " + diagnostic.message)
}let notification = method_value.build_notification({"scope": "all"})let calls : Array[@openrpc.BatchCall] = [
@openrpc.BatchCall::new(
1,
"inventory.get",
@openrpc.RequestParams::named({"id": "abc"}),
),
]
let batch = document.build_batch(calls)match document.decode_batch_response(response, calls) {
Ok(values) => {
for value in values {
println(value.method_name)
}
}
Err(diagnostics) => println(diagnostics[0].path + ": " + diagnostics[0].message)
}match method_value.decode_response(response, 7) {
Ok(@openrpc.RpcResponse::Result(value)) => println(value.stringify())
Ok(@openrpc.RpcResponse::Error(error_value)) => println(error_value.message)
Err(diagnostics) => {
for diagnostic in diagnostics {
println(diagnostic.path + ": " + diagnostic.message)
}
}
}moon fmt --check
moon check --target wasm-gc
moon build --target wasm-gc
moon test --target wasm-gc
moon run examples/quickstart --target wasm-gcpub enum ChangeImpact {
Breaking
Compatible
Informational
}pub enum ChangeKind {
MethodAdded
MethodRemoved
ParameterAdded
ParameterRemoved
ParameterRequiredChanged
ParameterOrderChanged
ParameterSchemaChanged
ResultAdded
ResultRemoved
ResultSchemaChanged
ServerAdded
ServerRemoved
ServerChanged
TagAdded
TagRemoved
ComponentAdded
ComponentRemoved
ComponentChanged
}pub enum DiagnosticCode {
InvalidJson
ExpectedObject
MissingField
InvalidField
UnsupportedVersion
DuplicateMethod
MissingParameter
UnknownParameter
TooManyParameters
EmptyMethodName
EmptyParameterName
EmptyResultName
DuplicateParameter
OptionalBeforeRequired
InvalidSchemaBoundary
EmptyBatch
UnknownMethod
DuplicateRequestId
SchemaViolation
UnsupportedSchema
InvalidResponse
InvalidBatchResponse
UnknownResponseId
DuplicateResponseId
MissingResponse
ResponseIdMismatch
InvalidRpcError
DuplicateTag
UnsupportedReference
UnresolvedReference
CircularReference
InvalidServerTemplate
UnknownServerVariable
InvalidServerVariableValue
InvalidExamplePairing
}fn Document::decode_batch_response(self : Document, response : Json, calls : Array[BatchCall]) -> Result[Array[BatchResponse], Array[Diagnostic]]fn Document::validate_examples(self : Document, method_name : String) -> Result[Unit, Array[Diagnostic]]fn Document::validate_result(self : Document, method_name : String, value : Json) -> Result[Unit, Array[Diagnostic]]pub struct Method {
name : String
params : Array[Parameter]
result : ResultDescriptor?
summary : String?
description : String?
deprecated : Bool
tags : Array[Tag]
servers : Array[Server]
examples : Array[ExamplePairing]
}fn Method::decode_response(_self : Method, response : Json, request_id : Json) -> Result[RpcResponse, Array[Diagnostic]]fn ResultDescriptor::validate(self : ResultDescriptor, value : Json) -> Result[Unit, Array[Diagnostic]]pub struct Server {
name : String
url : String
description : String?
variables : Map[String, ServerVariable]
}fn Server::render_url(self : Server, overrides : Map[String, String]) -> Result[String, Array[Diagnostic]]pub struct ServerVariable {
default_value : String
enum_values : Array[String]
description : String?
}pub struct Tag {
name : String
description : String?
}fn quickstart_source() -> String