Skip to content

Commit

Permalink
Add string uuid rule (elixir-protobuf#3)
Browse files Browse the repository at this point in the history
* Handle oneof validation rules

* Add UUID string validation to extension

* Add message with UUID validation rule to example.proto

* Add uuid rule tests

* Add vex rule translation
  • Loading branch information
fabriziosestito authored Sep 30, 2022
1 parent 1a1cd12 commit 88c0cf0
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 4 deletions.
18 changes: 15 additions & 3 deletions lib/proto_validator/protoc/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,28 @@ defmodule ProtoValidator.Protoc.Utils do
rule_str =
rules
|> Enum.map(fn
{_k, nil} -> nil
{k, v} when is_map(v) -> "#{k}: [#{get_rule_str(v)}]"
{k, v} -> "#{k}: #{get_rule_str(v)}"
{_k, nil} ->
nil

{k, v} when is_map(v) ->
"#{k}: [#{get_rule_str(v)}]"

{k, v} when is_tuple(v) ->
"#{k}: [#{get_rule_str(v)}]"

{k, v} ->
"#{k}: #{get_rule_str(v)}"
end)
|> Enum.reject(&is_nil/1)
|> Enum.join(", ")

"#{rule_str}"
end

def get_rule_str({type, type_rules}) when is_boolean(type_rules) do
"#{type}: #{get_rule_str(type_rules)}"
end

def get_rule_str({type, type_rules}) do
"#{type}: [#{get_rule_str(type_rules)}]"
end
Expand Down
3 changes: 3 additions & 0 deletions lib/validate.pb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ defmodule Validate.StringRules do
@moduledoc false
use Protobuf, protoc_gen_elixir_version: "0.11.0", syntax: :proto2

oneof :well_known, 0

field :min_len, 2, optional: true, type: :uint64
field :max_len, 3, optional: true, type: :uint64
field :uuid, 22, optional: true, type: :bool, oneof: 0
end

defmodule Validate.RepeatedRules do
Expand Down
8 changes: 7 additions & 1 deletion lib/validator/vex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,11 @@ defmodule ProtoValidator.Validator.Vex do
{:function, {ProtoValidator.Validator, :validate_uniq}}
end

defp translate_rule(_), do: nil
defp translate_rule({:string, {:well_known, {:uuid, true}}}) do
{Vex.Validators.Uuid, [format: :default]}
end

defp translate_rule(_) do
nil
end
end
12 changes: 12 additions & 0 deletions src/validate.proto
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ message StringRules {
// characters (Unicode code points) at a maximum. Note that the number of
// characters may differ from the number of bytes in the string.
optional uint64 max_len = 3;



// WellKnown rules provide advanced constraints against common string
// patterns
oneof well_known {


// Uuid specifies that the field must be a valid UUID as defined by
// RFC 4122
bool uuid = 22;
}
}

// RepeatedRules describe the constraints applied to `repeated` values
Expand Down
4 changes: 4 additions & 0 deletions test/proto/example.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ message Foo {
int32: {gte: 0, lte: 10}
}];
}

message Bar {
string uuid = 1 [(validate.rules).string.uuid = true];
}
7 changes: 7 additions & 0 deletions test/proto_gen/example.pb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,10 @@ defmodule Examplepb.Foo do

field :int32, 1, type: :int32, deprecated: false
end

defmodule Examplepb.Bar do
@moduledoc false
use Protobuf, protoc_gen_elixir_version: "0.11.0", syntax: :proto3

field :uuid, 1, type: :string, deprecated: false
end
7 changes: 7 additions & 0 deletions test/proto_gen/example.pb.validate.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,10 @@ defmodule ProtoValidator.Gen.Examplepb.Foo do

validate(:int32, type: :int32, int32: [gte: 0, lte: 10])
end

defmodule ProtoValidator.Gen.Examplepb.Bar do
@moduledoc false
use ProtoValidator, entity: Examplepb.Bar

validate(:uuid, type: :string, string: [well_known: [uuid: true]])
end
81 changes: 81 additions & 0 deletions test/proto_validator_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -236,4 +236,85 @@ defmodule ProtoValidator.ProtoValidatorTest do
assert {:error, "Invalid int32, should less than or equal to 10"} =
ProtoValidator.validate(%Examplepb.Foo{int32: 11})
end

describe "validate string uuid rule" do
test "should be valid with a nil uuid" do
assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "00000000-0000-0000-0000-000000000000"
})
end

test "should be valid with a v1 uuid" do
assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "b45c0c80-8880-11e9-a5b1-000000000000"
})

assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "B45C0C80-8880-11E9-A5B1-000000000000"
})
end

test "should be valid with a v2 uuid" do
assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "b45c0c80-8880-21e9-a5b1-000000000000"
})

assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "B45C0C80-8880-21E9-A5B1-000000000000"
})
end

test "should be valid with a v3 uuid" do
assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "a3bb189e-8bf9-3888-9912-ace4e6543002"
})

assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "A3BB189E-8BF9-3888-9912-ACE4E6543002"
})
end

test "should be valid with a v4 uuid" do
assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "8b208305-00e8-4460-a440-5e0dcd83bb0a"
})

assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "8B208305-00E8-4460-A440-5E0DCD83BB0A"
})
end

test "should be valid with a v5 uuid" do
assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "a6edc906-2f9f-5fb2-a373-efac406f0ef2"
})

assert :ok =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "A6EDC906-2F9F-5FB2-A373-EFAC406F0EF2"
})
end

test "should be invalid with a non-uuid string" do
assert {:error, "Invalid uuid, must be a valid UUID string in default format"} =
ProtoValidator.validate(%Examplepb.Bar{uuid: "invalid"})
end

test "should be invalid with a bad uuid" do
assert {:error, "Invalid uuid, must be a valid UUID string in default format"} =
ProtoValidator.validate(%Examplepb.Bar{
uuid: "ffffffff-ffff-ffff-ffff-fffffffffffff"
})
end
end
end

0 comments on commit 88c0cf0

Please sign in to comment.