#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Limits {
pub(crate) list_members: u16,
pub(crate) inner_list_members: u16,
pub(crate) params: u16,
pub(crate) dictionary_members: u16,
pub(crate) key_len: u16,
pub(crate) string_len: u16,
pub(crate) token_len: u16,
pub(crate) byte_seq_len: u32,
pub(crate) empty_elements: u16,
pub(crate) comment_depth: u8,
pub(crate) ranges: u16,
pub(crate) rfc2231_sections: u8,
pub(crate) encoded_words: u16,
pub(crate) hops: u8,
pub(crate) allow_leap_second: bool,
pub(crate) duplicate_params: DuplicatePolicy,
}
pub(crate) const MAX_RFC2231_SECTIONS: u8 = 32;
impl Limits {
pub const DEFAULT: Self = Self {
list_members: 1024,
inner_list_members: 256,
params: 256,
dictionary_members: 1024,
key_len: 256,
string_len: 1024,
token_len: 512,
byte_seq_len: 16384,
empty_elements: 16,
comment_depth: 8,
ranges: 16,
rfc2231_sections: MAX_RFC2231_SECTIONS,
encoded_words: 64,
hops: 16,
allow_leap_second: false,
duplicate_params: DuplicatePolicy::Refuse,
};
#[must_use]
pub const fn new() -> Self {
Self::DEFAULT
}
#[must_use]
pub const fn max_list_members(self, n: u16) -> Self {
Self {
list_members: n,
..self
}
}
#[must_use]
pub const fn max_inner_list_members(self, n: u16) -> Self {
Self {
inner_list_members: n,
..self
}
}
#[must_use]
pub const fn max_params(self, n: u16) -> Self {
Self { params: n, ..self }
}
#[must_use]
pub const fn max_dictionary_members(self, n: u16) -> Self {
Self {
dictionary_members: n,
..self
}
}
#[must_use]
pub const fn max_key_len(self, n: u16) -> Self {
Self { key_len: n, ..self }
}
#[must_use]
pub const fn max_string_len(self, n: u16) -> Self {
Self {
string_len: n,
..self
}
}
#[must_use]
pub const fn max_token_len(self, n: u16) -> Self {
Self {
token_len: n,
..self
}
}
#[must_use]
pub const fn max_byte_seq_len(self, n: u32) -> Self {
Self {
byte_seq_len: n,
..self
}
}
#[must_use]
pub const fn max_empty_elements(self, n: u16) -> Self {
Self {
empty_elements: n,
..self
}
}
#[must_use]
pub const fn max_comment_depth(self, n: u8) -> Self {
Self {
comment_depth: n,
..self
}
}
#[must_use]
pub const fn max_ranges(self, n: u16) -> Self {
Self { ranges: n, ..self }
}
#[must_use]
pub const fn max_rfc2231_sections(self, n: u8) -> Self {
let n = if n > MAX_RFC2231_SECTIONS {
MAX_RFC2231_SECTIONS
} else {
n
};
Self {
rfc2231_sections: n,
..self
}
}
#[must_use]
pub const fn max_encoded_words(self, n: u16) -> Self {
Self {
encoded_words: n,
..self
}
}
#[must_use]
pub const fn max_hops(self, n: u8) -> Self {
Self { hops: n, ..self }
}
#[must_use]
pub const fn allow_leap_second(self, yes: bool) -> Self {
Self {
allow_leap_second: yes,
..self
}
}
#[must_use]
pub const fn duplicate_params(self, p: DuplicatePolicy) -> Self {
Self {
duplicate_params: p,
..self
}
}
}
impl Default for Limits {
fn default() -> Self {
Self::DEFAULT
}
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub enum DuplicatePolicy {
#[default]
Refuse,
First,
Last,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_limits_defaults_meet_rfc_minimums() {
let l = Limits::new();
assert_eq!(l, Limits::default());
assert!(l.list_members >= 1024);
assert!(l.inner_list_members >= 256);
assert!(l.params >= 256);
assert!(l.dictionary_members >= 1024);
assert!(l.key_len >= 64);
assert!(l.string_len >= 1024);
assert!(l.token_len >= 512);
assert!(l.byte_seq_len >= 16384);
assert!(!l.allow_leap_second);
assert_eq!(l.duplicate_params, DuplicatePolicy::Refuse);
}
#[test]
fn test_limits_setters_set_one_field() {
let l = Limits::DEFAULT
.max_list_members(1)
.max_inner_list_members(2)
.max_params(3)
.max_dictionary_members(4)
.max_key_len(5)
.max_string_len(6)
.max_token_len(7)
.max_byte_seq_len(8)
.max_empty_elements(9)
.max_comment_depth(10)
.max_ranges(11)
.max_rfc2231_sections(12)
.max_encoded_words(13)
.max_hops(14)
.allow_leap_second(true)
.duplicate_params(DuplicatePolicy::First);
assert_eq!(
(
l.list_members,
l.inner_list_members,
l.params,
l.dictionary_members
),
(1, 2, 3, 4)
);
assert_eq!(
(l.key_len, l.string_len, l.token_len, l.byte_seq_len),
(5, 6, 7, 8)
);
assert_eq!((l.empty_elements, l.comment_depth, l.ranges), (9, 10, 11));
assert_eq!((l.rfc2231_sections, l.encoded_words, l.hops), (12, 13, 14));
assert!(l.allow_leap_second);
assert_eq!(l.duplicate_params, DuplicatePolicy::First);
}
#[test]
fn test_limits_rfc2231_sections_capped_at_32() {
assert_eq!(
Limits::DEFAULT.max_rfc2231_sections(200).rfc2231_sections,
32
);
}
}