use bon::Builder;
use crate::{
validators::{
any::*,
bool::*,
bytes::*,
cel::CelRule,
duration::*,
enums::*,
message::{MessageValidator, MessageValidatorBuilder},
numeric::*,
string::{StringValidator, StringValidatorBuilder},
timestamp::*,
Ignore, OptionValueList,
},
OptionValue, ProtoOption,
};
#[derive(Clone, Debug, Builder)]
pub struct RepeatedValidator {
#[builder(into)]
pub items: Option<ProtoOption>,
pub min_items: Option<u64>,
pub max_items: Option<u64>,
#[builder(with = || true)]
pub unique: Option<bool>,
#[builder(into)]
pub cel: Option<Box<[CelRule]>>,
#[builder(with = || true)]
pub required: Option<bool>,
#[builder(setters(vis = "", name = ignore))]
pub ignore: Option<Ignore>,
}
impl_ignore!(no_lifetime, RepeatedValidatorBuilder);
impl<S: repeated_validator_builder::State> From<RepeatedValidatorBuilder<S>> for ProtoOption {
#[track_caller]
fn from(value: RepeatedValidatorBuilder<S>) -> Self {
value.build().into()
}
}
impl From<RepeatedValidator> for ProtoOption {
#[track_caller]
fn from(validator: RepeatedValidator) -> ProtoOption {
let name = "(buf.validate.field)";
let mut values: OptionValueList = Vec::new();
insert_option!(validator, values, unique, bool);
insert_option!(validator, values, min_items, Uint);
insert_option!(validator, values, max_items, Uint);
if let Some(items_option) = validator.items {
values.push(("items".into(), (*items_option.value).clone()));
}
let mut option_value: OptionValueList = vec![(
"repeated".into(),
OptionValue::Message(values.into_boxed_slice()),
)];
insert_cel_rule!(validator, option_value);
insert_option!(validator, option_value, required, bool);
ProtoOption {
name,
value: OptionValue::Message(option_value.into_boxed_slice()).into(),
}
}
}
macro_rules! repeated_validator {
($validator_type:ident) => {
$crate::paste! {
#[doc(hidden)]
#[track_caller]
pub fn [< build_repeated_ $validator_type _validator_option >]<F, S: repeated_validator_builder::State>(config_fn: F) -> ProtoOption
where
F: FnOnce(RepeatedValidatorBuilder, [< $validator_type:camel ValidatorBuilder >]) -> RepeatedValidatorBuilder<S>,
{
let repeated_validator_builder: RepeatedValidatorBuilder = RepeatedValidator::builder();
let items_builder = [< $validator_type:camel Validator >]::builder();
let validator = config_fn(repeated_validator_builder, items_builder).build();
validator.into()
}
}
};
}
repeated_validator!(string);
repeated_validator!(any);
repeated_validator!(duration);
repeated_validator!(timestamp);
repeated_validator!(bytes);
repeated_validator!(bool);
repeated_validator!(enum);
repeated_validator!(int64);
repeated_validator!(int32);
repeated_validator!(sint64);
repeated_validator!(sint32);
repeated_validator!(sfixed64);
repeated_validator!(sfixed32);
repeated_validator!(uint64);
repeated_validator!(uint32);
repeated_validator!(fixed64);
repeated_validator!(fixed32);
repeated_validator!(double);
repeated_validator!(float);
repeated_validator!(message);