use crate::Error;
#[derive(Debug, Clone)]
#[must_use]
pub struct ODataLimits {
pub max_top: usize,
pub max_orderby_fields: usize,
pub max_filter_length: usize,
pub require_signed_cursors: bool,
pub cursor_hmac_key: Option<Vec<u8>>,
}
impl Default for ODataLimits {
fn default() -> Self {
Self {
max_top: 1000,
max_orderby_fields: 5,
max_filter_length: 2000,
require_signed_cursors: false,
cursor_hmac_key: None,
}
}
}
impl ODataLimits {
pub fn new() -> Self {
Self::default()
}
pub fn with_max_top(mut self, max_top: usize) -> Self {
self.max_top = max_top;
self
}
pub fn with_max_orderby_fields(mut self, max: usize) -> Self {
self.max_orderby_fields = max;
self
}
pub fn with_max_filter_length(mut self, max: usize) -> Self {
self.max_filter_length = max;
self
}
pub fn with_signed_cursors(mut self, key: Vec<u8>) -> Self {
self.require_signed_cursors = true;
self.cursor_hmac_key = Some(key);
self
}
pub fn validate_top(&self, top: usize) -> Result<(), Error> {
if top > self.max_top {
return Err(Error::InvalidLimit);
}
Ok(())
}
pub fn validate_filter(&self, filter: &str) -> Result<(), Error> {
if filter.len() > self.max_filter_length {
return Err(Error::InvalidFilter(format!(
"Filter expression exceeds maximum length of {} characters",
self.max_filter_length
)));
}
Ok(())
}
pub fn validate_orderby_count(&self, count: usize) -> Result<(), Error> {
if count > self.max_orderby_fields {
return Err(Error::InvalidOrderByField(format!(
"Too many orderby fields (max: {})",
self.max_orderby_fields
)));
}
Ok(())
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn test_default_limits() {
let limits = ODataLimits::default();
assert_eq!(limits.max_top, 1000);
assert_eq!(limits.max_orderby_fields, 5);
assert_eq!(limits.max_filter_length, 2000);
assert!(!limits.require_signed_cursors);
}
#[test]
fn test_validate_top_ok() {
let limits = ODataLimits::default();
assert!(limits.validate_top(500).is_ok());
assert!(limits.validate_top(1000).is_ok());
}
#[test]
fn test_validate_top_exceeds() {
let limits = ODataLimits::default();
assert!(limits.validate_top(1001).is_err());
}
#[test]
fn test_validate_filter_ok() {
let limits = ODataLimits::default();
assert!(limits.validate_filter("name eq 'John'").is_ok());
}
#[test]
fn test_validate_filter_too_long() {
let limits = ODataLimits::default();
let long_filter = "x".repeat(2001);
assert!(limits.validate_filter(&long_filter).is_err());
}
#[test]
fn test_validate_orderby_count_ok() {
let limits = ODataLimits::default();
assert!(limits.validate_orderby_count(3).is_ok());
assert!(limits.validate_orderby_count(5).is_ok());
}
#[test]
fn test_validate_orderby_count_exceeds() {
let limits = ODataLimits::default();
assert!(limits.validate_orderby_count(6).is_err());
}
#[test]
fn test_custom_limits() {
let limits = ODataLimits::new()
.with_max_top(100)
.with_max_orderby_fields(3)
.with_max_filter_length(500);
assert_eq!(limits.max_top, 100);
assert_eq!(limits.max_orderby_fields, 3);
assert_eq!(limits.max_filter_length, 500);
}
}