use super::JsonValueBudget;
use super::JsonValueLimitsBuilder;
use super::internal::PreparedJsonAdmission;
use crate::json::JsonMeasurement;
use crate::json::JsonResource;
use crate::resource::MeasuredBudgetError;
use crate::resource::ResourceLimit;
use crate::resource::ResourceQuantity;
use crate::structure::StructureLimits;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct JsonValueLimits<R = JsonResource, Q = usize>
where
Q: ResourceQuantity,
{
structure: StructureLimits<R, Q>,
max_string_bytes: Option<ResourceLimit<R, Q>>,
max_number_bytes: Option<ResourceLimit<R, Q>>,
max_payload_bytes: Option<ResourceLimit<R, Q>>,
}
impl<R, Q> Default for JsonValueLimits<R, Q>
where
Q: ResourceQuantity,
{
fn default() -> Self {
Self::new()
}
}
impl<R, Q> JsonValueLimits<R, Q>
where
Q: ResourceQuantity,
{
#[inline]
#[must_use = "the point check result must be handled"]
pub const fn new() -> Self {
Self {
structure: StructureLimits::new(),
max_string_bytes: None,
max_number_bytes: None,
max_payload_bytes: None,
}
}
#[inline]
#[must_use]
pub const fn builder() -> JsonValueLimitsBuilder<R, Q> {
JsonValueLimitsBuilder::new()
}
#[inline]
#[must_use]
pub const fn into_builder(self) -> JsonValueLimitsBuilder<R, Q> {
JsonValueLimitsBuilder::from_limits(self)
}
#[must_use]
#[inline(always)]
pub const fn has_limits(&self) -> bool {
self.structure.has_limits()
|| self.max_string_bytes.is_some()
|| self.max_number_bytes.is_some()
|| self.max_payload_bytes.is_some()
}
#[must_use]
#[inline(always)]
pub const fn structure_limits(&self) -> &StructureLimits<R, Q> {
&self.structure
}
#[must_use]
#[inline]
pub fn into_structure_limits(self) -> StructureLimits<R, Q> {
self.structure
}
#[must_use]
#[inline(always)]
pub const fn max_depth(&self) -> Option<Q> {
self.structure.max_depth()
}
#[must_use]
#[inline(always)]
pub const fn max_nodes(&self) -> Option<Q> {
self.structure.max_nodes()
}
#[must_use]
#[inline(always)]
pub const fn max_sequence_items(&self) -> Option<Q> {
self.structure.max_sequence_items()
}
#[must_use]
#[inline(always)]
pub const fn max_map_entries(&self) -> Option<Q> {
self.structure.max_map_entries()
}
#[must_use]
#[inline(always)]
pub const fn max_key_bytes(&self) -> Option<Q> {
self.structure.max_key_bytes()
}
#[must_use]
#[inline(always)]
pub const fn string_bytes_limit(&self) -> Option<&ResourceLimit<R, Q>> {
self.max_string_bytes.as_ref()
}
#[must_use]
#[inline(always)]
pub const fn number_bytes_limit(&self) -> Option<&ResourceLimit<R, Q>> {
self.max_number_bytes.as_ref()
}
#[must_use]
#[inline(always)]
pub const fn payload_bytes_limit(&self) -> Option<&ResourceLimit<R, Q>> {
self.max_payload_bytes.as_ref()
}
#[must_use]
#[inline(always)]
pub const fn max_string_bytes(&self) -> Option<Q> {
limit_maximum(self.max_string_bytes.as_ref())
}
#[must_use]
#[inline(always)]
pub const fn max_number_bytes(&self) -> Option<Q> {
limit_maximum(self.max_number_bytes.as_ref())
}
#[must_use]
#[inline(always)]
pub const fn max_payload_bytes(&self) -> Option<Q> {
limit_maximum(self.max_payload_bytes.as_ref())
}
#[inline]
#[must_use = "the point check result must be handled"]
pub fn check_point(&self, measurement: JsonMeasurement) -> Result<(), MeasuredBudgetError<R, Q>>
where
R: Clone,
{
PreparedJsonAdmission::prepare(self, measurement)?.check_point(self)
}
#[inline]
#[must_use]
pub fn budget(self) -> JsonValueBudget<R, Q> {
JsonValueBudget::new(self)
}
pub(super) fn set_string_bytes_limit(&mut self, limit: ResourceLimit<R, Q>) {
self.max_string_bytes = Some(limit);
}
pub(super) fn set_number_bytes_limit(&mut self, limit: ResourceLimit<R, Q>) {
self.max_number_bytes = Some(limit);
}
pub(super) fn set_payload_bytes_limit(&mut self, limit: ResourceLimit<R, Q>) {
self.max_payload_bytes = Some(limit);
}
pub(super) fn set_structure_limits(&mut self, limits: StructureLimits<R, Q>) {
self.structure = limits;
}
}
#[inline(always)]
const fn limit_maximum<R, Q>(limit: Option<&ResourceLimit<R, Q>>) -> Option<Q>
where
Q: ResourceQuantity,
{
match limit {
Some(limit) => Some(limit.maximum()),
None => None,
}
}