# Eyeon
An Elixir library for encoding and decoding [Amazon Ion](https://amazon-ion.github.io/ion-docs/) data.
Supports both Ion text (`.ion`) and Ion binary (`.10n`) formats, with auto-detection of binary input on decode. Passes Amazon's official Ion conformance test suite for Ion 1.0 and 1.1.
## Installation
Add `eyeon` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:eyeon, "~> 0.1.0"}
]
end
```
## Usage
```elixir
# Decode Ion text
{:ok, value} = Eyeon.decode("{name: \"Alice\", scores: [98, 87, 95]}")
value["name"] #=> "Alice"
# Encode to Ion text (default)
{:ok, ion} = Eyeon.encode(%{"greeting" => "hello"})
# Encode to Ion binary
{:ok, bin} = Eyeon.encode(42, %{encoding: :binary})
# Round-trip through files
File.write!("user.ion", Eyeon.encode!(%{"name" => "Alice", "age" => 30}))
Eyeon.decode!(File.read!("user.ion"))
#=> %{"age" => 30, "name" => "Alice"}
```
## Ion type mapping
Most Ion types map directly to Elixir types. Types without a native equivalent use tagged tuples:
| Ion type | Elixir representation |
|-------------|-----------------------------------------------------|
| `null` | `nil` |
| `bool` | `true` / `false` |
| `int` | integer |
| `float` | float, `:nan`, `:infinity`, `:neg_infinity` |
| `decimal` | `Decimal.t()` |
| `timestamp` | `DateTime.t()`, `NaiveDateTime.t()`, or `Date.t()` |
| `string` | binary string |
| `symbol` | `{:symbol, name}` |
| `blob` | `{:blob, binary}` |
| `clob` | `{:clob, binary}` |
| `list` | list |
| `struct` | map with string keys |
| `sexp` | `{:sexp, list}` |
| `annotation`| `{:annotated, {:symbol, name}, value}` |
| typed null | `{:null, type}` e.g. `{:null, :int}` |
## Timestamps
By default, Ion timestamps decode to native Elixir date/time types based on their precision and offset:
```elixir
Eyeon.decode!("2024-01-15T12:30:00Z")
#=> ~U[2024-01-15 12:30:00Z]
Eyeon.decode!("2024-01-15")
#=> ~D[2024-01-15]
```
Pass `%{timestamp: :raw}` to get `{:timestamp, string}` tuples that preserve the original Ion precision and offset semantics:
```elixir
Eyeon.decode!("2024-01-15T12:30:00Z", %{timestamp: :raw})
#=> {:timestamp, "2024-01-15T12:30:00Z"}
```
## Documentation
Full documentation is available at [hexdocs.pm/eyeon](https://hexdocs.pm/eyeon).
## Development
### Updating `ion-tests`
Add the `ion-tests` remote, if needed:
```
git remote add -f ion-tests https://github.com/amazon-ion/ion-tests
```
Then pull/fetch:
```
git fetch ion-tests main
git subtree pull --prefix test/ion-tests ion-tests main --squash
```
## License
MIT - see [LICENSE](LICENSE) for details.