#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LexConfig {
max_string_length: usize,
max_recursion_depth: usize,
max_field_count: usize,
max_paren_depth: usize,
}
impl LexConfig {
pub const DEFAULT_MAX_STRING_LENGTH: usize = 100 * 1024 * 1024;
pub const DEFAULT_MAX_RECURSION_DEPTH: usize = 10_000;
pub const DEFAULT_MAX_FIELD_COUNT: usize = 10_000_000;
pub const DEFAULT_MAX_PAREN_DEPTH: usize = 1_000;
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn with_max_string_length(mut self, max: usize) -> Self {
self.max_string_length = max;
self
}
#[inline]
pub fn with_max_recursion_depth(mut self, max: usize) -> Self {
self.max_recursion_depth = max;
self
}
#[inline]
pub fn with_max_field_count(mut self, max: usize) -> Self {
self.max_field_count = max;
self
}
#[inline]
pub fn with_max_paren_depth(mut self, max: usize) -> Self {
self.max_paren_depth = max;
self
}
#[inline]
pub fn max_string_length(&self) -> usize {
self.max_string_length
}
#[inline]
pub fn max_recursion_depth(&self) -> usize {
self.max_recursion_depth
}
#[inline]
pub fn max_field_count(&self) -> usize {
self.max_field_count
}
#[inline]
pub fn max_paren_depth(&self) -> usize {
self.max_paren_depth
}
#[inline]
pub fn strict() -> Self {
Self {
max_string_length: 64 * 1024, max_recursion_depth: 32, max_field_count: 1_000, max_paren_depth: 16, }
}
#[inline]
pub fn permissive() -> Self {
Self {
max_string_length: 100 * 1024 * 1024, max_recursion_depth: 1_000, max_field_count: 1_000_000, max_paren_depth: 256, }
}
#[inline]
pub fn check_string_length(&self, length: usize) -> bool {
length <= self.max_string_length
}
#[inline]
pub fn check_recursion_depth(&self, depth: usize) -> bool {
depth <= self.max_recursion_depth
}
#[inline]
pub fn check_field_count(&self, count: usize) -> bool {
count <= self.max_field_count
}
#[inline]
pub fn check_paren_depth(&self, depth: usize) -> bool {
depth <= self.max_paren_depth
}
}
impl Default for LexConfig {
fn default() -> Self {
Self {
max_string_length: Self::DEFAULT_MAX_STRING_LENGTH,
max_recursion_depth: Self::DEFAULT_MAX_RECURSION_DEPTH,
max_field_count: Self::DEFAULT_MAX_FIELD_COUNT,
max_paren_depth: Self::DEFAULT_MAX_PAREN_DEPTH,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_new() {
let config = LexConfig::new();
assert_eq!(
config.max_string_length(),
LexConfig::DEFAULT_MAX_STRING_LENGTH
);
assert_eq!(
config.max_recursion_depth(),
LexConfig::DEFAULT_MAX_RECURSION_DEPTH
);
assert_eq!(config.max_field_count(), LexConfig::DEFAULT_MAX_FIELD_COUNT);
assert_eq!(config.max_paren_depth(), LexConfig::DEFAULT_MAX_PAREN_DEPTH);
}
#[test]
fn test_config_default() {
let config = LexConfig::default();
assert_eq!(config.max_string_length(), 100 * 1024 * 1024);
assert_eq!(config.max_recursion_depth(), 10_000);
assert_eq!(config.max_field_count(), 10_000_000);
assert_eq!(config.max_paren_depth(), 1_000);
}
#[test]
fn test_config_strict() {
let config = LexConfig::strict();
assert_eq!(config.max_string_length(), 64 * 1024);
assert_eq!(config.max_recursion_depth(), 32);
assert_eq!(config.max_field_count(), 1_000);
assert_eq!(config.max_paren_depth(), 16);
}
#[test]
fn test_config_permissive() {
let config = LexConfig::permissive();
assert_eq!(config.max_string_length(), 100 * 1024 * 1024);
assert_eq!(config.max_recursion_depth(), 1_000);
assert_eq!(config.max_field_count(), 1_000_000);
assert_eq!(config.max_paren_depth(), 256);
}
#[test]
fn test_with_max_string_length() {
let config = LexConfig::new().with_max_string_length(5000);
assert_eq!(config.max_string_length(), 5000);
}
#[test]
fn test_with_max_recursion_depth() {
let config = LexConfig::new().with_max_recursion_depth(50);
assert_eq!(config.max_recursion_depth(), 50);
}
#[test]
fn test_with_max_field_count() {
let config = LexConfig::new().with_max_field_count(500);
assert_eq!(config.max_field_count(), 500);
}
#[test]
fn test_with_max_paren_depth() {
let config = LexConfig::new().with_max_paren_depth(32);
assert_eq!(config.max_paren_depth(), 32);
}
#[test]
fn test_builder_chaining() {
let config = LexConfig::new()
.with_max_string_length(1000)
.with_max_recursion_depth(20)
.with_max_field_count(100)
.with_max_paren_depth(16);
assert_eq!(config.max_string_length(), 1000);
assert_eq!(config.max_recursion_depth(), 20);
assert_eq!(config.max_field_count(), 100);
assert_eq!(config.max_paren_depth(), 16);
}
#[test]
fn test_check_string_length_within_limit() {
let config = LexConfig::new().with_max_string_length(100);
assert!(config.check_string_length(50));
assert!(config.check_string_length(100));
}
#[test]
fn test_check_string_length_exceeds_limit() {
let config = LexConfig::new().with_max_string_length(100);
assert!(!config.check_string_length(101));
assert!(!config.check_string_length(1000));
}
#[test]
fn test_check_recursion_depth_within_limit() {
let config = LexConfig::new().with_max_recursion_depth(10);
assert!(config.check_recursion_depth(5));
assert!(config.check_recursion_depth(10));
}
#[test]
fn test_check_recursion_depth_exceeds_limit() {
let config = LexConfig::new().with_max_recursion_depth(10);
assert!(!config.check_recursion_depth(11));
assert!(!config.check_recursion_depth(100));
}
#[test]
fn test_check_field_count_within_limit() {
let config = LexConfig::new().with_max_field_count(1000);
assert!(config.check_field_count(500));
assert!(config.check_field_count(1000));
}
#[test]
fn test_check_field_count_exceeds_limit() {
let config = LexConfig::new().with_max_field_count(1000);
assert!(!config.check_field_count(1001));
assert!(!config.check_field_count(10000));
}
#[test]
fn test_check_paren_depth_within_limit() {
let config = LexConfig::new().with_max_paren_depth(32);
assert!(config.check_paren_depth(16));
assert!(config.check_paren_depth(32));
}
#[test]
fn test_check_paren_depth_exceeds_limit() {
let config = LexConfig::new().with_max_paren_depth(32);
assert!(!config.check_paren_depth(33));
assert!(!config.check_paren_depth(100));
}
#[test]
fn test_zero_limits() {
let config = LexConfig::new()
.with_max_string_length(0)
.with_max_recursion_depth(0)
.with_max_field_count(0)
.with_max_paren_depth(0);
assert_eq!(config.max_string_length(), 0);
assert_eq!(config.max_recursion_depth(), 0);
assert_eq!(config.max_field_count(), 0);
assert_eq!(config.max_paren_depth(), 0);
assert!(!config.check_string_length(1));
assert!(!config.check_recursion_depth(1));
assert!(!config.check_field_count(1));
assert!(!config.check_paren_depth(1));
}
#[test]
fn test_max_usize_limits() {
let config = LexConfig::new()
.with_max_string_length(usize::MAX)
.with_max_recursion_depth(usize::MAX)
.with_max_field_count(usize::MAX)
.with_max_paren_depth(usize::MAX);
assert_eq!(config.max_string_length(), usize::MAX);
assert_eq!(config.max_recursion_depth(), usize::MAX);
assert_eq!(config.max_field_count(), usize::MAX);
assert_eq!(config.max_paren_depth(), usize::MAX);
assert!(config.check_string_length(usize::MAX));
assert!(config.check_recursion_depth(usize::MAX));
assert!(config.check_field_count(usize::MAX));
assert!(config.check_paren_depth(usize::MAX));
}
#[test]
fn test_check_boundary_values() {
let config = LexConfig::new().with_max_string_length(100);
assert!(config.check_string_length(0));
assert!(config.check_string_length(100));
assert!(!config.check_string_length(101));
}
#[test]
fn test_config_equality() {
let a = LexConfig::new();
let b = LexConfig::new();
assert_eq!(a, b);
let c = LexConfig::new().with_max_string_length(5000);
assert_ne!(a, c);
}
#[test]
fn test_config_clone() {
let original = LexConfig::new().with_max_string_length(5000);
let cloned = original;
assert_eq!(original, cloned);
}
#[test]
fn test_config_debug() {
let config = LexConfig::new();
let debug = format!("{:?}", config);
assert!(debug.contains("LexConfig"));
}
#[test]
fn test_strict_vs_default() {
let strict = LexConfig::strict();
let default = LexConfig::default();
assert!(strict.max_string_length() < default.max_string_length());
assert!(strict.max_recursion_depth() < default.max_recursion_depth());
assert!(strict.max_field_count() < default.max_field_count());
assert!(strict.max_paren_depth() < default.max_paren_depth());
}
#[test]
fn test_permissive_vs_default() {
let permissive = LexConfig::permissive();
let default = LexConfig::default();
assert!(permissive.max_string_length() == default.max_string_length());
assert!(permissive.max_recursion_depth() < default.max_recursion_depth());
assert!(permissive.max_field_count() < default.max_field_count());
assert!(permissive.max_paren_depth() < default.max_paren_depth());
}
#[test]
fn test_custom_high_limits() {
let config = LexConfig::new()
.with_max_string_length(500 * 1024 * 1024) .with_max_recursion_depth(50_000) .with_max_field_count(100_000_000) .with_max_paren_depth(10_000);
assert_eq!(config.max_string_length(), 500 * 1024 * 1024);
assert_eq!(config.max_recursion_depth(), 50_000);
assert_eq!(config.max_field_count(), 100_000_000);
assert_eq!(config.max_paren_depth(), 10_000);
assert!(config.check_string_length(500 * 1024 * 1024));
assert!(config.check_recursion_depth(50_000));
assert!(config.check_field_count(100_000_000));
assert!(config.check_paren_depth(10_000));
}
#[test]
fn test_unlimited_config() {
let config = LexConfig::new()
.with_max_string_length(usize::MAX)
.with_max_recursion_depth(usize::MAX)
.with_max_field_count(usize::MAX)
.with_max_paren_depth(usize::MAX);
assert!(config.check_string_length(usize::MAX));
assert!(config.check_recursion_depth(usize::MAX));
assert!(config.check_field_count(usize::MAX));
assert!(config.check_paren_depth(usize::MAX));
assert!(config.check_string_length(1_000_000_000));
assert!(config.check_recursion_depth(1_000_000));
}
#[test]
fn test_use_case_large_datasets() {
let config = LexConfig::new()
.with_max_string_length(1024 * 1024 * 1024) .with_max_field_count(50_000_000);
assert!(config.check_string_length(500 * 1024 * 1024)); assert!(config.check_field_count(30_000_000)); }
#[test]
fn test_use_case_deep_nesting() {
let config = LexConfig::new()
.with_max_recursion_depth(100_000) .with_max_paren_depth(100_000);
assert!(config.check_recursion_depth(75_000));
assert!(config.check_paren_depth(75_000));
}
}