Skip to content

Commit

Permalink
refactor engine/compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
phcurado committed Jul 5, 2023
1 parent 41f50a0 commit 701372c
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 58 deletions.
79 changes: 23 additions & 56 deletions lib/parameter/engine.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,6 @@ defmodule Parameter.Engine do
cast_fields: [],
operation: :load

def asdf() do
%{
first_name: [type: :string, key: "firstName", required: true],
info: [type: {:map, %{number: [type: {:array, %{number: [type: :integer]}}]}}],
address: [type: {:array, %{number: [type: :integer]}}]
}
|> Schema.compile!()
|> load(
%{
"firstName" => "Ola",
"info" => %{
"number" => [%{"number" => "2"}, %{"number" => "asdajsh"}, %{"number" => "what"}]
}
},
struct: true
)
|> apply_operation()
end

@spec load(module | list(Field.t()), map(), Keyword.t()) :: t()
def load(schema_or_fields, params, opts \\ []) do
fields = Schema.fields(schema_or_fields)
Expand Down Expand Up @@ -92,13 +73,18 @@ defmodule Parameter.Engine do
defp fetch_engine_errors(%__MODULE__{errors: errors, changes: changes}) do
Enum.reduce(changes, errors, fn
{field_key, values}, acc when is_list(values) ->
values
|> Enum.with_index()
|> Enum.filter(fn {engine, _index} -> !engine.valid? end)
|> Enum.map(fn {engine, index} -> %{index => engine.errors} end)
|> then(fn list ->
Map.put(acc, field_key, list)
end)
invalid_data =
values |> Enum.with_index() |> Enum.filter(fn {engine, _index} -> !engine.valid? end)

if Enum.empty?(invalid_data) do
acc
else
invalid_data
|> Enum.map(fn {engine, index} -> %{index => engine.errors} end)
|> then(fn list ->
Map.put(acc, field_key, list)
end)
end

{field_key, %__MODULE__{valid?: false} = engine}, acc ->
Map.merge(acc, %{field_key => fetch_engine_errors(engine)})
Expand Down Expand Up @@ -286,35 +272,17 @@ defmodule Parameter.Engine do

defp handle_field(engine, %Field{type: {:map, schema}} = field, value, opts)
when is_map(value) do
handle_field(engine, schema, value, opts) |> IO.inspect()
# value
# |> Enum.reduce(engine, fn {key, value}, engine ->
# case handle_method(engine, schema, value, opts) do
# %__MODULE__{valid?: false} = inner_engine ->
# IO.inspect("whats happening")
# IO.inspect(key)
# IO.inspect(inner_engine)

# %__MODULE__{valid?: true} = inner_engine ->
# IO.inspect("Im valid ")
# IO.inspect(key)
# IO.inspect(key)
# IO.inspect(inner_engine)
# # add_change(engine, field.name, inner_engine)
# end
# end)

# case handle_method(engine, schema, value, opts) do
# %__MODULE__{valid?: false} = inner_engine ->
# %__MODULE__{
# engine
# | changes: Map.put(engine.changes, field.name, inner_engine),
# valid?: false
# }

# %__MODULE__{valid?: true} = inner_engine ->
# add_change(engine, field.name, inner_engine)
# end
case handle_method(engine, schema, value, opts) do
%__MODULE__{valid?: false} = inner_engine ->
%__MODULE__{
engine
| changes: Map.put(engine.changes, field.name, inner_engine),
valid?: false
}

%__MODULE__{valid?: true} = inner_engine ->
add_change(engine, field.name, inner_engine)
end
end

defp handle_field(engine, %Field{name: name, type: {:map, _schema}}, _values, _opts) do
Expand All @@ -338,7 +306,6 @@ defmodule Parameter.Engine do

defp handle_method(%__MODULE__{operation: :load}, {:map, schema}, params, opts) do
load(schema, params, opts)
|> IO.inspect()
end

defp handle_method(%__MODULE__{operation: :load}, schema, params, opts) do
Expand Down
2 changes: 2 additions & 0 deletions lib/parameter/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ defmodule Parameter.Schema do
"""

alias Parameter.Field
alias Parameter.Schema.Builder
alias Parameter.Schema.Compiler
alias Parameter.Types

Expand Down Expand Up @@ -319,6 +320,7 @@ defmodule Parameter.Schema do
end

defdelegate compile!(opts), to: Compiler, as: :compile_schema!
defdelegate build!(opts), to: Builder, as: :build!

defp schema(caller, block) do
precompile =
Expand Down
75 changes: 75 additions & 0 deletions lib/parameter/schema/builder.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
defmodule Parameter.Schema.Builder do
@moduledoc false
alias Parameter.Field
alias Parameter.Types

def build!(schema) when is_map(schema) do
for {name, opts} <- schema do
{type, opts} = Keyword.pop(opts, :type, :string)
type = compile_type!(type)

field = Field.new!([name: name, type: type] ++ opts)

case validate_default(field) do
:ok -> field
{:error, reason} -> raise ArgumentError, message: inspect(reason)
end
end
end

def build!(schema) when is_atom(schema) do
Parameter.Schema.fields(schema)
end

defp compile_type!({type, schema}) when is_tuple(schema) do
{type, compile_type!(schema)}
end

defp compile_type!({type, schema}) do
if Types.composite_type?(type) do
{type, build!(schema)}
else
raise ArgumentError,
message:
"not a valid inner type, please use `{map, inner_type}` or `{array, inner_type}` for nested associations"
end
end

defp compile_type!(type) when is_atom(type) do
type
end

defp validate_default(
%Field{default: default, load_default: load_default, dump_default: dump_default} = field
) do
with :ok <- validate_default(field, default),
:ok <- validate_default(field, load_default),
do: validate_default(field, dump_default)
end

defp validate_default(_field, nil) do
:ok
end

defp validate_default(%Field{name: name} = field, default_value) do
Parameter.validate([field], %{name => default_value})
end

def validate_nested_opts!(opts) do
keys = Keyword.keys(opts)

if :validator in keys do
raise ArgumentError, "validator cannot be used on nested fields"
end

if :on_load in keys do
raise ArgumentError, "on_load cannot be used on nested fields"
end

if :on_dump in keys do
raise ArgumentError, "on_dump cannot be used on nested fields"
end

opts
end
end
3 changes: 1 addition & 2 deletions lib/parameter/schema/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ defmodule Parameter.Schema.Compiler do
end

def compile_schema!(schema) when is_atom(schema) do
Parameter.Schema.fields(schema)
# schema
schema
end

defp compile_type!({type, schema}) when is_tuple(schema) do
Expand Down

0 comments on commit 701372c

Please sign in to comment.