# `BB.Message.Option`
[🔗](https://github.com/beam-bots/bb/blob/main/lib/bb/message/option.ex#L5)

Custom Spark.Options types for message primitives.

Provides type functions for use in payload schemas to validate
`BB.Math.Vec3.t()`, `BB.Math.Quaternion.t()`, and `BB.Math.Transform.t()` types.

## Usage

    import BB.Message.Option

    @schema Spark.Options.new!([
      position: [type: vec3_type(), required: true],
      orientation: [type: quaternion_type(), required: true],
      pose: [type: transform_type(), required: true]
    ])

# `configurations_type`

```elixir
@spec configurations_type() :: {:custom, module(), atom(), list()}
```

Returns a Spark.Options type for a list of joint configurations.

A joint's configuration is shaped to its type, so the list is heterogeneous: a
float for single-DoF joints, a `BB.Math.Transform2D` for `:planar` and a
`BB.Math.Transform` for `:floating`.

This checks each element is one of those three, which is as much as a message
can check — matching a *particular* joint's type needs the robot, which the
message does not carry. `BB.Robot.State.set_configuration/3` is what rejects a
shape that doesn't match its joint.

## Examples

    iex> BB.Message.Option.configurations_type()
    {:custom, BB.Message.Option, :validate_configurations, [[]]}

# `covariance3_type`

```elixir
@spec covariance3_type() :: {:custom, module(), atom(), list()}
```

Returns a Spark.Options type for validating `BB.Math.Covariance3.t()`.

## Examples

    iex> BB.Message.Option.covariance3_type()
    {:custom, BB.Message.Option, :validate_covariance3, [[]]}

# `covariance6_type`

```elixir
@spec covariance6_type() :: {:custom, module(), atom(), list()}
```

Returns a Spark.Options type for validating `BB.Math.Covariance6.t()`.

## Examples

    iex> BB.Message.Option.covariance6_type()
    {:custom, BB.Message.Option, :validate_covariance6, [[]]}

# `efforts_type`

```elixir
@spec efforts_type() :: {:custom, module(), atom(), list()}
```

Returns a Spark.Options type for a list of joint efforts.

As `configurations_type/0`, but the multi-DoF shapes are
`BB.Message.Geometry.Wrench2D` and `BB.Message.Geometry.Wrench`.

## Examples

    iex> BB.Message.Option.efforts_type()
    {:custom, BB.Message.Option, :validate_efforts, [[]]}

# `quaternion_type`

```elixir
@spec quaternion_type() :: {:custom, module(), atom(), list()}
```

Returns a Spark.Options type for validating `BB.Quaternion.t()`.

## Examples

    iex> BB.Message.Option.quaternion_type()
    {:custom, BB.Message.Option, :validate_quaternion, [[]]}

# `transform_type`

```elixir
@spec transform_type() :: {:custom, module(), atom(), list()}
```

Returns a Spark.Options type for validating `BB.Math.Transform.t()`.

## Examples

    iex> BB.Message.Option.transform_type()
    {:custom, BB.Message.Option, :validate_transform, [[]]}

# `validate_configurations`

```elixir
@spec validate_configurations(
  term(),
  keyword()
) :: {:ok, list()} | {:error, String.t()}
```

Validates a list of joint configurations.

## Examples

    iex> BB.Message.Option.validate_configurations([0.5, BB.Math.Transform.identity()], [])
    {:ok, [0.5, BB.Math.Transform.identity()]}

    iex> BB.Message.Option.validate_configurations([:nope], [])
    {:error,
     "expected element 0 to be a float, BB.Math.Transform2D.t() or BB.Math.Transform.t(), got: :nope"}

# `validate_covariance3`

```elixir
@spec validate_covariance3(
  term(),
  keyword()
) :: {:ok, BB.Math.Covariance3.t()} | {:error, String.t()}
```

Validates a BB.Math.Covariance3 struct.

# `validate_covariance6`

```elixir
@spec validate_covariance6(
  term(),
  keyword()
) :: {:ok, BB.Math.Covariance6.t()} | {:error, String.t()}
```

Validates a BB.Math.Covariance6 struct.

# `validate_efforts`

```elixir
@spec validate_efforts(
  term(),
  keyword()
) :: {:ok, list()} | {:error, String.t()}
```

Validates a list of joint efforts.

# `validate_quaternion`

```elixir
@spec validate_quaternion(
  term(),
  keyword()
) :: {:ok, BB.Math.Quaternion.t()} | {:error, String.t()}
```

Validates a BB.Quaternion struct.

## Examples

    iex> BB.Message.Option.validate_quaternion(BB.Quaternion.identity(), [])
    {:ok, %BB.Quaternion{}}

    iex> BB.Message.Option.validate_quaternion("not a quaternion", [])
    {:error, "expected BB.Quaternion.t(), got: \"not a quaternion\""}

# `validate_transform`

```elixir
@spec validate_transform(
  term(),
  keyword()
) :: {:ok, BB.Math.Transform.t()} | {:error, String.t()}
```

Validates a BB.Math.Transform struct.

## Examples

    iex> BB.Message.Option.validate_transform(BB.Math.Transform.identity(), [])
    {:ok, %BB.Math.Transform{}}

    iex> BB.Message.Option.validate_transform("not a transform", [])
    {:error, "expected BB.Math.Transform.t(), got: \"not a transform\""}

# `validate_vec3`

```elixir
@spec validate_vec3(
  term(),
  keyword()
) :: {:ok, BB.Math.Vec3.t()} | {:error, String.t()}
```

Validates a BB.Vec3 struct.

## Examples

    iex> BB.Message.Option.validate_vec3(BB.Vec3.new(1.0, 2.0, 3.0), [])
    {:ok, %BB.Vec3{}}

    iex> BB.Message.Option.validate_vec3("not a vec3", [])
    {:error, "expected BB.Vec3.t(), got: \"not a vec3\""}

# `validate_velocities`

```elixir
@spec validate_velocities(
  term(),
  keyword()
) :: {:ok, list()} | {:error, String.t()}
```

Validates a list of joint velocities.

# `vec3_type`

```elixir
@spec vec3_type() :: {:custom, module(), atom(), list()}
```

Returns a Spark.Options type for validating `BB.Vec3.t()`.

## Examples

    iex> BB.Message.Option.vec3_type()
    {:custom, BB.Message.Option, :validate_vec3, [[]]}

# `velocities_type`

```elixir
@spec velocities_type() :: {:custom, module(), atom(), list()}
```

Returns a Spark.Options type for a list of joint velocities.

As `configurations_type/0`, but the multi-DoF shapes are
`BB.Message.Geometry.Twist2D` and `BB.Message.Geometry.Twist`.

## Examples

    iex> BB.Message.Option.velocities_type()
    {:custom, BB.Message.Option, :validate_velocities, [[]]}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
