11defprotocol ProtoValidator.Verifiable do
22 @ doc ""
3+ @ fallback_to_any true
34 def validate ( data )
45end
56
@@ -16,24 +17,59 @@ defmodule ProtoValidator do
1617 """
1718
1819 defmacro __using__ ( opts ) do
19- entity_module = Keyword . get ( opts , :entity )
20+ # entity_module = Keyword.get(opts, :entity)
2021
2122 quote location: :keep do
22- import unquote ( __MODULE__ ) , except: [ validate: 2 ]
2323 import ProtoValidator.DSL , only: [ validate: 2 ]
2424
2525 @ options unquote ( opts )
2626 Module . register_attribute ( __MODULE__ , :validations , accumulate: true )
2727
2828 validator_module = __MODULE__
2929
30- defimpl ProtoValidator.Verifiable , for: unquote ( entity_module ) do
30+ entity_module = Keyword . get ( @ options , :entity )
31+
32+ defimpl ProtoValidator.Verifiable , for: entity_module do
3133 @ validator_module validator_module
3234 def validate ( data ) do
3335 apply ( @ validator_module , :validate , [ data ] )
3436 end
3537 end
3638
39+ def validate ( % { __struct__: protobuf_module } = data ) do
40+ props = protobuf_module . __message_props__ ( )
41+
42+ props
43+ |> Map . get ( :field_props )
44+ |> Stream . filter ( fn { _ , % { oneof: oneof } } -> is_nil ( oneof ) end )
45+ |> ProtoValidator.Utils . pipe_validates ( fn { _ , % { name_atom: field } = field_prop } ->
46+ value = Map . get ( data , field )
47+
48+ case validate_value ( field , value ) do
49+ :ok -> validate_field ( field_prop , value )
50+ { :error , msg } -> { :error , msg }
51+ end
52+ end )
53+ end
54+
55+ def validate ( data ) when is_map ( data ) do
56+ @ options |> Keyword . get ( :entity ) |> struct ( data ) |> validate ( )
57+ end
58+
59+ def validate ( _ ) , do: :ok
60+
61+ def validate_field ( _ , nil ) , do: :ok
62+
63+ def validate_field ( % { type: type , repeated?: true } , values ) do
64+ ProtoValidator.Utils . pipe_validates ( values , fn value ->
65+ ProtoValidator . validate ( type , value )
66+ end )
67+ end
68+
69+ def validate_field ( % { type: type } = field_prop , value ) do
70+ ProtoValidator . validate ( type , value )
71+ end
72+
3773 @ before_compile ProtoValidator.DSL
3874 end
3975 end
@@ -42,9 +78,19 @@ defmodule ProtoValidator do
4278 ProtoValidator.Verifiable . validate ( data )
4379 end
4480
45- def validate ( module , data ) do
81+ def validate ( _ ) , do: :ok
82+
83+ def validate ( _module , % _ { } = data ) do
84+ validate ( data )
85+ end
86+
87+ def validate ( module , data ) when is_map ( data ) do
4688 module
4789 |> struct ( data )
4890 |> ProtoValidator.Verifiable . validate ( )
91+ rescue
92+ err -> { :error , inspect ( err ) }
4993 end
94+
95+ def validate ( _ , _ ) , do: :ok
5096end
0 commit comments