Skip to main content

sacp_cbor/
encode.rs

1use crate::alloc_util::try_reserve;
2use crate::canonical::{CanonicalCbor, CanonicalCborRef, EncodedTextKey};
3use crate::codec::CborEncode;
4use crate::profile::{check_encoded_key_order, validate_bignum_bytes, validate_int_safe_i64};
5use crate::query::CborValueRef;
6use crate::scalar::F64Bits;
7use crate::{CborError, ErrorCode};
8use alloc::vec::Vec;
9
10trait Sink {
11    fn write(&mut self, bytes: &[u8]) -> Result<(), CborError>;
12
13    fn write_u8(&mut self, byte: u8) -> Result<(), CborError> {
14        self.write(&[byte])
15    }
16
17    fn position(&self) -> usize;
18}
19
20struct VecSink {
21    buf: Vec<u8>,
22}
23
24impl VecSink {
25    const fn new() -> Self {
26        Self { buf: Vec::new() }
27    }
28
29    fn with_capacity(capacity: usize) -> Self {
30        let mut buf = Vec::new();
31        let _ = buf.try_reserve(capacity);
32        Self { buf }
33    }
34
35    fn into_vec(self) -> Vec<u8> {
36        self.buf
37    }
38
39    #[inline]
40    fn reserve(&mut self, additional: usize) -> Result<(), CborError> {
41        let available = self.buf.capacity().saturating_sub(self.buf.len());
42        if additional <= available {
43            return Ok(());
44        }
45        let offset = self.buf.len();
46        try_reserve(&mut self.buf, additional, offset)
47    }
48}
49
50impl Sink for VecSink {
51    fn write(&mut self, bytes: &[u8]) -> Result<(), CborError> {
52        self.reserve(bytes.len())?;
53        self.buf.extend_from_slice(bytes);
54        Ok(())
55    }
56
57    fn write_u8(&mut self, byte: u8) -> Result<(), CborError> {
58        if self.buf.len() == self.buf.capacity() {
59            self.reserve(1)?;
60        }
61        self.buf.push(byte);
62        Ok(())
63    }
64
65    fn position(&self) -> usize {
66        self.buf.len()
67    }
68}
69
70fn err_at<S: Sink>(sink: &S, code: ErrorCode) -> CborError {
71    CborError::new(code, sink.position())
72}
73
74fn encode_int<S: Sink>(sink: &mut S, v: i64) -> Result<(), CborError> {
75    if v >= 0 {
76        let u = u64::try_from(v).map_err(|_| err_at(sink, ErrorCode::LengthOverflow))?;
77        encode_major_uint(sink, 0, u)
78    } else {
79        let n_i128 = -1_i128 - i128::from(v);
80        let n_u64 = u64::try_from(n_i128).map_err(|_| err_at(sink, ErrorCode::LengthOverflow))?;
81        encode_major_uint(sink, 1, n_u64)
82    }
83}
84
85fn encode_bytes<S: Sink>(sink: &mut S, bytes: &[u8]) -> Result<(), CborError> {
86    encode_major_len(sink, 2, bytes.len())?;
87    sink.write(bytes)
88}
89
90fn encode_text<S: Sink>(sink: &mut S, s: &str) -> Result<(), CborError> {
91    // `str` guarantees valid UTF-8.
92    let b = s.as_bytes();
93    encode_major_len(sink, 3, b.len())?;
94    sink.write(b)
95}
96
97fn encode_float64<S: Sink>(sink: &mut S, bits: F64Bits) -> Result<(), CborError> {
98    let raw = bits.bits();
99    let mut buf = [0u8; 9];
100    buf[0] = 0xfb;
101    buf[1..9].copy_from_slice(&raw.to_be_bytes());
102    sink.write(&buf)
103}
104
105fn encode_major_len<S: Sink>(sink: &mut S, major: u8, len: usize) -> Result<(), CborError> {
106    let len_u64 = u64::try_from(len).map_err(|_| err_at(sink, ErrorCode::LengthOverflow))?;
107    encode_major_uint(sink, major, len_u64)
108}
109
110fn encode_major_uint<S: Sink>(sink: &mut S, major: u8, value: u64) -> Result<(), CborError> {
111    debug_assert!(major <= 7);
112    if value < 24 {
113        let v = u8::try_from(value).unwrap();
114        return sink.write_u8((major << 5) | v);
115    }
116    if value <= 0xff {
117        let v = u8::try_from(value).unwrap();
118        sink.write_u8((major << 5) | 0x18)?;
119        return sink.write_u8(v);
120    }
121    if value <= 0xffff {
122        let v = u16::try_from(value).unwrap();
123        sink.write_u8((major << 5) | 0x19)?;
124        return sink.write(&v.to_be_bytes());
125    }
126    if value <= 0xffff_ffff {
127        let v = u32::try_from(value).unwrap();
128        sink.write_u8((major << 5) | 0x1a)?;
129        return sink.write(&v.to_be_bytes());
130    }
131    sink.write_u8((major << 5) | 0x1b)?;
132    sink.write(&value.to_be_bytes())
133}
134
135/// Streaming encoder that writes canonical CBOR directly into a `Vec<u8>`.
136///
137/// This supports splicing validated canonical bytes.
138pub struct Encoder {
139    sink: VecSink,
140    depth: usize,
141    root_done: bool,
142    root_end: usize,
143}
144
145impl Encoder {
146    /// Create a new canonical encoder.
147    #[must_use]
148    pub const fn new() -> Self {
149        Self {
150            sink: VecSink::new(),
151            depth: 0,
152            root_done: false,
153            root_end: 0,
154        }
155    }
156
157    /// Create a canonical encoder with pre-allocated capacity.
158    #[must_use]
159    pub fn with_capacity(capacity: usize) -> Self {
160        Self {
161            sink: VecSink::with_capacity(capacity),
162            depth: 0,
163            root_done: false,
164            root_end: 0,
165        }
166    }
167
168    /// Return the number of bytes written so far.
169    #[must_use]
170    pub fn len(&self) -> usize {
171        self.sink.buf.len()
172    }
173
174    /// Returns `true` if no bytes have been written.
175    #[must_use]
176    pub fn is_empty(&self) -> bool {
177        self.sink.buf.is_empty()
178    }
179
180    /// Consume and return the encoded bytes.
181    #[must_use]
182    pub fn into_vec(self) -> Vec<u8> {
183        self.sink.into_vec()
184    }
185
186    /// Consume and return canonical bytes as a `CanonicalCbor`.
187    ///
188    /// # Errors
189    ///
190    /// Returns an error if the buffer does not contain exactly one canonical CBOR item.
191    pub fn into_canonical(self) -> Result<CanonicalCbor, CborError> {
192        if self.depth != 0 {
193            return Err(CborError::new(
194                ErrorCode::UnexpectedEof,
195                self.sink.position(),
196            ));
197        }
198        if !self.root_done {
199            return Err(CborError::new(ErrorCode::UnexpectedEof, 0));
200        }
201        Ok(CanonicalCbor::new_unchecked(self.into_vec()))
202    }
203
204    /// Clear the encoder while retaining allocated capacity.
205    pub fn clear(&mut self) {
206        self.sink.buf.clear();
207        self.depth = 0;
208        self.root_done = false;
209        self.root_end = 0;
210    }
211
212    /// Borrow the bytes emitted so far.
213    #[must_use]
214    pub fn as_bytes(&self) -> &[u8] {
215        &self.sink.buf
216    }
217
218    #[inline]
219    const fn begin_value(&self) -> Result<bool, CborError> {
220        if self.depth == 0 {
221            if self.root_done {
222                return Err(CborError::new(ErrorCode::TrailingBytes, self.root_end));
223            }
224            Ok(true)
225        } else {
226            Ok(false)
227        }
228    }
229
230    #[inline]
231    fn finish_value(&mut self, root: bool) {
232        if root {
233            self.root_done = true;
234            self.root_end = self.sink.position();
235        }
236    }
237
238    #[inline]
239    fn enter_container(&mut self) {
240        self.depth = self.depth.saturating_add(1);
241    }
242
243    #[inline]
244    fn exit_container(&mut self) {
245        debug_assert!(self.depth > 0);
246        self.depth = self.depth.saturating_sub(1);
247    }
248
249    #[cfg(feature = "serde")]
250    #[inline]
251    pub(crate) const fn in_container(&self) -> bool {
252        self.depth != 0
253    }
254
255    #[cfg(feature = "serde")]
256    #[inline]
257    pub(crate) fn finish_container(&mut self, root: bool) {
258        self.exit_container();
259        self.finish_value(root);
260    }
261
262    #[cfg(feature = "serde")]
263    #[inline]
264    pub(crate) fn abort_container(&mut self) {
265        self.exit_container();
266    }
267
268    #[inline]
269    pub(crate) fn emit_null(&mut self) -> Result<(), CborError> {
270        self.sink.write_u8(0xf6)
271    }
272
273    #[inline]
274    pub(crate) fn emit_bool(&mut self, v: bool) -> Result<(), CborError> {
275        self.sink.write_u8(if v { 0xf5 } else { 0xf4 })
276    }
277
278    #[inline]
279    pub(crate) fn emit_int(&mut self, v: i64) -> Result<(), CborError> {
280        validate_int_safe_i64(v).map_err(|code| CborError::new(code, self.sink.position()))?;
281        encode_int(&mut self.sink, v)
282    }
283
284    #[cfg(feature = "serde")]
285    #[inline]
286    pub(crate) fn emit_int_u128(&mut self, v: u128) -> Result<(), CborError> {
287        let safe_max = u128::from(crate::profile::MAX_SAFE_INTEGER);
288        if v <= safe_max {
289            let i = i64::try_from(v)
290                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?;
291            return self.emit_int(i);
292        }
293
294        let magnitude = crate::int::magnitude_from_u128(v)
295            .map_err(|code| CborError::new(code, self.sink.position()))?;
296        self.emit_bignum(false, &magnitude)
297    }
298
299    #[cfg(feature = "serde")]
300    #[inline]
301    pub(crate) fn emit_int_i128(&mut self, v: i128) -> Result<(), CborError> {
302        let min = i128::from(crate::profile::MIN_SAFE_INTEGER);
303        let max = i128::from(crate::profile::MAX_SAFE_INTEGER_I64);
304
305        if v >= min && v <= max {
306            let i = i64::try_from(v)
307                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?;
308            return self.emit_int(i);
309        }
310
311        let negative = v < 0;
312        let n_u128 = if negative {
313            let n_i128 = -1_i128 - v;
314            u128::try_from(n_i128)
315                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?
316        } else {
317            u128::try_from(v)
318                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?
319        };
320
321        let magnitude = crate::int::magnitude_from_u128(n_u128)
322            .map_err(|code| CborError::new(code, self.sink.position()))?;
323        self.emit_bignum(negative, &magnitude)
324    }
325
326    #[inline]
327    pub(crate) fn emit_bignum(
328        &mut self,
329        negative: bool,
330        magnitude: &[u8],
331    ) -> Result<(), CborError> {
332        validate_bignum_bytes(negative, magnitude)
333            .map_err(|code| CborError::new(code, self.sink.position()))?;
334        let tag = if negative { 3u64 } else { 2u64 };
335        encode_major_uint(&mut self.sink, 6, tag)?;
336        encode_bytes(&mut self.sink, magnitude)
337    }
338
339    #[inline]
340    pub(crate) fn emit_bytes(&mut self, b: &[u8]) -> Result<(), CborError> {
341        encode_bytes(&mut self.sink, b)
342    }
343
344    #[inline]
345    pub(crate) fn emit_text(&mut self, s: &str) -> Result<(), CborError> {
346        encode_text(&mut self.sink, s)
347    }
348
349    #[inline]
350    pub(crate) fn emit_float(&mut self, bits: F64Bits) -> Result<(), CborError> {
351        encode_float64(&mut self.sink, bits)
352    }
353
354    #[inline]
355    pub(crate) fn emit_raw_cbor(&mut self, v: CanonicalCborRef<'_>) -> Result<(), CborError> {
356        self.sink.write(v.as_bytes())
357    }
358
359    #[inline]
360    pub(crate) fn emit_raw_value_ref(&mut self, v: CborValueRef<'_>) -> Result<(), CborError> {
361        self.sink.write(v.as_bytes())
362    }
363
364    #[cfg(feature = "serde")]
365    #[inline]
366    pub(crate) fn emit_raw_bytes(&mut self, bytes: &[u8]) -> Result<(), CborError> {
367        self.sink.write(bytes)
368    }
369
370    #[cfg(feature = "serde")]
371    pub(crate) fn buf_len(&self) -> usize {
372        self.sink.buf.len()
373    }
374
375    #[cfg(feature = "serde")]
376    pub(crate) fn truncate(&mut self, len: usize) {
377        self.sink.buf.truncate(len);
378    }
379
380    /// Encode CBOR null.
381    ///
382    /// # Errors
383    ///
384    /// Returns an error if writing to the underlying buffer fails.
385    pub fn null(&mut self) -> Result<(), CborError> {
386        let root = self.begin_value()?;
387        self.emit_null()?;
388        self.finish_value(root);
389        Ok(())
390    }
391
392    /// Encode a CBOR boolean.
393    ///
394    /// # Errors
395    ///
396    /// Returns an error if writing to the underlying buffer fails.
397    pub fn bool(&mut self, v: bool) -> Result<(), CborError> {
398        let root = self.begin_value()?;
399        self.emit_bool(v)?;
400        self.finish_value(root);
401        Ok(())
402    }
403
404    /// Encode a safe-range integer.
405    ///
406    /// # Errors
407    ///
408    /// Returns an error if the integer is outside the safe range or if encoding fails.
409    pub fn int(&mut self, v: i64) -> Result<(), CborError> {
410        let root = self.begin_value()?;
411        self.emit_int(v)?;
412        self.finish_value(root);
413        Ok(())
414    }
415
416    /// Encode an unsigned integer, using a bignum when outside the safe range.
417    ///
418    /// # Errors
419    ///
420    /// Returns an error if encoding fails or allocation for the bignum magnitude fails.
421    pub fn int_u128(&mut self, v: u128) -> Result<(), CborError> {
422        let safe_max = u128::from(crate::profile::MAX_SAFE_INTEGER);
423        if v <= safe_max {
424            let i = i64::try_from(v)
425                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?;
426            return self.int(i);
427        }
428
429        let magnitude = crate::int::magnitude_from_u128(v)
430            .map_err(|code| CborError::new(code, self.sink.position()))?;
431        self.bignum(false, &magnitude)
432    }
433
434    /// Encode a signed integer, using a bignum when outside the safe range.
435    ///
436    /// # Errors
437    ///
438    /// Returns an error if encoding fails or allocation for the bignum magnitude fails.
439    pub fn int_i128(&mut self, v: i128) -> Result<(), CborError> {
440        let min = i128::from(crate::profile::MIN_SAFE_INTEGER);
441        let max = i128::from(crate::profile::MAX_SAFE_INTEGER_I64);
442
443        if v >= min && v <= max {
444            let i = i64::try_from(v)
445                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?;
446            return self.int(i);
447        }
448
449        let negative = v < 0;
450        let n_u128 = if negative {
451            let n_i128 = -1_i128 - v;
452            u128::try_from(n_i128)
453                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?
454        } else {
455            u128::try_from(v)
456                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?
457        };
458
459        let magnitude = crate::int::magnitude_from_u128(n_u128)
460            .map_err(|code| CborError::new(code, self.sink.position()))?;
461        self.bignum(negative, &magnitude)
462    }
463
464    /// Encode a CBOR bignum (tag 2/3 + byte string magnitude).
465    ///
466    /// # Errors
467    ///
468    /// Returns an error if the magnitude is not canonical or if encoding fails.
469    pub fn bignum(&mut self, negative: bool, magnitude: &[u8]) -> Result<(), CborError> {
470        let root = self.begin_value()?;
471        self.emit_bignum(negative, magnitude)?;
472        self.finish_value(root);
473        Ok(())
474    }
475
476    /// Encode a byte string.
477    ///
478    /// # Errors
479    ///
480    /// Returns an error if encoding fails.
481    pub fn bytes(&mut self, b: &[u8]) -> Result<(), CborError> {
482        let root = self.begin_value()?;
483        self.emit_bytes(b)?;
484        self.finish_value(root);
485        Ok(())
486    }
487
488    /// Encode a text string.
489    ///
490    /// # Errors
491    ///
492    /// Returns an error if encoding fails.
493    pub fn text(&mut self, s: &str) -> Result<(), CborError> {
494        let root = self.begin_value()?;
495        self.emit_text(s)?;
496        self.finish_value(root);
497        Ok(())
498    }
499
500    /// Encode a float64 bit pattern.
501    ///
502    /// # Errors
503    ///
504    /// Returns an error if encoding fails.
505    pub fn float(&mut self, bits: F64Bits) -> Result<(), CborError> {
506        let root = self.begin_value()?;
507        self.emit_float(bits)?;
508        self.finish_value(root);
509        Ok(())
510    }
511
512    /// Splice already validated canonical CBOR bytes as the next value.
513    ///
514    /// # Errors
515    ///
516    /// Returns an error if writing to the underlying buffer fails.
517    pub fn raw_cbor(&mut self, v: CanonicalCborRef<'_>) -> Result<(), CborError> {
518        let root = self.begin_value()?;
519        self.emit_raw_cbor(v)?;
520        self.finish_value(root);
521        Ok(())
522    }
523
524    /// Splice a canonical sub-value reference.
525    ///
526    /// # Errors
527    ///
528    /// Returns an error if writing to the underlying buffer fails.
529    pub fn raw_value_ref(&mut self, v: CborValueRef<'_>) -> Result<(), CborError> {
530        let root = self.begin_value()?;
531        self.emit_raw_value_ref(v)?;
532        self.finish_value(root);
533        Ok(())
534    }
535
536    /// Encode a definite-length array and fill it via the provided builder.
537    ///
538    /// # Errors
539    ///
540    /// Returns an error if encoding fails or if the builder emits a different number of items.
541    pub fn array<F>(&mut self, len: usize, f: F) -> Result<(), CborError>
542    where
543        F: FnOnce(&mut ArrayEncoder<'_>) -> Result<(), CborError>,
544    {
545        let root = self.begin_value()?;
546        let start = self.sink.buf.len();
547        if let Err(err) = encode_major_len(&mut self.sink, 4, len) {
548            self.sink.buf.truncate(start);
549            return Err(err);
550        }
551        if let Err(err) = self.reserve_min_array_items(len) {
552            self.sink.buf.truncate(start);
553            return Err(err);
554        }
555        self.enter_container();
556        let (res, remaining) = {
557            let mut a = ArrayEncoder {
558                enc: self,
559                remaining: len,
560            };
561            let res = f(&mut a);
562            (res, a.remaining)
563        };
564        self.exit_container();
565        if let Err(err) = res {
566            self.sink.buf.truncate(start);
567            return Err(err);
568        }
569        if remaining != 0 {
570            let err = CborError::new(ErrorCode::ArrayLenMismatch, self.sink.position());
571            self.sink.buf.truncate(start);
572            return Err(err);
573        }
574        self.finish_value(root);
575        Ok(())
576    }
577
578    #[cfg(feature = "serde")]
579    pub(crate) fn array_header(&mut self, len: usize) -> Result<bool, CborError> {
580        let root = self.begin_value()?;
581        encode_major_len(&mut self.sink, 4, len)?;
582        self.reserve_min_array_items(len)?;
583        self.enter_container();
584        Ok(root)
585    }
586
587    /// Encode a definite-length map and fill it via the provided builder.
588    ///
589    /// # Errors
590    ///
591    /// Returns an error if encoding fails or if the builder emits a different number of entries.
592    pub fn map<F>(&mut self, len: usize, f: F) -> Result<(), CborError>
593    where
594        F: FnOnce(&mut MapEncoder<'_>) -> Result<(), CborError>,
595    {
596        let root = self.begin_value()?;
597        let start = self.sink.buf.len();
598        if let Err(err) = encode_major_len(&mut self.sink, 5, len) {
599            self.sink.buf.truncate(start);
600            return Err(err);
601        }
602        if let Err(err) = self.reserve_min_map_items(len) {
603            self.sink.buf.truncate(start);
604            return Err(err);
605        }
606        self.enter_container();
607        let (res, remaining) = {
608            let mut m = MapEncoder {
609                enc: self,
610                remaining: len,
611                prev_key_range: None,
612            };
613            let res = f(&mut m);
614            (res, m.remaining)
615        };
616        self.exit_container();
617        if let Err(err) = res {
618            self.sink.buf.truncate(start);
619            return Err(err);
620        }
621        if remaining != 0 {
622            let err = CborError::new(ErrorCode::MapLenMismatch, self.sink.position());
623            self.sink.buf.truncate(start);
624            return Err(err);
625        }
626        self.finish_value(root);
627        Ok(())
628    }
629
630    #[cfg(feature = "serde")]
631    pub(crate) fn map_header(&mut self, len: usize) -> Result<bool, CborError> {
632        let root = self.begin_value()?;
633        encode_major_len(&mut self.sink, 5, len)?;
634        self.reserve_min_map_items(len)?;
635        self.enter_container();
636        Ok(root)
637    }
638
639    /// Internal hook used by `cbor_bytes!` for `$expr` values.
640    #[doc(hidden)]
641    #[allow(missing_docs)]
642    pub fn __encode_any<T>(&mut self, v: T) -> Result<(), CborError>
643    where
644        T: crate::__cbor_macro::IntoCborBytes,
645    {
646        crate::__cbor_macro::IntoCborBytes::into_cbor_bytes(v, self)
647    }
648
649    fn reserve_min_array_items(&mut self, len: usize) -> Result<(), CborError> {
650        if len == 0 {
651            return Ok(());
652        }
653        self.sink.reserve(len)
654    }
655
656    fn reserve_min_map_items(&mut self, len: usize) -> Result<(), CborError> {
657        if len == 0 {
658            return Ok(());
659        }
660        let items = len
661            .checked_mul(2)
662            .ok_or_else(|| CborError::new(ErrorCode::LengthOverflow, self.sink.position()))?;
663        self.sink.reserve(items)
664    }
665}
666
667impl Default for Encoder {
668    fn default() -> Self {
669        Self::new()
670    }
671}
672
673/// Builder for writing array elements into a canonical CBOR stream.
674pub struct ArrayEncoder<'a> {
675    enc: &'a mut Encoder,
676    remaining: usize,
677}
678
679#[allow(missing_docs)]
680impl ArrayEncoder<'_> {
681    fn consume_one(&mut self) -> Result<(), CborError> {
682        if self.remaining == 0 {
683            return Err(CborError::new(
684                ErrorCode::ArrayLenMismatch,
685                self.enc.sink.position(),
686            ));
687        }
688        self.remaining -= 1;
689        Ok(())
690    }
691
692    /// Encode CBOR null.
693    ///
694    /// # Errors
695    ///
696    /// Returns an error if the array length is exceeded or if encoding fails.
697    pub fn null(&mut self) -> Result<(), CborError> {
698        self.consume_one()?;
699        self.enc.emit_null()
700    }
701
702    /// Encode a CBOR boolean.
703    ///
704    /// # Errors
705    ///
706    /// Returns an error if the array length is exceeded or if encoding fails.
707    pub fn bool(&mut self, v: bool) -> Result<(), CborError> {
708        self.consume_one()?;
709        self.enc.emit_bool(v)
710    }
711
712    /// Encode a safe-range integer.
713    ///
714    /// # Errors
715    ///
716    /// Returns an error if the array length is exceeded or if encoding fails.
717    pub fn int(&mut self, v: i64) -> Result<(), CborError> {
718        self.consume_one()?;
719        self.enc.emit_int(v)
720    }
721
722    /// Encode a CBOR bignum (tag 2/3 + byte string magnitude).
723    ///
724    /// # Errors
725    ///
726    /// Returns an error if the array length is exceeded or if encoding fails.
727    pub fn bignum(&mut self, negative: bool, magnitude: &[u8]) -> Result<(), CborError> {
728        self.consume_one()?;
729        self.enc.emit_bignum(negative, magnitude)
730    }
731
732    /// Encode a byte string.
733    ///
734    /// # Errors
735    ///
736    /// Returns an error if the array length is exceeded or if encoding fails.
737    pub fn bytes(&mut self, b: &[u8]) -> Result<(), CborError> {
738        self.consume_one()?;
739        self.enc.emit_bytes(b)
740    }
741
742    /// Encode a text string.
743    ///
744    /// # Errors
745    ///
746    /// Returns an error if the array length is exceeded or if encoding fails.
747    pub fn text(&mut self, s: &str) -> Result<(), CborError> {
748        self.consume_one()?;
749        self.enc.emit_text(s)
750    }
751
752    /// Encode a float64 bit pattern.
753    ///
754    /// # Errors
755    ///
756    /// Returns an error if the array length is exceeded or if encoding fails.
757    pub fn float(&mut self, bits: F64Bits) -> Result<(), CborError> {
758        self.consume_one()?;
759        self.enc.emit_float(bits)
760    }
761
762    /// Splice canonical CBOR bytes as the next array element.
763    ///
764    /// # Errors
765    ///
766    /// Returns an error if the array length is exceeded or if encoding fails.
767    pub fn raw_cbor(&mut self, v: CanonicalCborRef<'_>) -> Result<(), CborError> {
768        self.consume_one()?;
769        self.enc.emit_raw_cbor(v)
770    }
771
772    /// Splice a canonical sub-value reference as the next array element.
773    ///
774    /// # Errors
775    ///
776    /// Returns an error if the array length is exceeded or if encoding fails.
777    pub fn raw_value_ref(&mut self, v: CborValueRef<'_>) -> Result<(), CborError> {
778        self.consume_one()?;
779        self.enc.emit_raw_value_ref(v)
780    }
781
782    /// Encode a value using the native `CborEncode` trait.
783    ///
784    /// # Errors
785    ///
786    /// Returns an error if the array length is exceeded or if encoding fails.
787    pub fn value<T: CborEncode>(&mut self, value: &T) -> Result<(), CborError> {
788        self.consume_one()?;
789        value.encode(self.enc)
790    }
791
792    /// Encode a nested array.
793    ///
794    /// # Errors
795    ///
796    /// Returns an error if the array length is exceeded or if encoding fails.
797    pub fn array<F>(&mut self, len: usize, f: F) -> Result<(), CborError>
798    where
799        F: FnOnce(&mut ArrayEncoder<'_>) -> Result<(), CborError>,
800    {
801        self.consume_one()?;
802        self.enc.array(len, f)
803    }
804
805    /// Encode a nested map.
806    ///
807    /// # Errors
808    ///
809    /// Returns an error if the array length is exceeded or if encoding fails.
810    pub fn map<F>(&mut self, len: usize, f: F) -> Result<(), CborError>
811    where
812        F: FnOnce(&mut MapEncoder<'_>) -> Result<(), CborError>,
813    {
814        self.consume_one()?;
815        self.enc.map(len, f)
816    }
817
818    #[doc(hidden)]
819    #[allow(missing_docs)]
820    pub fn __encode_any<T>(&mut self, v: T) -> Result<(), CborError>
821    where
822        T: crate::__cbor_macro::IntoCborBytes,
823    {
824        self.consume_one()?;
825        crate::__cbor_macro::IntoCborBytes::into_cbor_bytes(v, self.enc)
826    }
827}
828
829/// Builder for writing map entries into a canonical CBOR stream.
830pub struct MapEncoder<'a> {
831    enc: &'a mut Encoder,
832    remaining: usize,
833    prev_key_range: Option<(usize, usize)>,
834}
835
836#[allow(missing_docs)]
837impl MapEncoder<'_> {
838    fn write_entry<K, F>(&mut self, write_key: K, f: F) -> Result<(), CborError>
839    where
840        K: FnOnce(&mut VecSink) -> Result<(), CborError>,
841        F: FnOnce(&mut Encoder) -> Result<(), CborError>,
842    {
843        if self.remaining == 0 {
844            return Err(CborError::new(
845                ErrorCode::MapLenMismatch,
846                self.enc.sink.position(),
847            ));
848        }
849
850        let entry_start = self.enc.sink.buf.len();
851        let (key_start, key_end) = self.write_key(entry_start, write_key)?;
852        self.enforce_key_order(entry_start, key_start, key_end)?;
853        let res = f(self.enc);
854        self.finish_entry(entry_start, key_start, key_end, res)
855    }
856
857    fn enforce_key_order(
858        &mut self,
859        entry_start: usize,
860        key_start: usize,
861        key_end: usize,
862    ) -> Result<(), CborError> {
863        if let Some((ps, pe)) = self.prev_key_range {
864            let prev = &self.enc.sink.buf[ps..pe];
865            let curr = &self.enc.sink.buf[key_start..key_end];
866            if let Err(code) = check_encoded_key_order(prev, curr) {
867                return self.fail_entry(entry_start, CborError::new(code, key_start));
868            }
869        }
870        Ok(())
871    }
872
873    fn finish_entry(
874        &mut self,
875        entry_start: usize,
876        key_start: usize,
877        key_end: usize,
878        res: Result<(), CborError>,
879    ) -> Result<(), CborError> {
880        if let Err(err) = res {
881            return self.fail_entry(entry_start, err);
882        }
883        self.prev_key_range = Some((key_start, key_end));
884        self.remaining -= 1;
885        Ok(())
886    }
887
888    fn write_key<F>(&mut self, entry_start: usize, write: F) -> Result<(usize, usize), CborError>
889    where
890        F: FnOnce(&mut VecSink) -> Result<(), CborError>,
891    {
892        if let Err(err) = write(&mut self.enc.sink) {
893            return self.fail_entry(entry_start, err);
894        }
895        Ok((entry_start, self.enc.sink.buf.len()))
896    }
897
898    fn fail_entry<T>(&mut self, entry_start: usize, err: CborError) -> Result<T, CborError> {
899        self.enc.sink.buf.truncate(entry_start);
900        Err(err)
901    }
902
903    /// Insert a map entry. Keys must be in canonical order; duplicates are rejected.
904    ///
905    /// # Errors
906    ///
907    /// Returns an error if encoding fails, if keys are out of order, or if duplicates are found.
908    pub fn entry<F>(&mut self, key: &str, f: F) -> Result<(), CborError>
909    where
910        F: FnOnce(&mut Encoder) -> Result<(), CborError>,
911    {
912        self.write_entry(|sink| encode_text(sink, key), f)
913    }
914
915    /// Insert a map entry using a pre-encoded canonical text key.
916    ///
917    /// This avoids re-encoding keys when splicing from validated canonical bytes.
918    ///
919    /// # Errors
920    ///
921    /// Returns an error if encoding fails, if keys are out of order, or if duplicates are found.
922    pub fn entry_raw_key<F>(&mut self, key: EncodedTextKey<'_>, f: F) -> Result<(), CborError>
923    where
924        F: FnOnce(&mut Encoder) -> Result<(), CborError>,
925    {
926        let key_bytes = key.as_bytes();
927        self.write_entry(|sink| sink.write(key_bytes), f)
928    }
929}