# `LiveVue.Encoder`
[🔗](https://github.com/Valian/live_vue/blob/v1.0.1/lib/live_vue/encoder.ex#L1)

Protocol for encoding values to JSON for LiveVue.

This protocol is used to safely transform structs into plain maps before
calculating JSON patches. It ensures that struct fields are explicitly
exposed and prevents accidental exposure of sensitive data.

It's very similar to Jason.Encoder, but it's converting structs to maps instead of strings.

## Deriving

The protocol allows leveraging Elixir's `@derive` feature to simplify protocol
implementation in trivial cases. Accepted options are:

* `:only` - encodes only values of specified keys.
* `:except` - encodes all struct fields except specified keys.

By default all keys except the `:__struct__` key are encoded.

## Example

Let's assume a presence of the following struct:

    defmodule User do
      defstruct [:name, :email, :password]
    end

If we were to call `@derive LiveVue.Encoder` just before `defstruct`, an
implementation would be generated that encodes all fields except `:__struct__`:

    defmodule User do
      @derive LiveVue.Encoder
      defstruct [:name, :email, :password]
    end

If we called `@derive {LiveVue.Encoder, only: [:name, :email]}`, only the
specified fields would be encoded:

    defmodule User do
      @derive {LiveVue.Encoder, only: [:name, :email]}
      defstruct [:name, :email, :password]
    end

If we called `@derive {LiveVue.Encoder, except: [:password]}`, all fields
except the specified ones would be encoded:

    defmodule User do
      @derive {LiveVue.Encoder, except: [:password]}
      defstruct [:name, :email, :password]
    end

## Deriving outside of the module

If you don't own the struct you want to encode, you may use Protocol.derive/3 placed outside of any module:

Protocol.derive(LiveVue.Encoder, User, only: [...])

## Custom implementations

You may define your own implementation for the struct:

defimpl LiveVue.Encoder, for: User do
  def encode(struct, opts) do
    struct
    |> Map.take([:first, :second])
    |> LiveVue.Encoder.encode(opts)
  end
end

# `opts`

```elixir
@type opts() :: Keyword.t()
```

# `t`

```elixir
@type t() :: term()
```

# `encode`

```elixir
@spec encode(t(), opts()) :: any()
```

Encodes a value to one of the primitive types.

---

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