Atex.Lexicon (atex v0.6.0)

View Source

Summary

Functions

Defines a lexicon module from a JSON lexicon definition.

Functions

deflexicon(lexicon)

(macro)

Defines a lexicon module from a JSON lexicon definition.

The deflexicon macro processes the provided lexicon map (typically loaded from a JSON file) and generates:

  • Typespecs for each definition, exposing a t/0 type for the main definition and named types for any additional definitions.
  • Peri schemas via defschema/2 for runtime validation of data.
  • Structs for object and record definitions, with @enforce_keys ensuring required fields are present.
  • For queries and procedures, it creates structs for params, input, and output when those sections exist in the lexicon. It also generates a top‑level struct that aggregates params and input (when applicable); this struct is used by the XRPC client to locate the appropriate output struct.

If a procedure doesn't have a schema for a JSON body specified as it's input, the top-level struct will instead have a raw_input field, allowing for miscellaneous bodies such as a binary blob.

The generated structs also implement the JSON.Encoder and Jason.Encoder protocols (the latter currently present for compatibility), as well as a from_json function which is used to validate an input map - e.g. from a JSON HTTP response - and turn it into a struct.

Example

deflexicon(%{
  "lexicon" => 1,
  "id" => "com.ovyerus.testing",
  "defs" => %{
    "main" => %{
      "type" => "record",
      "key" => "tid",
      "record" => %{
        "type" => "object",
        "required" => ["foobar"],
        "properties" => %{ "foobar" => %{ "type" => "string" } }
      }
    }
  }
})

The macro expands to following code (truncated for brevity):

@type main() :: %{required(:foobar) => String.t(), optional(:"$type") => String.t()}
@type t() :: %{required(:foobar) => String.t(), optional(:"$type") => String.t()}

defschema(:main, %{
  foobar: {:required, {:custom, {Atex.Lexicon.Validators.String, :validate, [[]]}}},
  "$type": {{:literal, "com.ovyerus.testing"}, {:default, "com.ovyerus.testing"}}
})

@enforce_keys [:foobar]
defstruct foobar: nil, "$type": "com.ovyerus.testing"

def from_json(json) do
  case apply(Com.Ovyerus.Testing, :main, [json]) do
    {:ok, map} -> {:ok, struct(__MODULE__, map)}
    err -> err
  end
end

The generated module can be used directly with Atex.XRPC functions, allowing type‑safe construction of requests and automatic decoding of responses.