use super::JsonEncodeAttempt;
use super::JsonEncodeLimits;
use super::internal::EncodeStorage;
use crate::json::JsonResource;
use crate::json::JsonValueBudget;
use crate::resource::ResourceBudget;
use crate::resource::ResourceQuantity;
#[derive(Debug)]
pub struct JsonEncodeSession<'a, R = JsonResource, Q = usize>
where
Q: ResourceQuantity,
{
storage: EncodeStorage<'a, R, Q>,
}
impl<'a, R, Q> JsonEncodeSession<'a, R, Q>
where
R: Clone,
Q: ResourceQuantity,
{
#[inline]
#[must_use]
pub fn borrowing_value(value: &'a mut JsonValueBudget<R, Q>) -> Self {
Self {
storage: EncodeStorage::Borrowed { output: None, value },
}
}
#[inline]
#[must_use]
pub fn borrowing_output(output: &'a mut ResourceBudget<R, Q>, value: &'a mut JsonValueBudget<R, Q>) -> Self {
Self {
storage: EncodeStorage::Borrowed {
output: Some(output),
value,
},
}
}
#[must_use]
pub fn begin_value(&mut self) -> JsonEncodeAttempt<'_, R, Q> {
let (output, value) = self.storage.split();
JsonEncodeAttempt::new(output, value.transaction())
}
#[must_use]
#[inline(always)]
pub fn output_budget(&self) -> Option<&ResourceBudget<R, Q>> {
match &self.storage {
EncodeStorage::Owned { output, .. } => output.as_ref(),
EncodeStorage::Borrowed { output, .. } => output.as_deref(),
}
}
#[must_use]
#[inline(always)]
pub fn max_output_bytes(&self) -> Option<Q> {
self.output_budget().map(ResourceBudget::limit)
}
#[must_use]
#[inline(always)]
pub fn value_budget(&self) -> &JsonValueBudget<R, Q> {
match &self.storage {
EncodeStorage::Owned { value, .. } => value,
EncodeStorage::Borrowed { value, .. } => value,
}
}
}
impl<R, Q> JsonEncodeSession<'static, R, Q>
where
R: Clone,
Q: ResourceQuantity,
{
#[inline]
#[must_use]
pub fn from_limits(limits: JsonEncodeLimits<R, Q>) -> Self {
let output = limits.output_bytes_limit().cloned().map(ResourceBudget::from_limit);
let value = JsonValueBudget::new(limits.into_value_limits());
Self {
storage: EncodeStorage::Owned { output, value },
}
}
}