1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
use super::low_level::Bytes;
use crate::Writer;
use std::marker::PhantomData;
/// Builder for an array value, used by `write_array_ret()`.
///
/// see [`trait Encoder`](trait.Encoder.html) for usage examples
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,
}
}
/// Configure the limit above which indefinite size encoding will be used.
///
/// The default is 255, which is the largest size up to which definite size is at least as
/// compact as indefinite size. Set to 23 to avoid moving bytes around when finishing the array.
/// Set to `None` to always use indefinite size encoding.
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;
}
}
/// Builder for a dict value, used by `write_dict_rec()`.
///
/// see [`trait Encoder`](trait.Encoder.html) for usage examples
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
}
/// Configure the limit above which indefinite size encoding will be used.
///
/// The default is 255, which is the largest size up to which definite size is at least as
/// compact as indefinite size. Set to 23 to avoid moving bytes around when finishing the array.
/// Set to `None` to always use indefinite size encoding.
pub fn set_max_definite_size(&mut self, size: Option<u64>) {
self.0.max_definite = size;
}
/// Add one key–value pair to the dict.
///
/// ```
/// # use cbor_data::{CborBuilder, Writer, Encoder};
/// let cbor = CborBuilder::new().encode_dict(|builder| {
/// builder.with_key("the answer", |b| b.encode_u64(42));
/// });
/// ```
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)
}
}
/// Builder for the first step of [`try_write_pair`](struct.DictWriter.html#method.try_write_pair)
///
/// This builder can be used for exactly one item (which may be a complex one, like an array)
/// and returns a [`SingleBuilder`](struct.SingleBuilder.html) that needs to be used to write
/// the value for this dictionary entry.
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);
}
}
/// Builder for the single value of a dict key.
///
/// This builder can be used for exactly one item (which may be a complex one, like an array)
/// and returns a [`SingleResult`](struct.SingleResult.html) to prove to its
/// [`DictWriter`](struct.DictWriter.html) that it has been used.
pub struct SingleBuilder<'a, 'b>(&'b mut ArrayWriter<'a>);
/// Result value of using a [`SingleBuilder`](struct.SingleBuilder.html) proving that it has been used.
///
/// This value needs to be returned to [`DictWriter.with_key()`](struct.DictWriter.html#method.with_key).
/// You can only obtain it by using the `SingleBuilder`.
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);
}
}