use crate::types::{QrError, QrResult, Version};
pub const DEFAULT_MAX_DATA_LENGTH: usize = 7_089;
pub const DEFAULT_MAX_RENDER_SIZE: (u32, u32) = (4_096, 4_096);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ResourceLimits {
pub max_data_length: usize,
pub max_version: Version,
pub max_render_size: (u32, u32),
}
impl Default for ResourceLimits {
fn default() -> Self {
Self {
max_data_length: DEFAULT_MAX_DATA_LENGTH,
max_version: Version::Normal(40),
max_render_size: DEFAULT_MAX_RENDER_SIZE,
}
}
}
impl ResourceLimits {
#[must_use]
pub const fn new(max_data_length: usize, max_version: Version, max_render_size: (u32, u32)) -> Self {
Self { max_data_length, max_version, max_render_size }
}
pub fn validate(self) -> QrResult<()> {
let valid_version = matches!(self.max_version, Version::Normal(1..=40));
let valid_render_size = self.max_render_size.0 != 0 && self.max_render_size.1 != 0;
if valid_version && valid_render_size { Ok(()) } else { Err(QrError::InvalidResourceLimits) }
}
}
#[cfg(test)]
mod tests {
use super::{DEFAULT_MAX_DATA_LENGTH, DEFAULT_MAX_RENDER_SIZE, ResourceLimits};
use crate::types::Version;
#[test]
fn default_budget_is_bounded() {
let limits = ResourceLimits::default();
assert_eq!(limits.max_data_length, DEFAULT_MAX_DATA_LENGTH);
assert_eq!(limits.max_version, Version::Normal(40));
assert_eq!(limits.max_render_size, DEFAULT_MAX_RENDER_SIZE);
assert!(limits.validate().is_ok());
}
#[test]
fn invalid_budget_is_rejected() {
assert!(ResourceLimits::new(1, Version::Micro(4), (1, 1)).validate().is_err());
assert!(ResourceLimits::new(1, Version::Normal(1), (0, 1)).validate().is_err());
}
}