use super::low_level::Bytes;
use crate::Writer;
use std::marker::PhantomData;
pub struct ArrayWriter<'a> {
bytes: Bytes<'a>,
count: u64,
max_definite: Option<u64>,
}
impl<'a> ArrayWriter<'a> {
pub(crate) fn new(bytes: &'a mut Vec<u8>, max_definite: Option<u64>) -> Self {
Self {
bytes: Bytes::Borrowed(bytes),
count: 0,
max_definite,
}
}
fn non_tracking(&mut self, max_definite: Option<u64>) -> ArrayWriter {
ArrayWriter {
bytes: self.bytes.copy(),
count: 0,
max_definite,
}
}
pub fn set_max_definite_size(&mut self, size: Option<u64>) {
self.max_definite = size;
}
pub(crate) fn count(&self) -> u64 {
self.count
}
}
impl<'a> Writer for ArrayWriter<'a> {
type Output = Self;
fn bytes<T>(&mut self, f: impl FnOnce(&mut Vec<u8>) -> T) -> T {
self.count += 1;
f(self.bytes.as_mut())
}
fn into_output(self) -> Self::Output {
self
}
fn max_definite(&self) -> Option<u64> {
self.max_definite
}
fn set_max_definite(&mut self, max: Option<u64>) {
self.max_definite = max;
}
}
pub struct DictWriter<'a>(ArrayWriter<'a>);
impl<'a> DictWriter<'a> {
pub(crate) fn new(bytes: &'a mut Vec<u8>, max_definite: Option<u64>) -> Self {
Self(ArrayWriter::new(bytes, max_definite))
}
pub(crate) fn count(&self) -> u64 {
self.0.count
}
pub fn max_definite(&self) -> Option<u64> {
self.0.max_definite
}
pub fn set_max_definite_size(&mut self, size: Option<u64>) {
self.0.max_definite = size;
}
pub fn with_key(
&mut self,
key: &str,
f: impl FnOnce(SingleBuilder<'_, '_>) -> SingleResult,
) -> &mut Self {
self.with_cbor_key(|b| b.write_str(key, None), f)
}
pub fn with_cbor_key(
&mut self,
k: impl FnOnce(SingleBuilder<'_, '_>) -> SingleResult,
v: impl FnOnce(SingleBuilder<'_, '_>) -> SingleResult,
) -> &mut Self {
k(SingleBuilder(&mut self.0.non_tracking(self.0.max_definite)));
v(SingleBuilder(&mut self.0));
self
}
pub fn try_write_pair<E>(
&mut self,
f: impl FnOnce(KeyBuilder<'_, '_>) -> Result<SingleResult, E>,
) -> Result<&mut Self, E> {
f(KeyBuilder(&mut self.0))?;
Ok(self)
}
}
pub struct KeyBuilder<'a, 'b>(&'b mut ArrayWriter<'a>);
impl<'a, 'b> Writer for KeyBuilder<'a, 'b> {
type Output = SingleBuilder<'a, 'b>;
fn bytes<T>(&mut self, f: impl FnOnce(&mut Vec<u8>) -> T) -> T {
self.0.non_tracking(self.0.max_definite).bytes(f)
}
fn into_output(self) -> Self::Output {
SingleBuilder(self.0)
}
fn max_definite(&self) -> Option<u64> {
self.0.max_definite
}
fn set_max_definite(&mut self, max: Option<u64>) {
self.0.set_max_definite(max);
}
}
pub struct SingleBuilder<'a, 'b>(&'b mut ArrayWriter<'a>);
pub struct SingleResult {
ph: PhantomData<u8>,
}
impl<'a, 'b> Writer for SingleBuilder<'a, 'b> {
type Output = SingleResult;
fn bytes<T>(&mut self, f: impl FnOnce(&mut Vec<u8>) -> T) -> T {
self.0.bytes(f)
}
fn into_output(self) -> Self::Output {
SingleResult { ph: PhantomData }
}
fn max_definite(&self) -> Option<u64> {
self.0.max_definite
}
fn set_max_definite(&mut self, max: Option<u64>) {
self.0.set_max_definite(max);
}
}