Skip to main content

qubit_io/codecs/
zig_zag_writer.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::io::{
11    Result,
12    Seek,
13    SeekFrom,
14    Write,
15};
16
17use crate::ZigZagWriteExt;
18
19/// Writer wrapper for ZigZag encoded signed integers.
20///
21/// # Examples
22/// ```
23/// use qubit_io::ZigZagWriter;
24///
25/// let mut output = ZigZagWriter::new(Vec::new());
26/// output.write_i32(-1)?;
27///
28/// assert_eq!(vec![0x01], output.into_inner());
29/// # Ok::<(), std::io::Error>(())
30/// ```
31pub struct ZigZagWriter<W> {
32    inner: W,
33}
34
35impl<W> ZigZagWriter<W> {
36    /// Creates a ZigZag writer.
37    ///
38    /// # Parameters
39    /// - `inner`: Writer to wrap.
40    ///
41    /// # Returns
42    /// A new ZigZag writer.
43    #[inline]
44    pub fn new(inner: W) -> Self {
45        Self { inner }
46    }
47
48    /// Returns an immutable reference to the wrapped writer.
49    ///
50    /// # Returns
51    /// The wrapped writer reference.
52    #[inline]
53    pub fn get_ref(&self) -> &W {
54        &self.inner
55    }
56
57    /// Returns a mutable reference to the wrapped writer.
58    ///
59    /// # Returns
60    /// The wrapped writer reference.
61    #[inline]
62    pub fn get_mut(&mut self) -> &mut W {
63        &mut self.inner
64    }
65
66    /// Consumes this wrapper and returns the wrapped writer.
67    ///
68    /// # Returns
69    /// The wrapped writer.
70    #[inline]
71    pub fn into_inner(self) -> W {
72        self.inner
73    }
74}
75
76macro_rules! delegate_write {
77    ($name:ident, $inner:ident, $value:ty) => {
78        #[doc = concat!("Writes a ZigZag encoded `", stringify!($value), "`.")]
79        ///
80        /// # Parameters
81        /// - `value`: Value to encode.
82        ///
83        /// # Errors
84        /// Returns an I/O error from the wrapped writer.
85        #[inline]
86        pub fn $name(&mut self, value: $value) -> Result<()> {
87            self.inner.$inner(value)
88        }
89    };
90}
91
92impl<W> ZigZagWriter<W>
93where
94    W: Write,
95{
96    delegate_write!(write_i8, write_zigzag_i8, i8);
97    delegate_write!(write_i16, write_zigzag_i16, i16);
98    delegate_write!(write_i32, write_zigzag_i32, i32);
99    delegate_write!(write_i64, write_zigzag_i64, i64);
100    delegate_write!(write_i128, write_zigzag_i128, i128);
101    delegate_write!(write_isize, write_zigzag_isize, isize);
102}
103
104impl<W> Write for ZigZagWriter<W>
105where
106    W: Write,
107{
108    #[inline]
109    fn write(&mut self, buffer: &[u8]) -> Result<usize> {
110        self.inner.write(buffer)
111    }
112
113    #[inline]
114    fn flush(&mut self) -> Result<()> {
115        self.inner.flush()
116    }
117}
118
119impl<W> Seek for ZigZagWriter<W>
120where
121    W: Seek,
122{
123    #[inline]
124    fn seek(&mut self, position: SeekFrom) -> Result<u64> {
125        self.inner.seek(position)
126    }
127}