View Source Want (want v1.18.0)

Type conversion library for Elixir and Erlang. Want allows you to convert between Elixir and Erlang types using an intuitive interface. In addition, Elixir users have access to more complex type conversion via the Want.map/3, Want.keywords/3 and Want.Shape functions and macros.

Summary

Functions

Cast a value to an atom.

Cast a value to a boolean.

Check whether the given type name is valid and raise if not.

Cast an incoming value to a datetime.

Dump a casted input into a more serializable form. Typically used to generate Phoenix query parameters.

Cast an input value to an enum. The input must loosely match one of the allowed values in order for the cast to succeed.

Convert a value to a float.

Convert a value to an integer.

Determine whether the given type name is valid.

Cast an incoming keyword list or map to an output keyword list using the provided schema to control conversion rules and validations. Each value in the schema map represents conversion options.

Cast an input into a list. By default this function will simply break up the input into list elements, but further casting and validation of elements can be performed by providing an element option. The separator used to split the list defaults to the comma character and this can be controlled using the separator option.

Cast an incoming keyword list or map to an output map using the provided schema to control conversion rules and validations. Each value in the schema map represents conversion options.

Cast an input to a sort tuple.

Convert a value to a string.

Return a list of atoms describing the types that Want recognizes.

Types

@type enumerable() :: map() | keyword()

Functions

Cast a value to an atom.

Options

  • :exists - If true, only convert to an atom if a matching atom already exists.
  • :default - If conversion fails, this value should be returned instead.

Examples

iex> Want.atom("hello")
{:ok, :hello}

iex> Want.atom(1.0)
{:ok, :'1.0'}

iex> Want.atom({:a, :b})
{:error, "Failed to convert value {:a, :b} to atom."}

iex> Want.atom({:a, :b}, default: :c)
{:ok, :c}

iex> Want.atom("10", exists: true)
{:error, "An atom matching the given value does not exist."}

Cast a value to a boolean.

Options

  • :default - If conversion fails, this value should be returned instead.

Examples

iex> Want.boolean("true")
{:ok, true}

iex> Want.boolean("FALSE")
{:ok, false}

iex> Want.boolean(1.0)
{:ok, true}

iex> Want.boolean({:a, :b})
{:error, "Failed to convert value {:a, :b} to boolean."}

iex> Want.boolean({:a, :b}, default: true)
{:ok, true}
Link to this function

boolean!(value, default)

View Source

Check whether the given type name is valid and raise if not.

Cast an incoming value to a datetime.

Examples

iex> Want.datetime("2020-02-06 18:23:55.850218Z")
{:ok, ~U[2020-02-06 18:23:55.850218Z]}

iex> Want.datetime({{2020, 02, 06}, {18, 23, 55}})
{:ok, ~U[2020-02-06 18:23:55Z]}

iex> Want.datetime({{2020, 02, 06}, {18, 23, 55, 123456}})
{:ok, ~U[2020-02-06 18:23:55.123456Z]}
Link to this function

datetime(value, default)

View Source
Link to this function

datetime!(value, default)

View Source

Dump a casted input into a more serializable form. Typically used to generate Phoenix query parameters.

Options

  • :update - Update the input value using Want.Update protocol before dumping

Examples

iex> Want.dump({:inserted_at, :desc})
{:ok, "inserted_at:desc"}

iex> Want.dump({:inserted_at, :desc}, update: :inserted_at)
{:ok, "inserted_at:asc"}

iex> Want.dump({:inserted_at, :desc}, update: :updated_at)
{:ok, "updated_at:asc"}

iex> Want.dump("hello")
{:ok, "hello"}

iex> Want.dump(%{hello: :world, sort: {:inserted_at, :desc}})
{:ok, [hello: :world, sort: "inserted_at:desc"]}

iex> Want.dump(%{hello: :world, sort: {:inserted_at, :desc}}, update: [sort: :inserted_at])
{:ok, [hello: :world, sort: "inserted_at:asc"]}

iex> Want.dump({:a, :b, :c})
{:error, "Unrecognized dump input {:a, :b, :c}"}

Cast an input value to an enum. The input must loosely match one of the allowed values in order for the cast to succeed.

Options

  • :valid - List of valid enum values. The input must loosely match one of these.
  • :default - If conversion fails, this value should be returned instead.

Examples

iex> Want.enum("hello", valid: [:hello, :world])
{:ok, :hello}

iex> Want.enum("hello", valid: ["hello", :world])
{:ok, "hello"}

iex> Want.enum("foo", valid: ["hello", :world], default: :bar)
{:ok, :bar}

Convert a value to a float.

Options

  • :max - Maximum allowable float value.
  • :min - Minimum allowable float value.
  • :default - If conversion fails, this value should be returned instead.

Examples

iex> Want.float(1.0)
{:ok, 1.0}

iex> Want.float({:a, :b}, default: 1.0)
{:ok, 1.0}

iex> Want.float(:'5.0', max: 3.0)
{:error, "Float value exceeds maximum 3.0."}

iex> Want.float("1.0", min: 3.0)
{:error, "Float value below minimum 3.0."}

Convert a value to an integer.

Options

  • :max - Maximum allowable integer value.
  • :min - Minimum allowable integer value.
  • :default - If conversion fails, this value should be returned instead.

Examples

iex> Want.integer(1.0)
{:ok, 1}

iex> Want.integer({:a, :b}, default: 1)
{:ok, 1}

iex> Want.integer(:'5', max: 3)
{:error, "Integer value exceeds maximum 3."}

iex> Want.integer("1", min: 3)
{:error, "Integer value below minimum 3."}
Link to this function

integer!(value, default)

View Source

Determine whether the given type name is valid.

Link to this function

keywords(input, schema, opts \\ [])

View Source

Cast an incoming keyword list or map to an output keyword list using the provided schema to control conversion rules and validations. Each value in the schema map represents conversion options.

Specify a :type field to cast the input value for a given key to that type, defaults to :string. Specific conversion and validation options for each type corresponds to those available for Want.integer/2, Want.float/2, Want.string/2 and Want.atom/2.

Keyword lists can be nested by using a new schema map as a value in a parent schema. The field from which a given value is derived can also be modified using the :from option.

Examples

iex> Want.keywords(%{"id" => 1}, %{id: [type: :integer]})
{:ok, [id: 1]}

iex> Want.keywords(%{"identifier" => 1}, %{id: [type: :integer, from: :identifier]})
{:ok, [id: 1]}

iex> Want.keywords(%{}, %{id: [type: :integer, default: 1]})
{:ok, [id: 1]}

iex> Want.keywords(%{"id" => "bananas"}, %{id: [type: :integer, default: 1]})
{:ok, [id: 1]}

iex> Want.keywords(%{"identifier" => "bananas"}, %{id: [type: :integer, default: 1, from: :identifier]})
{:ok, [id: 1]}

iex> Want.keywords(%{"hello" => "world", "foo" => "bar"}, %{hello: [], foo: [type: :atom]})
{:ok, [hello: "world", foo: :bar]}

iex> Want.keywords(%{"hello" => %{"foo" => "bar"}}, %{hello: %{foo: [type: :atom]}})
{:ok, [hello: [foo: :bar]]}

iex> Want.keywords(%{"id" => "bananas"}, %{id: [type: :integer, default: 1]}, merge: [id: 2])
{:ok, [id: 2]}
Link to this function

keywords!(input, schema, opts \\ [])

View Source

Cast an input into a list. By default this function will simply break up the input into list elements, but further casting and validation of elements can be performed by providing an element option. The separator used to split the list defaults to the comma character and this can be controlled using the separator option.

Options

  • :separator - Determines the character(s) used to separate list items. Defaults to the comma character.
  • :element - Provides the ability to further control how list elements are cast and validated. Similar to the map and keywords functions, accepts a keyword list with its own :type field and validation options.
  • :default - If conversion fails, this value should be returned instead.

Examples

iex> Want.list("1")
{:ok, ["1"]}

iex> Want.list("1", element: [type: :integer])
{:ok, [1]}

iex> Want.list("1,2,3,4", element: [type: :integer])
{:ok, [1, 2, 3, 4]}

iex> Want.list("1:2:3:4", separator: ":", element: [type: :integer])
{:ok, [1, 2, 3, 4]}

iex> Want.list("hello:world", separator: ":", element: [type: :enum, valid: [:hello, :world]])
{:ok, [:hello, :world]}

iex> Want.list("hello:world", separator: ":", element: [type: :enum, valid: [:hello]])
{:ok, [:hello]}
Link to this function

list!(input, opts \\ [])

View Source
Link to this function

map(input, schema, opts \\ [])

View Source

Cast an incoming keyword list or map to an output map using the provided schema to control conversion rules and validations. Each value in the schema map represents conversion options.

Specify a :type field to cast the input value for a given key to that type, defaults to :string. Specific conversion and validation options for each type corresponds to those available for Want.integer/2, Want.float/2, Want.string/2 and Want.atom/2.

Maps can be nested by using a new schema map as a value in a parent schema. The field from which a given value is derived can also be modified using the :from option.

Options

  • :merge - Provide a map matching the given schema that contains default values to be used if the input value does not contain a particular field. Useful when updating a map with new inputs without overwriting all fields.

Examples

iex> Want.map(%{"id" => 1}, %{id: [type: :integer]})
{:ok, %{id: 1}}

iex> Want.map(%{"identifier" => 1}, %{id: [type: :integer, from: :identifier]})
{:ok, %{id: 1}}

iex> Want.map(%{}, %{id: [type: :integer, default: 1]})
{:ok, %{id: 1}}

iex> Want.map(%{"id" => "bananas"}, %{id: [type: :integer, default: 1]})
{:ok, %{id: 1}}

iex> Want.map(%{"hello" => "world", "foo" => "bar"}, %{hello: [], foo: [type: :atom]})
{:ok, %{hello: "world", foo: :bar}}

iex> Want.map(%{"hello" => %{"foo" => "bar"}}, %{hello: %{foo: [type: :atom]}})
{:ok, %{hello: %{foo: :bar}}}

iex> Want.map(%{"id" => "bananas"}, %{id: [type: :integer, default: 1]}, merge: %{id: 2})
{:ok, %{id: 2}}
Link to this function

map!(input, schema, opts \\ [])

View Source

Cast an input to a sort tuple.

Options

  • :fields - List of allowed sort fields. Casting will fail if the input doesn't match any of these.
  • :default - If conversion fails, this value should be returned instead.

Examples

iex> Want.sort("inserted_at:desc", fields: [:inserted_at, :id, :name])
{:ok, {:inserted_at, :desc}}

iex> Want.sort("updated_at", fields: [:inserted_at, :id], default: {:id, :asc})
{:ok, {:id, :asc}}

iex> Want.sort("updated_at:asc", [])
{:error, "You must specify a list of valid sort fields using the :fields option."}

Convert a value to a string.

Options

  • :max - Maximum allowable string length.
  • :min - Minimum allowable string length.
  • ':decode' - Currently only supports :uri; runs URI.decode on the input value
  • :matches - The resulting string must match the given regex.
  • :default - If conversion fails, this value should be returned instead.

Examples

iex> Want.string(1)
{:ok, "1"}

iex> Want.string({:a, :b}, default: "string")
{:ok, "string"}

iex> Want.string(:hello, max: 3)
{:error, "String length exceeds maximum of 3."}

iex> Want.string("hello%20world", decode: :uri)
{:ok, "hello world"}

iex> Want.string(:a, min: 3)
{:error, "String length below minimum of 3."}

iex> Want.string(:a, matches: ~r/a/)
{:ok, "a"}

Return a list of atoms describing the types that Want recognizes.