Lavash.Type behaviour (Lavash v0.4.0-rc.3)

Copy Markdown View Source

Behaviour for bidirectional type conversion between URL strings and Elixir values.

Lavash uses this for:

  • Parsing URL params into typed Elixir values
  • Serializing Elixir values back to URL-safe strings

Built-in Types

  • :string - Pass-through, no conversion
  • :integer - "42"42
  • :float - "3.14"3.14
  • :boolean - "true"/"false"true/false
  • :uuid - UUID stored as full string, URL-encoded as base32 (26 chars)
  • {:uuid, "prefix"} - UUID with TypeID prefix, e.g. cat_01h455vb4pex5vsknk084sn02q
  • :atom - "foo":foo (uses String.to_existing_atom/1)
  • {:array, type} - "a,b,c"["a", "b", "c"] (with inner type conversion)

Custom Types

Implement the Lavash.Type behaviour for custom types:

defmodule MyApp.Types.Date do
  use Lavash.Type

  @impl true
  def parse(value) when is_binary(value) do
    case Date.from_iso8601(value) do
      {:ok, date} -> {:ok, date}
      {:error, _} -> {:error, "invalid date format"}
    end
  end

  @impl true
  def dump(%Date{} = date), do: Date.to_iso8601(date)
end

Then use in your state definition:

field :start_date, MyApp.Types.Date, default: nil

Summary

Callbacks

Serializes an Elixir value to a URL-safe string.

Parses a URL string into a typed Elixir value.

Functions

Decode a value coming off the JS wire into the closest Elixir type without a declared schema to consult.

Serializes a typed Elixir value to a URL-safe string.

Parses a URL param string into the given type.

Parses a URL param string into the given type, raising on error.

Callbacks

dump(term)

(optional)
@callback dump(term()) :: String.t()

Serializes an Elixir value to a URL-safe string.

parse(t)

(optional)
@callback parse(String.t()) :: {:ok, term()} | {:error, term()}

Parses a URL string into a typed Elixir value.

Returns {:ok, value} on success, {:error, reason} on failure.

Functions

decode_wire(value)

Decode a value coming off the JS wire into the closest Elixir type without a declared schema to consult.

Used by binding propagation and the set_<field> event path where we receive a string from the client but the receiver doesn't know the field's declared type at the dispatch point. Tries integer, then float, then leaves the value as a string.

Examples

iex> Lavash.Type.decode_wire("true")
true

iex> Lavash.Type.decode_wire("42")
42

iex> Lavash.Type.decode_wire("3.14")
3.14

iex> Lavash.Type.decode_wire("hello")
"hello"

dump(type, value)

Serializes a typed Elixir value to a URL-safe string.

Examples

iex> Lavash.Type.dump(:integer, 42)
"42"

iex> Lavash.Type.dump(:boolean, true)
"true"

iex> Lavash.Type.dump({:array, :integer}, [1, 2, 3])
"1,2,3"

parse(type, value)

Parses a URL param string into the given type.

Examples

iex> Lavash.Type.parse(:integer, "42")
{:ok, 42}

iex> Lavash.Type.parse(:boolean, "true")
{:ok, true}

iex> Lavash.Type.parse({:array, :integer}, "1,2,3")
{:ok, [1, 2, 3]}

parse!(type, value)

Parses a URL param string into the given type, raising on error.

Examples

iex> Lavash.Type.parse!(:integer, "42")
42