PB.Validate (PB.Validate v0.2.0)

Copy Markdown View Source

Runtime protovalidate validation.

Validation accepts the same public message term shape as PB.encode/4. Canonical maps, represented structs, identity oneofs, unwrapped messages, and adapted values are projected one message layer at a time before field rules, message rules, and CEL expressions read protobuf fields.

Validation rule failures return {:error, %PB.Validate.Error{}}. Unknown messages, message-name metadata mismatches, values that do not match the message shape, and projection failures return the PB.Error struct PB.encode/4 would (PB.SchemaError or PB.ValueError, with operation: :validate); a CEL rule that fails to evaluate returns CEL.Error. Those are errors rather than protovalidate violations, so they are not PB.Validate.Errors.

Schemas may be supplied either as a compiled schema map or as a module that use PB.Schema, and must be compiled with this module as a plugin, which compiles the protovalidate rules in the schema's descriptor options:

schema = PB.compile(descriptor_set, plugins: [PB.Validate])

defmodule MyApp.Schema do
  use PB.Schema, descriptor: "priv/proto/schema.binpb", plugins: [PB.Validate]
end

Compiling raises PB.Validate.CompileError for rules that are not valid for the schema, and PB.SchemaError for a schema whose rules can't be read, as its descriptor set lacks buf/validate/validate.proto.

Summary

Functions

Compiles the protovalidate rules of a prepared schema into it.

Returns the functions use PB.Schema adds to a schema module compiled with this plugin: validate/2,3 and validate!/2,3, which call validate/4 and validate!/4 with the module's schema.

Converts validation violations to the canonical buf.validate.Violations protobuf field shape.

Validates data as message_name using schema.

Validates data as message_name using schema, raising on validation or option failure.

Types

result()

@type result() :: :ok | {:error, PB.Validate.Error.t() | PB.Error.t() | CEL.Error.t()}

Functions

compile(schema, opts)

@spec compile(
  PB.schema(),
  keyword()
) :: PB.schema()

Compiles the protovalidate rules of a prepared schema into it.

This is the PB.Schema.Plugin callback; pass plugins: [PB.Validate] to PB.compile/2 or use PB.Schema rather than calling it. It takes no options.

schema_functions(opts)

@spec schema_functions(keyword()) :: Macro.t()

Returns the functions use PB.Schema adds to a schema module compiled with this plugin: validate/2,3 and validate!/2,3, which call validate/4 and validate!/4 with the module's schema.

to_proto_violations(violations)

@spec to_proto_violations(
  validation_result()
  | PB.Validate.Error.t()
  | [PB.Validate.Violation.t() | map()]
) :: %{violations: [map()]}

Converts validation violations to the canonical buf.validate.Violations protobuf field shape.

validate(data, schema, message_name, opts \\ [])

@spec validate(term(), PB.schema_source(), PB.message_name(), keyword()) :: result()

Validates data as message_name using schema.

Rule failures return {:error, %PB.Validate.Error{}}. Option failures return {:error, %PB.OptionError{}}, and unknown messages or values that do not match the message shape the PB.Error struct PB.encode/4 would. A CEL rule that fails to evaluate returns {:error, %CEL.Error{}}. Raises ArgumentError if schema was not compiled with plugins: [PB.Validate].

Accepted options:

  • :context - a keyword list or map of context values, currently only :now (as below).
  • :now - timestamp used for CEL now: unix nanoseconds, DateTime, or a CEL timestamp tuple {:timestamp, unix_nanoseconds}.

validate!(data, schema, message_name, opts \\ [])

@spec validate!(term(), PB.schema_source(), PB.message_name(), keyword()) :: :ok

Validates data as message_name using schema, raising on validation or option failure.

See validate/4 for accepted options.