use super::JsonDecodeAttempt;
use super::JsonDecodeLimits;
use super::internal::DecodeStorage;
use crate::json::JsonResource;
use crate::json::JsonValueBudget;
use crate::resource::ResourceBudget;
use crate::resource::ResourceQuantity;
#[derive(Debug)]
pub struct JsonDecodeSession<'a, R = JsonResource, Q = usize>
where
Q: ResourceQuantity,
{
storage: DecodeStorage<'a, R, Q>,
}
impl<'a, R, Q> JsonDecodeSession<'a, R, Q>
where
R: Clone,
Q: ResourceQuantity,
{
#[inline]
#[must_use]
pub fn borrowing_value(value: &'a mut JsonValueBudget<R, Q>) -> Self {
Self {
storage: DecodeStorage::Borrowed {
input: None,
normalized_input: None,
value,
},
}
}
#[inline]
#[must_use]
pub fn borrowing_input(input: &'a mut ResourceBudget<R, Q>, value: &'a mut JsonValueBudget<R, Q>) -> Self {
Self {
storage: DecodeStorage::Borrowed {
input: Some(input),
normalized_input: None,
value,
},
}
}
#[inline]
#[must_use]
pub fn borrowing_all(
input: &'a mut ResourceBudget<R, Q>,
normalized_input: &'a mut ResourceBudget<R, Q>,
value: &'a mut JsonValueBudget<R, Q>,
) -> Self {
Self {
storage: DecodeStorage::Borrowed {
input: Some(input),
normalized_input: Some(normalized_input),
value,
},
}
}
#[must_use]
pub fn begin_value(&mut self) -> JsonDecodeAttempt<'_, R, Q> {
let (input, normalized_input, value) = self.storage.split();
JsonDecodeAttempt::new(input, normalized_input, value.transaction())
}
#[must_use]
#[inline(always)]
pub fn input_budget(&self) -> Option<&ResourceBudget<R, Q>> {
match &self.storage {
DecodeStorage::Owned { input, .. } => input.as_ref(),
DecodeStorage::Borrowed { input, .. } => input.as_deref(),
}
}
#[must_use]
#[inline(always)]
pub fn max_input_bytes(&self) -> Option<Q> {
self.input_budget().map(ResourceBudget::limit)
}
#[must_use]
#[inline(always)]
pub fn max_normalized_input_bytes(&self) -> Option<Q> {
self.normalized_input_budget().map(ResourceBudget::limit)
}
#[must_use]
#[inline(always)]
pub fn normalized_input_budget(&self) -> Option<&ResourceBudget<R, Q>> {
match &self.storage {
DecodeStorage::Owned { normalized_input, .. } => normalized_input.as_ref(),
DecodeStorage::Borrowed { normalized_input, .. } => normalized_input.as_deref(),
}
}
#[must_use]
#[inline(always)]
pub fn value_budget(&self) -> &JsonValueBudget<R, Q> {
match &self.storage {
DecodeStorage::Owned { value, .. } => value,
DecodeStorage::Borrowed { value, .. } => value,
}
}
}
impl<R, Q> JsonDecodeSession<'static, R, Q>
where
R: Clone,
Q: ResourceQuantity,
{
#[inline]
#[must_use]
pub fn owned(limits: JsonDecodeLimits<R, Q>) -> Self {
let input = limits.input_bytes_limit().cloned().map(ResourceBudget::from_limit);
let normalized_input = limits
.normalized_input_bytes_limit()
.cloned()
.map(ResourceBudget::from_limit);
let value = JsonValueBudget::new(limits.into_value_limits());
Self {
storage: DecodeStorage::Owned {
input,
normalized_input,
value,
},
}
}
}