use super::ValueDescriptionsBuilder;
use crate::{
Error, MAX_NAME_SIZE, MAX_VALUE_DESCRIPTIONS, Result, ValueDescriptions, compat,
error::check_max_limit,
};
impl ValueDescriptionsBuilder {
fn extract_fields(&self) -> Result<&[(u64, String)]> {
if self.entries.is_empty() {
return Err(Error::Validation(Error::VALUE_DESCRIPTIONS_EMPTY));
}
if let Some(err) = check_max_limit(
self.entries.len(),
MAX_VALUE_DESCRIPTIONS,
Error::Decoding(Error::VALUE_DESCRIPTIONS_TOO_MANY),
) {
return Err(err);
}
Ok(&self.entries)
}
#[must_use = "validation result should be checked"]
pub fn validate(self) -> Result<Self> {
self.extract_fields()?;
Ok(self)
}
pub fn build(self) -> Result<ValueDescriptions> {
let entries = self.extract_fields()?;
let mut compat_entries: compat::Vec<
(u64, compat::String<{ MAX_NAME_SIZE }>),
{ MAX_VALUE_DESCRIPTIONS },
> = compat::Vec::new();
for (value, desc) in entries {
let compat_desc = compat::String::try_from(desc.as_str())
.map_err(|_| Error::Validation(Error::MAX_NAME_SIZE_EXCEEDED))?;
compat_entries
.push((*value, compat_desc))
.map_err(|_| Error::Validation(Error::VALUE_DESCRIPTIONS_TOO_MANY))?;
}
Ok(ValueDescriptions::new(compat_entries))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_builder_new() {
let builder = ValueDescriptionsBuilder::new();
assert!(builder.build().is_err());
}
#[test]
fn test_builder_default() {
let builder = ValueDescriptionsBuilder::default();
assert!(builder.build().is_err());
}
#[test]
fn test_builder_empty_fails() {
let result = ValueDescriptionsBuilder::new().build();
assert!(result.is_err());
}
#[test]
fn test_builder_validate_empty_fails() {
let result = ValueDescriptionsBuilder::new().validate();
assert!(result.is_err());
}
#[test]
fn test_builder_validate_valid() {
let result = ValueDescriptionsBuilder::new().add_entry(0, "Off").validate();
assert!(result.is_ok());
}
#[test]
fn test_builder_at_max_limit() {
let mut builder = ValueDescriptionsBuilder::new();
for i in 0..MAX_VALUE_DESCRIPTIONS {
builder = builder.add_entry(i as u64, format!("Value{}", i));
}
let vd = builder.build().unwrap();
assert_eq!(vd.len(), MAX_VALUE_DESCRIPTIONS);
}
#[test]
fn test_builder_ignores_entries_over_limit() {
let mut builder = ValueDescriptionsBuilder::new();
for i in 0..=MAX_VALUE_DESCRIPTIONS {
builder = builder.add_entry(i as u64, format!("Value{}", i));
}
let vd = builder.build().unwrap();
assert_eq!(vd.len(), MAX_VALUE_DESCRIPTIONS);
}
#[test]
fn test_builder_description_name_too_long() {
let long_desc = "A".repeat(MAX_NAME_SIZE + 1);
let result = ValueDescriptionsBuilder::new().add_entry(0, long_desc).build();
assert!(result.is_err());
}
#[test]
fn test_builder_single_entry() {
let vd = ValueDescriptionsBuilder::new().add_entry(42, "Answer").build().unwrap();
assert_eq!(vd.len(), 1);
assert_eq!(vd.get(42), Some("Answer"));
}
#[test]
fn test_builder_clone() {
let builder = ValueDescriptionsBuilder::new().add_entry(0, "Off").add_entry(1, "On");
let cloned = builder.clone();
let vd1 = builder.build().unwrap();
let vd2 = cloned.build().unwrap();
assert_eq!(vd1.len(), vd2.len());
}
}