defimpl Altstd.Compact, for: Any do @moduledoc since: "0.1.0" @doc since: "0.1.0" @spec resolve(any(), keyword) :: Altstd.Compact.resolution_t() def resolve(object, _opts \\ []) do {:resolve, object} end @doc since: "0.1.0" @spec cast(any(), keyword) :: Altstd.Compact.t() def cast(object, opts \\ []) do resolution = object |> Altstd.Compact.resolve(opts) case resolution do {:resolve, resolved_value} -> resolved_value |> List.wrap() {:reject, _any} -> [] :reject -> [] resolved_value -> resolved_value |> List.wrap() end end @doc since: "0.1.0" defmacro __deriving__(module, _struct, opts) do keys = Keyword.get(opts, :keys, []) quote do defimpl Altstd.Compact, for: unquote(module) do def resolve(object, opts \\ []) do struct_as_map = object |> Map.from_struct() expressive_map = case length(unquote(keys)) do 0 -> struct_as_map _any -> Map.take(struct_as_map, unquote(keys)) end resolution = expressive_map |> Altstd.Compact.resolve(opts) case resolution do {:resolve, _resolved_value} -> {:resolve, object} {:reject, _resolved_value} -> {:reject, object} :reject -> {:reject, object} _resolved_value -> {:resolve, object} end end def cast(object, opts \\ []) do resolution = object |> Altstd.Compact.resolve(opts) case resolution do {:resolve, resolved_value} -> resolved_value |> List.wrap() {:reject, _any} -> [] :reject -> [] resolved_value -> resolved_value |> List.wrap() end end end end end end