# `Angelus.Ephemeris`
[🔗](https://github.com/MonsignorEduardo/angelus/blob/v0.0.2/lib/angelus/ephemeris.ex#L1)

Public v0.1 API for geocentric ephemeris positions.

# `position`

```elixir
@spec position(atom(), DateTime.t(), keyword()) ::
  {:ok, Angelus.Ephemeris.BodyPosition.t()} | {:error, term()}
```

Returns the geocentric position of a single celestial body at a UTC datetime.

`body` must be one of the atoms supported by the v0.1 ephemeris body catalog.
`datetime` must be a `%DateTime{}` in the UTC timezone.

## Options

  * `:adapter` — an alternative ephemeris adapter module implementing the
    `Angelus.Ephemeris.Adapter` behaviour. Defaults to
    `Angelus.Ephemeris.Adapters.Spice`.

## Returns

  * `{:ok, %Angelus.Ephemeris.BodyPosition{}}` on success.
  * `{:error, :invalid_body}` when `body` is not an atom.
  * `{:error, :invalid_datetime}` / `{:error, :datetime_must_be_utc}` for bad datetimes.
  * `{:error, {:unsupported_body, body}}` for unrecognised bodies.
  * `{:error, {:datetime_out_of_range, %{from: Date.t(), to: Date.t()}}}` outside the
    supported range.

## Examples

    iex> {:ok, pos} = Angelus.Ephemeris.position(:sun, ~U[2000-01-01 12:00:00Z])
    iex> pos.body
    :sun

# `positions`

```elixir
@spec positions([atom(), ...], DateTime.t(), keyword()) ::
  {:ok, %{required(atom()) =&gt; Angelus.Ephemeris.BodyPosition.t()}}
  | {:error, term()}
```

Returns geocentric positions for a list of celestial bodies at a UTC datetime.

All entries in `bodies` must be atoms supported by the v0.1 ephemeris body
catalog. The list must be non-empty and contain no duplicates. `datetime`
must be a `%DateTime{}` in the UTC timezone.

## Options

  * `:adapter` — an alternative ephemeris adapter module implementing the
    `Angelus.Ephemeris.Adapter` behaviour. Defaults to
    `Angelus.Ephemeris.Adapters.Spice`.

## Returns

  * `{:ok, %{atom() => %Angelus.Ephemeris.BodyPosition{}}}` — a map keyed by
    body atom.
  * `{:error, :empty_body_list}` when `bodies` is `[]`.
  * `{:error, :invalid_body_list}` when `bodies` is not a list of atoms.
  * `{:error, {:duplicate_body, atom()}}` when the same body appears more than once.
  * `{:error, {:unsupported_body, atom()}}` for unrecognised bodies.
  * `{:error, :invalid_datetime}` / `{:error, :datetime_must_be_utc}` for bad datetimes.
  * `{:error, {:datetime_out_of_range, %{from: Date.t(), to: Date.t()}}}` outside the
    supported range.
  * `{:error, {:unsupported_option, term()}}` for unknown options.

## Examples

    iex> {:ok, positions} = Angelus.Ephemeris.positions([:sun, :moon], ~U[2000-01-01 12:00:00Z])
    iex> Map.keys(positions)
    [:sun, :moon]

---

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