use core::marker::PhantomData;
use alloc::vec::Vec;
use crate::{
param::IcalParam,
prop::{IcalProp, IcalPropName, spec::IcalPropSpec},
validator::{IcalValidateError, validate_prop},
value::IcalValue,
version::IcalVersion,
};
pub struct IcalPropBuilder<'a, L: IcalPropSpec> {
pub version: IcalVersion,
pub params: Vec<IcalParam<'a>>,
lens: PhantomData<L>,
}
impl<'a, L: IcalPropSpec> IcalPropBuilder<'a, L> {
pub fn new(version: IcalVersion) -> Self {
Self {
version,
params: Vec::new(),
lens: PhantomData,
}
}
pub fn param(mut self, param: IcalParam<'a>) -> Self {
self.params.push(param);
self
}
pub fn build(self, value: IcalValue<'a>) -> Result<IcalProp<'a>, Vec<IcalValidateError>> {
let prop = IcalProp {
name: IcalPropName::Kind(L::KIND),
params: self.params,
value,
};
let mut errors = Vec::new();
validate_prop(&prop, self.version, &mut errors);
if errors.is_empty() {
Ok(prop)
} else {
Err(errors)
}
}
}
#[cfg(test)]
mod tests {
use alloc::{borrow::Cow, vec};
use crate::{
builder::IcalPropBuilder,
param::IcalParam,
prop::summary::SUMMARY,
value::{IcalValue, text::IcalText},
version::IcalVersion,
};
#[test]
fn builds_a_property_pinning_the_name_from_the_spec() {
let prop = IcalPropBuilder::<SUMMARY>::new(IcalVersion::V2_0)
.param(IcalParam::Language(Cow::Borrowed("en")))
.build(IcalValue::Text(IcalText(Cow::Borrowed("Lunch"))))
.expect("SUMMARY takes text with a LANGUAGE param");
assert_eq!(&*prop.name, "SUMMARY");
assert_eq!(prop.params, vec![IcalParam::Language(Cow::Borrowed("en"))]);
assert_eq!(
prop.value,
IcalValue::Text(IcalText(Cow::Borrowed("Lunch")))
);
}
}