• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vigna / dsi-bitstream-rs / 18369738690

09 Oct 2025 08:06AM UTC coverage: 44.586% (-0.5%) from 45.049%
18369738690

push

github

zommiommy
no_std and no_alloc works

31 of 87 new or added lines in 6 files covered. (35.63%)

1 existing line in 1 file now uncovered.

1606 of 3602 relevant lines covered (44.59%)

2037939.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

22.76
/src/dispatch/codes.rs
1
/*
2
 * SPDX-FileCopyrightText: 2025 Tommaso Fontana
3
 * SPDX-FileCopyrightText: 2025 Inria
4
 * SPDX-FileCopyrightText: 2025 Sebastiano Vigna
5
 *
6
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
7
 */
8

9
//! Enumeration of all available codes, with associated read and write methods.
10
//!
11
//! This is the slower and more generic form of dispatching, mostly used for
12
//! testing and writing examples. For faster dispatching, consider using
13
//! [dynamic] or [static] dispatch.
14

15
use super::*;
16
#[cfg(feature = "mem_dbg")]
17
use mem_dbg::{MemDbg, MemSize};
18

19
#[derive(Debug, Clone, Copy, Eq)]
20
#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
21
#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
22
#[non_exhaustive]
23
/// An enum whose variants represent all the available codes.
24
///
25
/// This enum is kept in sync with implementations in the
26
/// [`codes`](crate::codes) module.
27
///
28
/// Both [`Display`](std::fmt::Display) and [`FromStr`](std::str::FromStr) are
29
/// implemented for this enum in a dual way, which makes it possible to store a
30
/// code as a string in a configuration file, and then parse it back.
31
pub enum Codes {
32
    Unary,
33
    Gamma,
34
    Delta,
35
    Omega,
36
    VByteLe,
37
    VByteBe,
38
    Zeta { k: usize },
39
    Pi { k: usize },
40
    Golomb { b: u64 },
41
    ExpGolomb { k: usize },
42
    Rice { log2_b: usize },
43
}
44

45
/// Some codes are equivalent, so we implement [`PartialEq`] to make them
46
/// interchangeable so `Codes::Unary == Codes::Rice{log2_b: 0}`.
47
impl PartialEq for Codes {
48
    fn eq(&self, other: &Self) -> bool {
×
49
        match (self, other) {
×
50
            // First we check the equivalence classes
51
            (
52
                Self::Unary | Self::Rice { log2_b: 0 } | Self::Golomb { b: 1 },
53
                Self::Unary | Self::Rice { log2_b: 0 } | Self::Golomb { b: 1 },
54
            ) => true,
×
55
            (
56
                Self::Gamma | Self::Zeta { k: 1 } | Self::ExpGolomb { k: 0 },
57
                Self::Gamma | Self::Zeta { k: 1 } | Self::ExpGolomb { k: 0 },
58
            ) => true,
×
59
            (
60
                Self::Golomb { b: 2 } | Self::Rice { log2_b: 1 },
61
                Self::Golomb { b: 2 } | Self::Rice { log2_b: 1 },
62
            ) => true,
×
63
            (
64
                Self::Golomb { b: 4 } | Self::Rice { log2_b: 2 },
65
                Self::Golomb { b: 4 } | Self::Rice { log2_b: 2 },
66
            ) => true,
×
67
            (
68
                Self::Golomb { b: 8 } | Self::Rice { log2_b: 3 },
69
                Self::Golomb { b: 8 } | Self::Rice { log2_b: 3 },
70
            ) => true,
×
71
            // we know that we are not in a special case, so we can directly
72
            // compare them naively
73
            (Self::Delta, Self::Delta) => true,
×
74
            (Self::Omega, Self::Omega) => true,
×
75
            (Self::VByteLe, Self::VByteLe) => true,
×
76
            (Self::VByteBe, Self::VByteBe) => true,
×
77
            (Self::Zeta { k }, Self::Zeta { k: k2 }) => k == k2,
×
78
            (Self::Pi { k }, Self::Pi { k: k2 }) => k == k2,
×
79
            (Self::Golomb { b }, Self::Golomb { b: b2 }) => b == b2,
×
80
            (Self::ExpGolomb { k }, Self::ExpGolomb { k: k2 }) => k == k2,
×
81
            (Self::Rice { log2_b }, Self::Rice { log2_b: log2_b2 }) => log2_b == log2_b2,
×
82
            _ => false,
×
83
        }
84
    }
85
}
86

87
impl Codes {
88
    /// Delegate to the [`DynamicCodeRead`] implementation.
89
    ///
90
    /// This inherent method is provided to reduce ambiguity in method
91
    /// resolution.
92
    #[inline(always)]
93
    pub fn read<E: Endianness, CR: CodesRead<E> + ?Sized>(
×
94
        &self,
95
        reader: &mut CR,
96
    ) -> Result<u64, CR::Error> {
97
        DynamicCodeRead::read(self, reader)
×
98
    }
99

100
    /// Delegate to the [`DynamicCodeWrite`] implementation.
101
    ///
102
    /// This inherent method is provided to reduce ambiguity in method
103
    /// resolution.
104
    #[inline(always)]
105
    pub fn write<E: Endianness, CW: CodesWrite<E> + ?Sized>(
×
106
        &self,
107
        writer: &mut CW,
108
        value: u64,
109
    ) -> Result<usize, CW::Error> {
110
        DynamicCodeWrite::write(self, writer, value)
×
111
    }
112

113
    /// Convert a code to the constant enum [`code_consts`] used for [`ConstCode`].
114
    /// This is mostly used to verify that the code is supported by
115
    /// [`ConstCode`].
116
    pub fn to_code_const(&self) -> Result<usize> {
×
117
        Ok(match self {
×
118
            Self::Unary => code_consts::UNARY,
×
119
            Self::Gamma => code_consts::GAMMA,
×
120
            Self::Delta => code_consts::DELTA,
×
121
            Self::Omega => code_consts::OMEGA,
×
122
            Self::VByteLe => code_consts::VBYTE_LE,
×
123
            Self::VByteBe => code_consts::VBYTE_BE,
×
124
            Self::Zeta { k: 1 } => code_consts::ZETA1,
×
125
            Self::Zeta { k: 2 } => code_consts::ZETA2,
×
126
            Self::Zeta { k: 3 } => code_consts::ZETA3,
×
127
            Self::Zeta { k: 4 } => code_consts::ZETA4,
×
128
            Self::Zeta { k: 5 } => code_consts::ZETA5,
×
129
            Self::Zeta { k: 6 } => code_consts::ZETA6,
×
130
            Self::Zeta { k: 7 } => code_consts::ZETA7,
×
131
            Self::Zeta { k: 8 } => code_consts::ZETA8,
×
132
            Self::Zeta { k: 9 } => code_consts::ZETA9,
×
133
            Self::Zeta { k: 10 } => code_consts::ZETA10,
×
134
            Self::Rice { log2_b: 0 } => code_consts::RICE0,
×
135
            Self::Rice { log2_b: 1 } => code_consts::RICE1,
×
136
            Self::Rice { log2_b: 2 } => code_consts::RICE2,
×
137
            Self::Rice { log2_b: 3 } => code_consts::RICE3,
×
138
            Self::Rice { log2_b: 4 } => code_consts::RICE4,
×
139
            Self::Rice { log2_b: 5 } => code_consts::RICE5,
×
140
            Self::Rice { log2_b: 6 } => code_consts::RICE6,
×
141
            Self::Rice { log2_b: 7 } => code_consts::RICE7,
×
142
            Self::Rice { log2_b: 8 } => code_consts::RICE8,
×
143
            Self::Rice { log2_b: 9 } => code_consts::RICE9,
×
144
            Self::Rice { log2_b: 10 } => code_consts::RICE10,
×
145
            Self::Pi { k: 0 } => code_consts::PI0,
×
146
            Self::Pi { k: 1 } => code_consts::PI1,
×
147
            Self::Pi { k: 2 } => code_consts::PI2,
×
148
            Self::Pi { k: 3 } => code_consts::PI3,
×
149
            Self::Pi { k: 4 } => code_consts::PI4,
×
150
            Self::Pi { k: 5 } => code_consts::PI5,
×
151
            Self::Pi { k: 6 } => code_consts::PI6,
×
152
            Self::Pi { k: 7 } => code_consts::PI7,
×
153
            Self::Pi { k: 8 } => code_consts::PI8,
×
154
            Self::Pi { k: 9 } => code_consts::PI9,
×
155
            Self::Pi { k: 10 } => code_consts::PI10,
×
156
            Self::Golomb { b: 1 } => code_consts::GOLOMB1,
×
157
            Self::Golomb { b: 2 } => code_consts::GOLOMB2,
×
158
            Self::Golomb { b: 3 } => code_consts::GOLOMB3,
×
159
            Self::Golomb { b: 4 } => code_consts::GOLOMB4,
×
160
            Self::Golomb { b: 5 } => code_consts::GOLOMB5,
×
161
            Self::Golomb { b: 6 } => code_consts::GOLOMB6,
×
162
            Self::Golomb { b: 7 } => code_consts::GOLOMB7,
×
163
            Self::Golomb { b: 8 } => code_consts::GOLOMB8,
×
164
            Self::Golomb { b: 9 } => code_consts::GOLOMB9,
×
165
            Self::Golomb { b: 10 } => code_consts::GOLOMB10,
×
166
            Self::ExpGolomb { k: 0 } => code_consts::EXP_GOLOMB0,
×
167
            Self::ExpGolomb { k: 1 } => code_consts::EXP_GOLOMB1,
×
168
            Self::ExpGolomb { k: 2 } => code_consts::EXP_GOLOMB2,
×
169
            Self::ExpGolomb { k: 3 } => code_consts::EXP_GOLOMB3,
×
170
            Self::ExpGolomb { k: 4 } => code_consts::EXP_GOLOMB4,
×
171
            Self::ExpGolomb { k: 5 } => code_consts::EXP_GOLOMB5,
×
172
            Self::ExpGolomb { k: 6 } => code_consts::EXP_GOLOMB6,
×
173
            Self::ExpGolomb { k: 7 } => code_consts::EXP_GOLOMB7,
×
174
            Self::ExpGolomb { k: 8 } => code_consts::EXP_GOLOMB8,
×
175
            Self::ExpGolomb { k: 9 } => code_consts::EXP_GOLOMB9,
×
176
            Self::ExpGolomb { k: 10 } => code_consts::EXP_GOLOMB10,
×
177
            _ => {
178
                return Err(anyhow::anyhow!(
×
179
                    "Code {:?} not supported as const code",
×
180
                    self
×
181
                ))
182
            }
183
        })
184
    }
185

186
    /// Convert a value from [`code_consts`] to a code.
187
    pub fn from_code_const(const_code: usize) -> Result<Self> {
×
188
        Ok(match const_code {
×
189
            code_consts::UNARY => Self::Unary,
×
190
            code_consts::GAMMA => Self::Gamma,
×
191
            code_consts::DELTA => Self::Delta,
×
192
            code_consts::OMEGA => Self::Omega,
×
193
            code_consts::VBYTE_LE => Self::VByteLe,
×
194
            code_consts::VBYTE_BE => Self::VByteBe,
×
195
            code_consts::ZETA2 => Self::Zeta { k: 2 },
×
196
            code_consts::ZETA3 => Self::Zeta { k: 3 },
×
197
            code_consts::ZETA4 => Self::Zeta { k: 4 },
×
198
            code_consts::ZETA5 => Self::Zeta { k: 5 },
×
199
            code_consts::ZETA6 => Self::Zeta { k: 6 },
×
200
            code_consts::ZETA7 => Self::Zeta { k: 7 },
×
201
            code_consts::ZETA8 => Self::Zeta { k: 8 },
×
202
            code_consts::ZETA9 => Self::Zeta { k: 9 },
×
203
            code_consts::ZETA10 => Self::Zeta { k: 10 },
×
204
            code_consts::RICE1 => Self::Rice { log2_b: 1 },
×
205
            code_consts::RICE2 => Self::Rice { log2_b: 2 },
×
206
            code_consts::RICE3 => Self::Rice { log2_b: 3 },
×
207
            code_consts::RICE4 => Self::Rice { log2_b: 4 },
×
208
            code_consts::RICE5 => Self::Rice { log2_b: 5 },
×
209
            code_consts::RICE6 => Self::Rice { log2_b: 6 },
×
210
            code_consts::RICE7 => Self::Rice { log2_b: 7 },
×
211
            code_consts::RICE8 => Self::Rice { log2_b: 8 },
×
212
            code_consts::RICE9 => Self::Rice { log2_b: 9 },
×
213
            code_consts::RICE10 => Self::Rice { log2_b: 10 },
×
214
            code_consts::PI1 => Self::Pi { k: 1 },
×
215
            code_consts::PI2 => Self::Pi { k: 2 },
×
216
            code_consts::PI3 => Self::Pi { k: 3 },
×
217
            code_consts::PI4 => Self::Pi { k: 4 },
×
218
            code_consts::PI5 => Self::Pi { k: 5 },
×
219
            code_consts::PI6 => Self::Pi { k: 6 },
×
220
            code_consts::PI7 => Self::Pi { k: 7 },
×
221
            code_consts::PI8 => Self::Pi { k: 8 },
×
222
            code_consts::PI9 => Self::Pi { k: 9 },
×
223
            code_consts::PI10 => Self::Pi { k: 10 },
×
224
            code_consts::GOLOMB3 => Self::Golomb { b: 3 },
×
225
            code_consts::GOLOMB5 => Self::Golomb { b: 5 },
×
226
            code_consts::GOLOMB6 => Self::Golomb { b: 6 },
×
227
            code_consts::GOLOMB7 => Self::Golomb { b: 7 },
×
228
            code_consts::GOLOMB9 => Self::Golomb { b: 9 },
×
229
            code_consts::GOLOMB10 => Self::Golomb { b: 10 },
×
230
            code_consts::EXP_GOLOMB1 => Self::ExpGolomb { k: 1 },
×
231
            code_consts::EXP_GOLOMB2 => Self::ExpGolomb { k: 2 },
×
232
            code_consts::EXP_GOLOMB3 => Self::ExpGolomb { k: 3 },
×
233
            code_consts::EXP_GOLOMB4 => Self::ExpGolomb { k: 4 },
×
234
            code_consts::EXP_GOLOMB5 => Self::ExpGolomb { k: 5 },
×
235
            code_consts::EXP_GOLOMB6 => Self::ExpGolomb { k: 6 },
×
236
            code_consts::EXP_GOLOMB7 => Self::ExpGolomb { k: 7 },
×
237
            code_consts::EXP_GOLOMB8 => Self::ExpGolomb { k: 8 },
×
238
            code_consts::EXP_GOLOMB9 => Self::ExpGolomb { k: 9 },
×
239
            code_consts::EXP_GOLOMB10 => Self::ExpGolomb { k: 10 },
×
240
            _ => return Err(anyhow::anyhow!("Code {} not supported", const_code)),
×
241
        })
242
    }
243
}
244

245
impl DynamicCodeRead for Codes {
246
    #[inline]
247
    fn read<E: Endianness, CR: CodesRead<E> + ?Sized>(
230,064✔
248
        &self,
249
        reader: &mut CR,
250
    ) -> Result<u64, CR::Error> {
251
        Ok(match self {
230,064✔
252
            Codes::Unary => reader.read_unary()?,
4,096✔
253
            Codes::Gamma => reader.read_gamma()?,
8,712✔
254
            Codes::Delta => reader.read_delta()?,
8,712✔
255
            Codes::Omega => reader.read_omega()?,
8,712✔
256
            Codes::VByteBe => reader.read_vbyte_be()?,
8,720✔
257
            Codes::VByteLe => reader.read_vbyte_le()?,
8,720✔
258
            Codes::Zeta { k: 3 } => reader.read_zeta3()?,
4,356✔
259
            Codes::Zeta { k } => reader.read_zeta(*k)?,
139,392✔
260
            Codes::Pi { k } => reader.read_pi(*k)?,
174,240✔
261
            Codes::Golomb { b } => reader.read_golomb(*b)?,
147,504✔
262
            Codes::ExpGolomb { k } => reader.read_exp_golomb(*k)?,
174,272✔
263
            Codes::Rice { log2_b } => reader.read_rice(*log2_b)?,
163,888✔
264
        })
265
    }
266
}
267

268
impl DynamicCodeWrite for Codes {
269
    #[inline]
270
    fn write<E: Endianness, CW: CodesWrite<E> + ?Sized>(
230,064✔
271
        &self,
272
        writer: &mut CW,
273
        value: u64,
274
    ) -> Result<usize, CW::Error> {
275
        Ok(match self {
230,064✔
276
            Codes::Unary => writer.write_unary(value)?,
4,096✔
277
            Codes::Gamma => writer.write_gamma(value)?,
13,068✔
278
            Codes::Delta => writer.write_delta(value)?,
13,068✔
279
            Codes::Omega => writer.write_omega(value)?,
13,068✔
280
            Codes::VByteBe => writer.write_vbyte_be(value)?,
13,080✔
281
            Codes::VByteLe => writer.write_vbyte_le(value)?,
13,080✔
282
            Codes::Zeta { k: 1 } => writer.write_gamma(value)?,
4,356✔
283
            Codes::Zeta { k: 3 } => writer.write_zeta3(value)?,
13,068✔
284
            Codes::Zeta { k } => writer.write_zeta(value, *k)?,
152,460✔
285
            Codes::Pi { k } => writer.write_pi(value, *k)?,
217,800✔
286
            Codes::Golomb { b } => writer.write_golomb(value, *b)?,
184,380✔
287
            Codes::ExpGolomb { k } => writer.write_exp_golomb(value, *k)?,
217,840✔
288
            Codes::Rice { log2_b } => writer.write_rice(value, *log2_b)?,
204,860✔
289
        })
290
    }
291
}
292

293
impl<E: Endianness, CR: CodesRead<E> + ?Sized> StaticCodeRead<E, CR> for Codes {
294
    #[inline(always)]
295
    fn read(&self, reader: &mut CR) -> Result<u64, CR::Error> {
115,032✔
296
        <Self as DynamicCodeRead>::read(self, reader)
345,096✔
297
    }
298
}
299

300
impl<E: Endianness, CW: CodesWrite<E> + ?Sized> StaticCodeWrite<E, CW> for Codes {
301
    #[inline(always)]
302
    fn write(&self, writer: &mut CW, value: u64) -> Result<usize, CW::Error> {
115,032✔
303
        <Self as DynamicCodeWrite>::write(self, writer, value)
460,128✔
304
    }
305
}
306

307
impl CodeLen for Codes {
308
    #[inline]
309
    fn len(&self, value: u64) -> usize {
230,064✔
310
        match self {
230,064✔
311
            Codes::Unary => value as usize + 1,
4,096✔
312
            Codes::Gamma => len_gamma(value),
8,712✔
313
            Codes::Delta => len_delta(value),
8,712✔
314
            Codes::Omega => len_omega(value),
8,712✔
315
            Codes::VByteLe | Codes::VByteBe => bit_len_vbyte(value),
17,440✔
316
            Codes::Zeta { k: 1 } => len_gamma(value),
4,356✔
317
            Codes::Zeta { k } => len_zeta(value, *k),
139,392✔
318
            Codes::Pi { k } => len_pi(value, *k),
174,240✔
319
            Codes::Golomb { b } => len_golomb(value, *b),
147,504✔
320
            Codes::ExpGolomb { k } => len_exp_golomb(value, *k),
174,272✔
321
            Codes::Rice { log2_b } => len_rice(value, *log2_b),
163,888✔
322
        }
323
    }
324
}
325

326
#[derive(Debug)]
327
/// Error type for parsing a code from a string.
328
pub enum CodeError {
329
    ParseError(core::num::ParseIntError),
330
    UnknownCode([u8; 32]),
331
}
332
#[cfg(feature = "std")]
333
impl std::error::Error for CodeError {}
334
impl core::fmt::Display for CodeError {
335
    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
×
336
        match self {
×
337
            CodeError::ParseError(e) => write!(f, "Parse error: {}", e),
×
NEW
338
            CodeError::UnknownCode(s) => {
×
NEW
339
                write!(f, "Unknown code: ")?;
×
NEW
340
                for c in s {
×
NEW
341
                    if *c == 0 {
×
NEW
342
                        break;
×
343
                    }
NEW
344
                    write!(f, "{}", *c as char)?;
×
345
                }
NEW
346
                Ok(())
×
347
            }
348
        }
349
    }
350
}
351

352
impl From<core::num::ParseIntError> for CodeError {
353
    fn from(e: core::num::ParseIntError) -> Self {
×
354
        CodeError::ParseError(e)
×
355
    }
356
}
357

358
impl core::fmt::Display for Codes {
359
    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
×
360
        match self {
×
361
            Codes::Unary => write!(f, "Unary"),
×
362
            Codes::Gamma => write!(f, "Gamma"),
×
363
            Codes::Delta => write!(f, "Delta"),
×
364
            Codes::Omega => write!(f, "Omega"),
×
365
            Codes::VByteBe => write!(f, "VByteBe"),
×
366
            Codes::VByteLe => write!(f, "VByteLe"),
×
367
            Codes::Zeta { k } => write!(f, "Zeta({})", k),
×
368
            Codes::Pi { k } => write!(f, "Pi({})", k),
×
369
            Codes::Golomb { b } => write!(f, "Golomb({})", b),
×
370
            Codes::ExpGolomb { k } => write!(f, "ExpGolomb({})", k),
×
371
            Codes::Rice { log2_b } => write!(f, "Rice({})", log2_b),
×
372
        }
373
    }
374
}
375

NEW
376
fn array_format_error(s: &str) -> [u8; 32] {
×
NEW
377
    let mut error_buffer = [0u8; 32];
×
378
    const ERROR_PREFIX: &[u8] = b"Could not parse ";
NEW
379
    error_buffer[..ERROR_PREFIX.len()].copy_from_slice(ERROR_PREFIX);
×
NEW
380
    error_buffer[ERROR_PREFIX.len()..ERROR_PREFIX.len() + s.len().min(32 - ERROR_PREFIX.len())]
×
NEW
381
        .copy_from_slice(&s.as_bytes()[..s.len().min(32 - ERROR_PREFIX.len())]);
×
NEW
382
    error_buffer
×
383
}
384

385
impl core::str::FromStr for Codes {
386
    type Err = CodeError;
387

388
    fn from_str(s: &str) -> Result<Self, Self::Err> {
×
389
        match s {
×
390
            "Unary" => Ok(Codes::Unary),
×
391
            "Gamma" => Ok(Codes::Gamma),
×
392
            "Delta" => Ok(Codes::Delta),
×
393
            "Omega" => Ok(Codes::Omega),
×
394
            "VByteBe" => Ok(Codes::VByteBe),
×
395

396
            _ => {
397
                let mut parts = s.split('(');
×
398
                let name = parts
×
399
                    .next()
NEW
400
                    .ok_or_else(|| CodeError::UnknownCode(array_format_error(s)))?;
×
401
                let k = parts
×
402
                    .next()
NEW
403
                    .ok_or_else(|| CodeError::UnknownCode(array_format_error(s)))?
×
404
                    .split(')')
405
                    .next()
NEW
406
                    .ok_or_else(|| CodeError::UnknownCode(array_format_error(s)))?;
×
407
                match name {
×
408
                    "Zeta" => Ok(Codes::Zeta { k: k.parse()? }),
×
409
                    "Pi" => Ok(Codes::Pi { k: k.parse()? }),
×
410
                    "Golomb" => Ok(Codes::Golomb { b: k.parse()? }),
×
411
                    "ExpGolomb" => Ok(Codes::ExpGolomb { k: k.parse()? }),
×
412
                    "Rice" => Ok(Codes::Rice { log2_b: k.parse()? }),
×
NEW
413
                    _ => Err(CodeError::UnknownCode(array_format_error(name))),
×
414
                }
415
            }
416
        }
417
    }
418
}
419

420
/// Structure representing minimal binary coding with a fixed length.
421
///
422
/// [Minimal binary coding](crate::codes::minimal_binary) does not
423
/// fit the [`Codes`] enum because it is not defined for all integers.
424
///
425
/// Instances of this structure can be used in context in which a
426
/// [`DynamicCodeRead`], [`DynamicCodeWrite`], [`StaticCodeRead`],
427
/// [`StaticCodeWrite`] or [`CodeLen`] implementing minimal binary coding
428
/// is necessary.
429
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
430
pub struct MinimalBinary(pub u64);
431

432
impl DynamicCodeRead for MinimalBinary {
433
    fn read<E: Endianness, R: CodesRead<E> + ?Sized>(
48✔
434
        &self,
435
        reader: &mut R,
436
    ) -> Result<u64, R::Error> {
437
        reader.read_minimal_binary(self.0)
144✔
438
    }
439
}
440

441
impl DynamicCodeWrite for MinimalBinary {
442
    fn write<E: Endianness, W: CodesWrite<E> + ?Sized>(
48✔
443
        &self,
444
        writer: &mut W,
445
        n: u64,
446
    ) -> Result<usize, W::Error> {
447
        writer.write_minimal_binary(n, self.0)
192✔
448
    }
449
}
450

451
impl<E: Endianness, CR: CodesRead<E> + ?Sized> StaticCodeRead<E, CR> for MinimalBinary {
452
    fn read(&self, reader: &mut CR) -> Result<u64, CR::Error> {
24✔
453
        <Self as DynamicCodeRead>::read(self, reader)
72✔
454
    }
455
}
456

457
impl<E: Endianness, CW: CodesWrite<E> + ?Sized> StaticCodeWrite<E, CW> for MinimalBinary {
458
    fn write(&self, writer: &mut CW, n: u64) -> Result<usize, CW::Error> {
24✔
459
        <Self as DynamicCodeWrite>::write(self, writer, n)
96✔
460
    }
461
}
462

463
impl CodeLen for MinimalBinary {
464
    fn len(&self, n: u64) -> usize {
48✔
465
        len_minimal_binary(n, self.0)
144✔
466
    }
467
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc