jsony 0.1.10

An experimental fast compiling serialization and deserialization library for JSON like formats.
Documentation
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
use std::alloc::{Layout, alloc, dealloc, handle_alloc_error, realloc};
use std::borrow::Cow;
use std::fmt;
use std::marker::PhantomData;
use std::mem::{ManuallyDrop, MaybeUninit};
use std::ptr::{self, NonNull};

/// An optimized output buffer with dynamic backing storage.
///
/// Similar to `dyn std::io::Write`, `BytesWriter` can be backed by various types including:
/// - `Vec<u8>`
/// - `&mut [MaybeUninit<u8>]`
/// - `dyn std::io::Write`
///
/// The implementation minimizes dynamic dispatch by restricting it to out-of-capacity situations
/// where the underlying buffer needs to be resized or flushed.  ///
/// `BytesWriter` guarantees to maintain a buffer, and when backing storage is already viable,
/// that backing will be used directly. Operations like `push` are guaranteed not to flush to
/// the backing store, meaning pushed bytes remain available and can be popped and discarded.
/// Note that `push_bytes` does not provide this same guarantee.
///
/// See [`crate::TextWriter`] for a UTF-8-specific version that guarantees valid UTF-8 content.
#[repr(C)]
pub struct BytesWriter<'a> {
    data: *mut u8,
    len: usize,
    capacity: usize,
    backing: Backing<'a>,
}

impl Default for BytesWriter<'_> {
    /// A empty BytesWriter backed by an owned buffer.
    fn default() -> Self {
        Self::new()
    }
}

impl<'a> From<&'a mut [MaybeUninit<u8>]> for BytesWriter<'a> {
    fn from(value: &'a mut [MaybeUninit<u8>]) -> Self {
        BytesWriter {
            capacity: value.len(),
            data: value.as_mut_ptr().cast(),
            len: 0,
            backing: Backing::Borrowed {
                marker: PhantomData,
            },
        }
    }
}

impl<'a> From<&'a mut Vec<u8>> for BytesWriter<'a> {
    fn from(value: &'a mut Vec<u8>) -> Self {
        BytesWriter {
            data: value.as_mut_ptr(),
            len: value.len(),
            capacity: value.capacity(),
            backing: Backing::Vec {
                bytes: NonNull::from(value),
                offset: 0,
                marker: PhantomData,
            },
        }
    }
}

impl Drop for BytesWriter<'_> {
    fn drop(&mut self) {
        match self.backing {
            Backing::Owned | Backing::Write { .. } => {
                // SAFETY: for these backing variants, a non-zero `capacity`
                // means `data` was allocated by this type with the global
                // allocator and alignment 1. A zero-capacity writer uses a
                // dangling pointer and has no allocation to free.
                unsafe {
                    if self.capacity != 0 {
                        let layout = Layout::from_size_align_unchecked(self.capacity, 1);
                        dealloc(self.data, layout);
                    }
                }
            }
            Backing::Vec {
                mut bytes, offset, ..
            } => {
                // SAFETY: this writer was created from an exclusive `&mut Vec<u8>`
                // and keeps that borrow for `'a`. The Vec owns the allocation,
                // and `offset..offset + len` is initialized by the writer.
                unsafe {
                    let vec = bytes.as_mut();
                    vec.set_len(offset + self.len);
                }
            }
            Backing::Borrowed { .. } => (),
        }
    }
}

pub(crate) enum Backing<'a> {
    Owned,
    Vec {
        bytes: NonNull<Vec<u8>>,
        offset: usize,
        // Life time as Vec<u8>... we store it as pointer
        // to avoid issues aliasing issues. Although it should be fine.
        marker: PhantomData<&'a ()>,
    },
    Borrowed {
        marker: PhantomData<&'a ()>,
    },
    Write {
        written: usize,
        error: Option<std::io::Error>,
        writer: &'a mut (dyn std::io::Write + Send),
    },
}

impl<'a> BytesWriter<'a> {
    /// Creates a new `BytesWriter` backed by the provided writer.
    pub fn new_writer(writer: &'a mut (dyn std::io::Write + Send)) -> BytesWriter<'a> {
        BytesWriter {
            data: safe_alloc(4096),
            len: 0,
            capacity: 4096,
            backing: Backing::Write {
                written: 0,
                error: None,
                writer,
            },
        }
    }

    pub(crate) fn from_vec_suffix(value: &'a mut Vec<u8>) -> Self {
        let offset = value.len();
        BytesWriter {
            // SAFETY: `offset == len <= capacity`, so this is either in-bounds
            // or one-past the Vec allocation. A zero-capacity Vec uses a
            // non-null dangling pointer and `add(0)`.
            data: unsafe { value.as_mut_ptr().add(offset) },
            len: 0,
            capacity: value.capacity() - offset,
            backing: Backing::Vec {
                bytes: NonNull::from(value),
                offset,
                marker: PhantomData,
            },
        }
    }

    /// Returns a mutable reference to the last two bytes, if available.
    pub fn last_2(&mut self) -> Option<&mut [u8; 2]> {
        if self.len < 2 {
            return None;
        }
        // SAFETY: `len >= 2`, `0..len` is initialized by the writer invariant,
        // and `&mut self` gives exclusive access to these bytes.
        Some(unsafe { &mut *self.data.add(self.len - 2).cast() })
    }
    /// Returns a mutable reference to the last byte, if available.
    pub fn last(&mut self) -> Option<&mut u8> {
        if self.len == 0 {
            return None;
        }
        // SAFETY: `len > 0`, `0..len` is initialized by the writer invariant,
        // and `&mut self` gives exclusive access to this byte.
        Some(unsafe { &mut *self.data.add(self.len - 1) })
    }
    /// Clears the buffer, setting its length to zero.
    pub fn clear(&mut self) {
        self.len = 0;
    }
    /// Returns true if the buffer is empty.
    pub fn is_empty(&self) -> bool {
        self.len == 0
    }

    /// Sets the length of the buffer.
    ///
    /// # Safety
    /// - `new_len` must not exceed the buffer's capacity
    /// - All elements in the range `old_len..new_len` must be initialized
    pub unsafe fn set_len(&mut self, new_len: usize) {
        self.len = new_len;
    }

    /// Decrements the length by 1, or does nothing if the buffer is empty.
    pub fn saturting_pop(&mut self) {
        self.len = self.len.saturating_sub(1);
    }

    /// Creates a new empty `BytesWriter`, that will be backed by a owned buffer.
    #[inline]
    pub fn new() -> BytesWriter<'a> {
        BytesWriter {
            data: NonNull::<u8>::dangling().as_ptr(),
            len: 0,
            capacity: 0,
            backing: Backing::Owned,
        }
    }

    /// Creates a new `BytesWriter` with the specified capacity.
    ///
    /// The writer will be backed by an owned buffer with at least the specified capacity.
    pub fn with_capacity(capacity: usize) -> BytesWriter<'a> {
        let data = safe_alloc(capacity);
        BytesWriter {
            data,
            len: 0,
            capacity,
            backing: Backing::Owned,
        }
    }

    /// Returns a reference to the current contents as a byte slice.
    ///
    /// Note that any write operation except `push` may flush this buffer to the backing store.
    pub fn buffer_slice(&self) -> &[u8] {
        // SAFETY: the writer invariant maintains `len <= capacity` and
        // initializes all bytes in `0..len`. For `len == 0`, `data` may be a
        // dangling but non-null aligned pointer, which is allowed for slices.
        unsafe { std::slice::from_raw_parts(self.data, self.len) }
    }

    /// Converts the writer into a `Vec<u8>`, consuming the writer.
    pub fn into_vec(self) -> Vec<u8> {
        let this = ManuallyDrop::new(self);
        match this.backing {
            Backing::Vec {
                mut bytes, offset, ..
            } => {
                // SAFETY: this writer has exclusive access to the borrowed Vec.
                // The initialized logical buffer ends at `offset + this.len`,
                // so restoring that length preserves its allocation invariants.
                unsafe {
                    let vec = bytes.as_mut();
                    vec.set_len(offset + this.len);
                    std::mem::take(vec)
                }
            }
            Backing::Borrowed { .. } => this.buffer_slice().into(),
            Backing::Write { .. } | Backing::Owned => {
                // SAFETY: owned/write buffers are allocated by this type with the
                // global allocator and alignment 1; for capacity 0 the dangling
                // pointer is valid for an empty Vec. `ManuallyDrop` prevents the
                // writer from freeing the allocation after transferring it.
                unsafe { Vec::from_raw_parts(this.data, this.len, this.capacity) }
            }
        }
    }

    /// Consumes the writer and returns the owned buffer as a `Vec<u8>`.
    ///
    /// ### Errors
    /// Panics if the writer is not backed by an owned buffer (e.g., when using a borrowed slice or writer).
    pub fn owned_into_vec(self) -> Vec<u8> {
        let mut this = ManuallyDrop::new(self);
        if let Backing::Owned = this.backing {
            // SAFETY: an owned buffer is allocated by this type with the global
            // allocator and alignment 1; for capacity 0 the dangling pointer is
            // valid for an empty Vec. `ManuallyDrop` prevents a double free.
            unsafe { Vec::from_raw_parts(this.data, this.len, this.capacity) }
        } else {
            // SAFETY: `this` has not been dropped yet, and this branch does not
            // move out any raw allocation owned by it.
            unsafe { ManuallyDrop::drop(&mut this) };
            panic!("Expected write buffer to backed by an owned allocation");
        }
    }

    /// Consumes the writer and returns a reference to the backing slice with
    /// content added since the creation of ByteWriter.
    ///
    /// ### Errors
    /// Panics if the writer is not backed by a `Vec<u8>`.
    pub fn into_backed_with_extended_slice(self) -> &'a [u8] {
        let mut this = ManuallyDrop::new(self);
        let len = this.len;
        if let Backing::Vec { bytes, offset, .. } = &mut this.backing {
            // SAFETY: the writer has exclusive access to the backing Vec. The
            // logical initialized bytes end at `offset + len`, so restoring the
            // Vec length is valid. The previous Vec length is the creation-time
            // suffix boundary.
            let (data, start, suffix_len) = unsafe {
                let bytes = bytes.as_mut();
                let oldlen = bytes.len();
                let end = *offset + len;
                bytes.set_len(end);
                let start = oldlen.min(end);
                (bytes.as_mut_ptr(), start, end - start)
            };
            // SAFETY: `start <= end`, and the backing Vec now owns these
            // initialized bytes for lifetime `'a`. A zero-length suffix may use
            // a one-past or dangling aligned pointer.
            return unsafe { std::slice::from_raw_parts(data.add(start), suffix_len) };
        }
        // SAFETY: `this` has not been dropped yet, and no allocation was moved
        // out on this error path.
        unsafe { ManuallyDrop::drop(&mut this) };
        panic!("Expected write buffer to backed by a Vec<u8>");
    }

    /// Converts the writer into a `Cow<str>`.
    ///
    /// # Safety
    /// The buffer must contain valid UTF-8 data
    pub unsafe fn into_cow_utf8_unchecked(self) -> Cow<'a, str> {
        let mut this = ManuallyDrop::new(self);
        let data = this.data;
        let len = this.len;
        let capacity = this.capacity;
        match &this.backing {
            // SAFETY: the caller guarantees the initialized bytes are UTF-8.
            // The Vec raw parts belong to this writer and are transferred under
            // `ManuallyDrop`.
            Backing::Owned => Cow::Owned(unsafe {
                String::from_utf8_unchecked(Vec::from_raw_parts(data, len, capacity))
            }),
            // SAFETY: the caller guarantees the initialized bytes are UTF-8,
            // and borrowed backing storage outlives `'a`.
            Backing::Borrowed { .. } => Cow::Borrowed(unsafe {
                std::str::from_utf8_unchecked(std::slice::from_raw_parts(data, len))
            }),
            _ => {
                // SAFETY: `this` has not been dropped yet, and no allocation was
                // moved out on this error path.
                unsafe { ManuallyDrop::drop(&mut this) };
                panic!("Expected Borrowed or owneded Instance");
            }
        }
    }
    /// Converts the writer into a `Cow<[u8]>`.
    ///
    /// # Panics
    /// Panics if the writer is not backed by an owned buffer (e.g., when using a borrowed slice or writer).
    pub fn into_cow(self) -> Cow<'a, [u8]> {
        let mut this = ManuallyDrop::new(self);
        let data = this.data;
        let len = this.len;
        let capacity = this.capacity;
        match &this.backing {
            // SAFETY: the raw parts belong to this writer and are transferred
            // under `ManuallyDrop`; `0..len` is initialized.
            Backing::Owned => Cow::Owned(unsafe { Vec::from_raw_parts(data, len, capacity) }),
            Backing::Borrowed { .. } => {
                // SAFETY: borrowed backing storage outlives `'a`, and `0..len`
                // is initialized by the writer invariant.
                Cow::Borrowed(unsafe { std::slice::from_raw_parts(data, len) })
            }
            _ => {
                // SAFETY: `this` has not been dropped yet, and no allocation was
                // moved out on this error path.
                unsafe { ManuallyDrop::drop(&mut this) };
                panic!("Expected Borrowed or owneded Instance");
            }
        }
    }

    /// Completes the write operation and returns the total number of bytes written.
    ///
    /// ### Errors
    /// Returns an error if writing to the underlying writer fails.
    pub fn into_write_finish(mut self) -> Result<usize, std::io::Error> {
        self.flush();
        match &mut self.backing {
            Backing::Write { written, error, .. } => {
                if let Some(error) = error.take() {
                    return Err(error);
                }
                Ok(*written)
            }
            _ => {
                panic!("Expected Write Instance");
            }
        }
    }

    /// Returns a mutable pointer to the buffer's internal data.
    #[inline]
    pub fn as_mut_ptr(&self) -> *mut u8 {
        self.data
    }

    /// Returns the length of this buffer in bytes
    #[inline]
    pub fn len(&self) -> usize {
        self.len
    }

    /// Returns this buffer's capacity in bytes
    #[inline]
    pub fn capacity(&self) -> usize {
        self.capacity
    }

    /// Increase the length of buffer by `additional` bytes
    ///
    /// # Safety
    ///
    /// - `additional` must be less than or equal to `capacity() - len()`
    /// - The elements at `old_len..old_len + additional` must be initialized
    #[inline]
    pub unsafe fn advance(&mut self, additional: usize) {
        self.len += additional;
    }

    //  /// Same as String::reserve
    //  ///
    //  /// # Panics
    //  ///
    //  /// This method panics if `size` overflows `isize::MAX`.
    //  #[inline]
    //  pub fn reserve(&mut self, size: usize) {
    //      if size <= self.capacity - self.len {
    //          return;
    //      }
    //      self.reserve_internal(size);
    //  }

    /// Same as String::reserve except that undefined behaviour can result if `size`
    /// overflows `isize::MAX`.
    #[inline]
    pub(crate) unsafe fn reserve_small(&mut self, size: usize) {
        debug_assert!(size <= isize::MAX as usize);
        if self.len + size <= self.capacity {
            return;
        }
        self.reserve_internal(size, true);
    }

    /// Appends the raw byte view of T.
    ///
    /// # Safety
    ///
    /// The caller must ensure that `data` is plain old data for this binary
    /// representation: every byte in `T`, including padding, must be
    /// initialized and valid to copy as output.
    pub unsafe fn push_as_bytes<T>(&mut self, data: &T) {
        // SAFETY: the caller guarantees that every byte in `data` is
        // initialized and may be observed as raw output bytes. The reference is
        // valid for `size_of::<T>()` bytes by construction.
        self.push_bytes(unsafe {
            ::std::slice::from_raw_parts(data as *const T as *const u8, ::std::mem::size_of::<T>())
        });
    }

    /// Appends the given bytes to the end of this buffer.
    ///
    /// Note: may flush the buffer to the underlying IO. If flushing results in
    /// error it will be stored in the writer and returned by `into_write_finish`.
    #[inline]
    pub fn push_bytes(&mut self, data: &[u8]) {
        let size = data.len();

        // SAFETY: `reserve_small(size)` ensures `len + size <= capacity`.
        // Slices cannot exceed the maximum object size, satisfying
        // `reserve_small`'s size precondition. The source slice cannot overlap
        // this writer's mutable destination through safe code because `&mut self`
        // is held for the duration of the call.
        unsafe {
            self.reserve_small(size);

            let p = self.data.add(self.len);
            std::ptr::copy_nonoverlapping(data.as_ptr(), p, size);
            self.len += size;
        }
        debug_assert!(self.len <= self.capacity);
    }

    /// Appends the given `byte` to the end of this buffer, guaranteed not
    /// to flush the buffer to the underlying IO.
    #[inline]
    pub fn push(&mut self, byte: u8) {
        // Inform codegen that the length does not change across reserve_internal with grou false.
        let len = self.len;

        // This will panic or abort if we would allocate > isize::MAX bytes
        // or if the length increment would overflow for zero-sized types.
        if len == self.capacity {
            self.reserve_internal(1, false);
        }

        // SAFETY: after the reserve above, `len < capacity`. The destination
        // byte is within the allocation and `&mut self` provides exclusive
        // access to it.
        unsafe {
            *self.data.add(len) = byte;
            self.len = len + 1;
        }
    }
    /// Appends the given `char` to the end of this buffer
    #[inline]
    pub fn push_char(&mut self, data: char) {
        // SAFETY: `reserve_small(4)` is valid because a char encodes to at most
        // four bytes and then guarantees enough spare capacity for the copy.
        unsafe {
            self.reserve_small(4);
            let mut buffer = [0u8; 4];
            let result = data.encode_utf8(&mut buffer);
            let result = result.as_bytes();
            std::ptr::copy_nonoverlapping(result.as_ptr(), self.data.add(self.len), result.len());
            self.len += result.len();
        }
    }

    /// If the backing store is writer, clear the internal buffer writing contents
    /// to backing writer.
    ///
    /// If not backed by writer this `flush` is a no-op.
    fn flush(&mut self) {
        if let Backing::Write {
            written,
            error,
            writer,
        } = &mut self.backing
        {
            use std::io::Write;
            // SAFETY: `0..len` is initialized by the writer invariant.
            let buffered = unsafe { std::slice::from_raw_parts(self.data, self.len) };
            if let Err(err) = writer.write_all(buffered) {
                *error = Some(err);
            }
            *written += self.len;
            self.len = 0;
        }
    }

    #[cold]
    fn reserve_internal(&mut self, size: usize, can_write: bool) {
        debug_assert!(size <= isize::MAX as usize);
        if let Backing::Write {
            written,
            error,
            writer,
        } = &mut self.backing
        {
            if can_write {
                use std::io::Write;
                // SAFETY: `0..len` is initialized by the writer invariant.
                let buffered = unsafe { std::slice::from_raw_parts(self.data, self.len) };
                if let Err(err) = writer.write_all(buffered) {
                    *error = Some(err);
                    return;
                }
                *written += self.len;
                self.len = 0;
                if self.capacity >= size {
                    return;
                }
            }
        }

        let new_capacity = std::cmp::max(self.capacity * 2, self.capacity + size);
        debug_assert!(new_capacity > self.capacity);
        if let Backing::Borrowed { .. } = &self.backing {
            let new_data = safe_alloc(new_capacity);
            // SAFETY: `new_data` points to a fresh allocation of at least
            // `new_capacity`, `self.data` has at least `self.len` initialized
            // bytes, and fresh allocations cannot overlap borrowed storage.
            unsafe {
                ptr::copy_nonoverlapping(self.data, new_data, self.len);
            }
            self.backing = Backing::Owned;
            self.data = new_data;
        } else if let Backing::Vec { bytes, offset, .. } = &mut self.backing {
            let old_capacity = *offset + self.capacity;
            let new_total_capacity = *offset + new_capacity;
            // SAFETY: the writer has exclusive access to the Vec. Its pointer
            // and capacity are the allocation raw parts, and `old_capacity` is
            // the total allocation capacity represented by this suffix view.
            let data = unsafe {
                let vec = bytes.as_mut();
                let original_len = vec.len();
                let data = safe_realloc(vec.as_mut_ptr(), old_capacity, new_total_capacity);
                bytes.write(Vec::from_raw_parts(data, original_len, new_total_capacity));
                data
            };
            // SAFETY: `offset <= new_total_capacity`, so this is in-bounds or
            // one-past the reallocated Vec allocation.
            self.data = unsafe { data.add(*offset) };
            self.capacity = new_capacity;
            return;
        } else {
            // SAFETY: for non-borrowed backing, `data`/`capacity` either
            // represent no allocation (`capacity == 0`) or an allocation made
            // with the global allocator and alignment 1.
            self.data = unsafe { safe_realloc(self.data, self.capacity, new_capacity) };
        }
        self.capacity = new_capacity;

        debug_assert!(!self.data.is_null());
        debug_assert!(self.len <= self.capacity);
    }
}

#[inline(never)]
fn safe_alloc(capacity: usize) -> *mut u8 {
    assert!(capacity > 0);
    assert!(capacity <= isize::MAX as usize, "capacity is too large");

    // SAFETY: capacity is non-zero, and always multiple of alignment (1).
    unsafe {
        let layout = Layout::from_size_align_unchecked(capacity, 1);
        let data = alloc(layout);
        if data.is_null() {
            handle_alloc_error(layout);
        }

        data
    }
}

/// # Safety
///
/// - if `capacity > 0`, `capacity` is the same value that was used to allocate the block
///   of memory pointed by `ptr`.
#[cold]
#[inline(never)]
unsafe fn safe_realloc(ptr: *mut u8, capacity: usize, new_capacity: usize) -> *mut u8 {
    assert!(new_capacity > 0);
    assert!(new_capacity <= isize::MAX as usize, "capacity is too large");

    // SAFETY: both layouts use alignment 1 and non-zero sizes bounded by
    // `isize::MAX`; when `capacity > 0`, the function safety contract says
    // `ptr` was allocated with exactly that old layout.
    let data = if capacity == 0 {
        // SAFETY: `new_capacity` is non-zero and bounded above; alignment 1 is
        // valid for byte storage.
        unsafe {
            let new_layout = Layout::from_size_align_unchecked(new_capacity, 1);
            alloc(new_layout)
        }
    } else {
        // SAFETY: the function contract says `ptr` was allocated with
        // `capacity` bytes and alignment 1; `new_capacity` is non-zero and
        // bounded above.
        unsafe {
            let old_layout = Layout::from_size_align_unchecked(capacity, 1);
            realloc(ptr, old_layout, new_capacity)
        }
    };

    if data.is_null() {
        // SAFETY: `new_capacity > 0`, alignment 1 is valid, and the size was
        // checked against `isize::MAX` above.
        unsafe {
            handle_alloc_error(Layout::from_size_align_unchecked(new_capacity, 1));
        }
    }

    data
}

impl fmt::Write for BytesWriter<'_> {
    #[inline]
    fn write_str(&mut self, s: &str) -> fmt::Result {
        BytesWriter::push_bytes(self, s.as_bytes());
        Ok(())
    }
}

// SAFETY: moving a writer to another thread preserves the unique borrow carried
// by its lifetime. All mutation of the raw buffer requires `&mut BytesWriter`,
// and shared methods only expose initialized bytes or raw pointers.
unsafe impl Send for BytesWriter<'_> {}
// SAFETY: shared access does not mutate the buffer or backing writer. Methods
// that can change `data`, `len`, `capacity`, or backing state require `&mut self`
// or ownership of the writer.
unsafe impl Sync for BytesWriter<'_> {}

/// Conversion into a `ByteWriter` with content extraction.
///
/// This is primaryily used in [crate::to_binary_into].
pub trait IntoByteWriter<'a> {
    type Output;

    /// Convert Self into TextWriter, preserving the contents.
    fn into_byte_writer(self) -> BytesWriter<'a>;

    /// Should return Output corresponding to added context since the
    /// creation from `into_text_writer()`.
    ///
    /// If `finish_writing` is called on an instance of TextWriter
    /// not create via `IntoTextWriter::into_text_writer` of the same type then this
    /// method may panic.
    fn finish_writing(buffer: BytesWriter<'a>) -> Self::Output;
}

impl<'a> IntoByteWriter<'a> for &'a mut Vec<u8> {
    type Output = &'a [u8];
    fn into_byte_writer(self) -> BytesWriter<'a> {
        BytesWriter::from(self)
    }
    fn finish_writing(buffer: BytesWriter<'a>) -> &'a [u8] {
        buffer.into_backed_with_extended_slice()
    }
}

pub type DynWrite<'a> = &'a mut (dyn std::io::Write + Send);
impl<'a> IntoByteWriter<'a> for DynWrite<'a> {
    type Output = Result<usize, std::io::Error>;
    fn into_byte_writer(self) -> BytesWriter<'a> {
        BytesWriter::new_writer(self)
    }
    fn finish_writing(buffer: BytesWriter<'a>) -> Result<usize, std::io::Error> {
        buffer.into_write_finish()
    }
}

impl<'a> IntoByteWriter<'a> for &'a mut [MaybeUninit<u8>] {
    type Output = Cow<'a, [u8]>;
    fn into_byte_writer(self) -> BytesWriter<'a> {
        BytesWriter::from(self)
    }
    fn finish_writing(buffer: BytesWriter<'a>) -> Cow<'a, [u8]> {
        buffer.into_cow()
    }
}