Skip to main content

Module reflection_usage

Module reflection_usage 

Source
Expand description

§Usage With Pre Built Protos

The preferred usage for this crate is to define the items in rust, and to generate the .proto files from it rather than the other way around, but it is also possible to use it purely for the validation side of things.

In this case, it is possible to use pre-build proto files that have been marked with protovalidate annotations, and generate the validation logic accordingly.

To do that, you must first add protify-build to the build-dependencies.

For convenience, the builder exports the DescriptorDataConfig struct, which you can use to gather information about the elements of a package while the validators are being set (which can often be useful to handle things like oneof attributes which aren’t very ergonomic to set up in prost in a programmatic way).

The DescriptorDataConfig::set_up_validators method can then be used to set up the validators for the target packages while collecting the decided data.

If you desire to just set up the validators without gathering any other data, you can just call the homonymous set_up_validators function exported from the root of the crate.

use std::{env, path::PathBuf};

use prost_build::Config;
use protify_build::DescriptorDataConfig;

fn main() -> Result<(), Box<dyn std::error::Error>> {
	println!("cargo:rerun-if-changed=../proto");

	let out_dir = env::var("OUT_DIR")
		.map(PathBuf::from)
		.unwrap_or(env::temp_dir());

	// Set path for descriptor output
	let descriptor_path = out_dir.join("file_descriptor_set.bin");

	// Your proto files and dependencies
	let include_paths = &["proto", "proto_deps"];

	// Helper to get all the files in a directory
	let files = protify_build::get_proto_files("proto");

	let mut config = Config::new();
	config
		.file_descriptor_set_path(&descriptor_path)
		// Required, if bytes fields are used
		.bytes(["."])
		.out_dir(&out_dir);

	let _ = builder::set_up_validators(
		&mut config,
		files,
		include_paths,
		// The packages for which you want to apply the validators.
		// If a message has validators or is a field of another message
		// with validators, then its package must be added here.
		&["test_schemas.v1"],
	)?;

	// Compile the protos
	config.compile_protos(files, include_paths)?;

	// Emit env for descriptor location
	println!(
		"cargo:rustc-env=PROTO_DESCRIPTOR_SET={}",
		descriptor_path.display()
	);

	Ok(())
}

After this setup:

If the cel feature is enabled, CelValue and CelOneof will also be implemented for messages and oneofs.

Just like the non-reflection-based version of this crate, this will also automatically generate a check_validators method on each message and oneof, as well as a test that automatically calls this method and panics on failure, in order to ensure that validators represent valid configurations. For more information about this, visit the correctness section.