byte_order/
write.rs

1use std::io::{Result, Write};
2
3use crate::order::ByteOrder;
4
5/// A `NumberWriter` wraps a [writer] and provides methods for writing numbers.
6///
7/// Unlike many libraries, which take byte order as a parameter per operation, a
8/// `NumberWriter` takes byte order as a parameter upon initialization.
9///
10/// # Examples
11///
12/// We can create a new `NumberWriter` using the target endianness using
13/// [`NumberWriter::new`]:
14///
15/// ```
16/// use byte_order::NumberWriter;
17///
18/// let mut writer = NumberWriter::new(vec![]);
19/// ```
20///
21/// Or, to write numbers with a certain endianness, we can create `NumberWriter`
22/// structures using [`NumberWriter::with_order`]:
23///
24/// ```
25/// use byte_order::{ByteOrder, NumberWriter};
26///
27/// let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
28/// let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
29/// let mut ne_writer = NumberWriter::with_order(ByteOrder::NE, vec![]);
30/// ```
31///
32/// To write numbers from the underlying [writer], use any of the `write_*`
33/// methods that are provided:
34///
35/// ```
36/// use std::io;
37/// use byte_order::{ByteOrder, NumberWriter};
38///
39/// fn main() -> io::Result<()> {
40///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
41///     be_writer.write_u16(0xA1B2)?;
42///     assert_eq!(be_writer.into_inner(), vec![0xA1, 0xB2]);
43///
44///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
45///     le_writer.write_u16(0xA1B2)?;
46///     assert_eq!(le_writer.into_inner(), vec![0xB2, 0xA1]);
47///
48///     let mut ne_writer = NumberWriter::with_order(ByteOrder::NE, vec![]);
49///     ne_writer.write_u16(0xA1B2)?;
50///     assert_eq!(
51///         ne_writer.into_inner(),
52///         if cfg!(target_endian = "big") {
53///             vec![0xA1, 0xB2]
54///         } else {
55///             vec![0xB2, 0xA1]
56///         }
57///     );
58///
59///     Ok(())
60/// }
61/// ```
62///
63/// [writer]: https://doc.rust-lang.org/std/io/trait.Write.html
64/// [`NumberWriter::new`]: NumberWriter::new
65/// [`NumberWriter::with_order`]: NumberWriter::with_order
66pub struct NumberWriter<W: Write> {
67    inner: W,
68    order: ByteOrder,
69}
70
71impl<W: Write> NumberWriter<W> {
72    #[inline]
73    pub fn new(w: W) -> NumberWriter<W> {
74        NumberWriter::with_order(ByteOrder::NE, w)
75    }
76
77    #[inline]
78    pub fn with_order(order: ByteOrder, w: W) -> NumberWriter<W> {
79        NumberWriter { inner: w, order }
80    }
81
82    /// Consumes this `NumberReader`, returning the underlying value.
83    ///
84    /// # Examples
85    ///
86    /// ```
87    /// use std::io::Cursor;
88    /// use byte_order::NumberReader;
89    ///
90    /// let reader = NumberReader::new(Cursor::new(vec![]));
91    ///
92    /// let cursor = reader.into_inner();
93    /// ```
94    pub fn into_inner(self) -> W {
95        self.inner
96    }
97
98    /// Gets a reference to the underlying value in this `NumberReader`.
99    ///
100    /// # Examples
101    ///
102    /// ```
103    /// use std::io::Cursor;
104    /// use byte_order::NumberReader;
105    ///
106    /// let reader = NumberReader::new(Cursor::new(vec![]));
107    ///
108    /// let reference = reader.get_ref();
109    /// ```
110    pub fn get_ref(&self) -> &W {
111        &self.inner
112    }
113
114    /// Gets a mutable reference to the underlying value in this `NumberReader`.
115    ///
116    /// # Examples
117    ///
118    /// ```
119    /// use std::io::Cursor;
120    /// use byte_order::NumberReader;
121    ///
122    /// let mut reader = NumberReader::new(Cursor::new(vec![]));
123    ///
124    /// let reference = reader.get_mut();
125    /// ```
126    pub fn get_mut(&mut self) -> &mut W {
127        &mut self.inner
128    }
129
130    /// Writes an unsigned 8-bit integer to the underlying writer.
131    ///
132    /// **Note:** Since this method reads a single byte, no byte order
133    /// conversions are used. It is included for completeness.
134    ///
135    /// # Errors
136    ///
137    /// This method propagates any error recieved from the internal call to
138    /// [`Write::write_all`].
139    ///
140    /// # Examples
141    ///
142    /// ```
143    /// use std::io;
144    /// use byte_order::NumberWriter;
145    ///
146    /// fn main() -> io::Result<()> {
147    ///     let mut writer = NumberWriter::new(vec![]);
148    ///     writer.write_u8(0x12u8)?;
149    ///     assert_eq!(writer.into_inner(), vec![0x12]);
150    ///     Ok(())
151    /// }
152    /// ```
153    ///
154    /// [`Write::write_all`]: Write::write_all
155    #[inline]
156    pub fn write_u8(&mut self, n: u8) -> Result<()> {
157        self.inner.write_all(&[n])
158    }
159
160    /// Writes an signed 8-bit integer to the underlying writer.
161    ///
162    /// **Note:** Since this method reads a single byte, no byte order
163    /// conversions are used. It is included for completeness.
164    ///
165    /// # Errors
166    ///
167    /// This method propagates any error recieved from the internal call to
168    /// [`Write::write_all`].
169    ///
170    /// # Examples
171    ///
172    /// ```
173    /// use std::io;
174    /// use byte_order::NumberWriter;
175    ///
176    /// fn main() -> io::Result<()> {
177    ///     let mut writer = NumberWriter::new(vec![]);
178    ///     writer.write_u8(0x12u8)?;
179    ///     assert_eq!(writer.into_inner(), vec![0x12]);
180    ///     Ok(())
181    /// }
182    /// ```
183    ///
184    /// [`Write::write_all`]: Write::write_all
185    #[inline]
186    pub fn write_i8(&mut self, n: i8) -> Result<()> {
187        self.write_u8(n as u8)
188    }
189
190    /// Writes an unsigned 16-bit integer to the underlying writer.
191    ///
192    /// # Errors
193    ///
194    /// This method propagates any error recieved from the internal call to
195    /// [`Write::write_all`].
196    ///
197    /// # Examples
198    ///
199    /// ```
200    /// use std::io;
201    /// use byte_order::{ByteOrder, NumberWriter};
202    ///
203    /// fn main() -> io::Result<()> {
204    ///     let n = 0x1234u16;
205    ///
206    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
207    ///     be_writer.write_u16(n)?;
208    ///     assert_eq!(be_writer.into_inner(), vec![0x12, 0x34]);
209    ///
210    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
211    ///     le_writer.write_u16(n)?;
212    ///     assert_eq!(le_writer.into_inner(), vec![0x34, 0x12]);
213    ///
214    ///     Ok(())
215    /// }
216    /// ```
217    ///
218    /// [`Write::write_all`]: Write::write_all
219    #[inline]
220    pub fn write_u16(&mut self, n: u16) -> Result<()> {
221        let bytes = match self.order {
222            ByteOrder::BE => n.to_be_bytes(),
223            ByteOrder::LE => n.to_le_bytes(),
224        };
225        self.inner.write_all(&bytes)
226    }
227
228    /// Writes a signed 16-bit integer to the underlying writer.
229    ///
230    /// # Errors
231    ///
232    /// This method propagates any error recieved from the internal call to
233    /// [`Write::write_all`].
234    ///
235    /// # Examples
236    ///
237    /// ```
238    /// use std::io;
239    /// use byte_order::{ByteOrder, NumberWriter};
240    ///
241    /// fn main() -> io::Result<()> {
242    ///     let n = 0x1234i16;
243    ///
244    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
245    ///     be_writer.write_i16(n)?;
246    ///     assert_eq!(be_writer.into_inner(), vec![0x12, 0x34]);
247    ///
248    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
249    ///     le_writer.write_i16(n)?;
250    ///     assert_eq!(le_writer.into_inner(), vec![0x34, 0x12]);
251    ///
252    ///     Ok(())
253    /// }
254    /// ```
255    ///
256    /// [`Write::write_all`]: Write::write_all
257    #[inline]
258    pub fn write_i16(&mut self, n: i16) -> Result<()> {
259        self.write_u16(n as u16)
260    }
261
262    /// Writes an unsigned 32-bit integer to the underlying writer.
263    ///
264    /// # Errors
265    ///
266    /// This method propagates any error recieved from the internal call to
267    /// [`Write::write_all`].
268    ///
269    /// # Examples
270    ///
271    /// ```
272    /// use std::io;
273    /// use byte_order::{ByteOrder, NumberWriter};
274    ///
275    /// fn main() -> io::Result<()> {
276    ///     let n = 0x12345678u32;
277    ///
278    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
279    ///     be_writer.write_u32(n)?;
280    ///     assert_eq!(be_writer.into_inner(), vec![0x12, 0x34, 0x56, 0x78]);
281    ///
282    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
283    ///     le_writer.write_u32(n)?;
284    ///     assert_eq!(le_writer.into_inner(), vec![0x78, 0x56, 0x34, 0x12]);
285    ///
286    ///     Ok(())
287    /// }
288    /// ```
289    ///
290    /// [`Write::write_all`]: Write::write_all
291    #[inline]
292    pub fn write_u32(&mut self, n: u32) -> Result<()> {
293        let bytes = match self.order {
294            ByteOrder::BE => n.to_be_bytes(),
295            ByteOrder::LE => n.to_le_bytes(),
296        };
297        self.inner.write_all(&bytes)
298    }
299
300    /// Writes a signed 32-bit integer to the underlying writer.
301    ///
302    /// # Errors
303    ///
304    /// This method propagates any error recieved from the internal call to
305    /// [`Write::write_all`].
306    ///
307    /// # Examples
308    ///
309    /// ```
310    /// use std::io;
311    /// use byte_order::{ByteOrder, NumberWriter};
312    ///
313    /// fn main() -> io::Result<()> {
314    ///     let n = 0x12345678i32;
315    ///
316    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
317    ///     be_writer.write_i32(n)?;
318    ///     assert_eq!(be_writer.into_inner(), vec![0x12, 0x34, 0x56, 0x78]);
319    ///
320    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
321    ///     le_writer.write_i32(n)?;
322    ///     assert_eq!(le_writer.into_inner(), vec![0x78, 0x56, 0x34, 0x12]);
323    ///
324    ///     Ok(())
325    /// }
326    /// ```
327    ///
328    /// [`Write::write_all`]: Write::write_all
329    #[inline]
330    pub fn write_i32(&mut self, n: i32) -> Result<()> {
331        self.write_u32(n as u32)
332    }
333
334    /// Writes an unsigned 64-bit integer to the underlying writer.
335    ///
336    /// # Errors
337    ///
338    /// This method propagates any error recieved from the internal call to
339    /// [`Write::write_all`].
340    ///
341    /// # Examples
342    ///
343    /// ```
344    /// use std::io;
345    /// use byte_order::{ByteOrder, NumberWriter};
346    ///
347    /// fn main() -> io::Result<()> {
348    ///     let n = 0x1234567890123456u64;
349    ///
350    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
351    ///     be_writer.write_u64(n)?;
352    ///     assert_eq!(be_writer.into_inner(), vec![0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]);
353    ///
354    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
355    ///     le_writer.write_u64(n)?;
356    ///     assert_eq!(le_writer.into_inner(), vec![0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]);
357    ///
358    ///     Ok(())
359    /// }
360    /// ```
361    ///
362    /// [`Write::write_all`]: Write::write_all
363    #[inline]
364    pub fn write_u64(&mut self, n: u64) -> Result<()> {
365        let bytes = match self.order {
366            ByteOrder::BE => n.to_be_bytes(),
367            ByteOrder::LE => n.to_le_bytes(),
368        };
369        self.inner.write_all(&bytes)
370    }
371
372    /// Writes a signed 64-bit integer to the underlying writer.
373    ///
374    /// # Errors
375    ///
376    /// This method propagates any error recieved from the internal call to
377    /// [`Write::write_all`].
378    ///
379    /// # Examples
380    ///
381    /// ```
382    /// use std::io;
383    /// use byte_order::{ByteOrder, NumberWriter};
384    ///
385    /// fn main() -> io::Result<()> {
386    ///     let n = 0x1234567890123456i64;
387    ///
388    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
389    ///     be_writer.write_i64(n)?;
390    ///     assert_eq!(be_writer.into_inner(), vec![0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]);
391    ///
392    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
393    ///     le_writer.write_i64(n)?;
394    ///     assert_eq!(le_writer.into_inner(), vec![0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]);
395    ///
396    ///     Ok(())
397    /// }
398    /// ```
399    ///
400    /// [`Write::write_all`]: Write::write_all
401    #[inline]
402    pub fn write_i64(&mut self, n: i64) -> Result<()> {
403        self.write_u64(n as u64)
404    }
405
406    /// Writes an unsigned 128-bit integer to the underlying writer.
407    ///
408    /// # Errors
409    ///
410    /// This method propagates any error recieved from the internal call to
411    /// [`Write::write_all`].
412    ///
413    /// # Examples
414    ///
415    /// ```
416    /// use std::io;
417    /// use byte_order::{ByteOrder, NumberWriter};
418    ///
419    /// fn main() -> io::Result<()> {
420    ///     let n = 0x12345678901234567890123456789012u128;
421    ///
422    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
423    ///     be_writer.write_u128(n)?;
424    ///     assert_eq!(
425    ///         be_writer.into_inner(),
426    ///         vec![
427    ///             0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
428    ///             0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
429    ///         ]
430    ///     );
431    ///
432    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
433    ///     le_writer.write_u128(n)?;
434    ///     assert_eq!(
435    ///         le_writer.into_inner(),
436    ///         vec![
437    ///             0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
438    ///             0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12
439    ///         ]
440    ///     );
441    ///
442    ///     Ok(())
443    /// }
444    /// ```
445    ///
446    /// [`Write::write_all`]: Write::write_all
447    #[inline]
448    pub fn write_u128(&mut self, n: u128) -> Result<()> {
449        let bytes = match self.order {
450            ByteOrder::BE => n.to_be_bytes(),
451            ByteOrder::LE => n.to_le_bytes(),
452        };
453        self.inner.write_all(&bytes)
454    }
455
456    /// Writes a signed 128-bit integer to the underlying writer.
457    ///
458    /// # Errors
459    ///
460    /// This method propagates any error recieved from the internal call to
461    /// [`Write::write_all`].
462    ///
463    /// # Examples
464    ///
465    /// ```
466    /// use std::io;
467    /// use byte_order::{ByteOrder, NumberWriter};
468    ///
469    /// fn main() -> io::Result<()> {
470    ///     let n = 0x12345678901234567890123456789012i128;
471    ///
472    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
473    ///     be_writer.write_i128(n)?;
474    ///     assert_eq!(
475    ///         be_writer.into_inner(),
476    ///         vec![
477    ///             0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
478    ///             0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
479    ///         ]
480    ///     );
481    ///
482    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
483    ///     le_writer.write_i128(n)?;
484    ///     assert_eq!(
485    ///         le_writer.into_inner(),
486    ///         vec![
487    ///             0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
488    ///             0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12
489    ///         ]
490    ///     );
491    ///
492    ///     Ok(())
493    /// }
494    /// ```
495    ///
496    /// [`Write::write_all`]: Write::write_all
497    #[inline]
498    pub fn write_i128(&mut self, n: i128) -> Result<()> {
499        self.write_u128(n as u128)
500    }
501
502    /// Writes a IEEE754 single-precision floating point number to the
503    /// underlying writer.
504    ///
505    /// # Errors
506    ///
507    /// This method propagates any error recieved from the internal call to
508    /// [`Write::write_all`].
509    ///
510    /// # Examples
511    ///
512    /// ```
513    /// use std::io::{self, Cursor};
514    /// use byte_order::{ByteOrder, NumberWriter};
515    ///
516    /// fn main() -> io::Result<()> {
517    ///     let n = 12.5f32;
518    ///
519    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
520    ///     be_writer.write_f32(n)?;
521    ///     assert_eq!(be_writer.into_inner(), vec![0x41, 0x48, 0x00, 0x00]);
522    ///
523    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
524    ///     le_writer.write_f32(n)?;
525    ///     assert_eq!(le_writer.into_inner(), vec![0x00, 0x00, 0x48, 0x41]);
526    ///
527    ///     Ok(())
528    /// }
529    /// ```
530    ///
531    /// [`Write::write_all`]: Write::write_all
532    #[inline]
533    pub fn write_f32(&mut self, n: f32) -> Result<()> {
534        let bytes = match self.order {
535            ByteOrder::BE => n.to_be_bytes(),
536            ByteOrder::LE => n.to_le_bytes(),
537        };
538        self.inner.write_all(&bytes)
539    }
540
541    /// Writes a IEEE754 double-precision floating point number to the
542    /// underlying writer.
543    ///
544    /// # Errors
545    ///
546    /// This method propagates any error recieved from the internal call to
547    /// [`Write::write_all`].
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// use std::io::{self, Cursor};
553    /// use byte_order::{ByteOrder, NumberWriter};
554    ///
555    /// fn main() -> io::Result<()> {
556    ///     let n = 12.5f64;
557    ///
558    ///     let mut be_writer = NumberWriter::with_order(ByteOrder::BE, vec![]);
559    ///     be_writer.write_f64(n)?;
560    ///     assert_eq!(be_writer.into_inner(), vec![0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
561    ///
562    ///     let mut le_writer = NumberWriter::with_order(ByteOrder::LE, vec![]);
563    ///     le_writer.write_f64(n)?;
564    ///     assert_eq!(le_writer.into_inner(), vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
565    ///
566    ///     Ok(())
567    /// }
568    /// ```
569    ///
570    /// [`Write::write_all`]: Write::write_all
571    #[inline]
572    pub fn write_f64(&mut self, n: f64) -> Result<()> {
573        let bytes = match self.order {
574            ByteOrder::BE => n.to_be_bytes(),
575            ByteOrder::LE => n.to_le_bytes(),
576        };
577        self.inner.write_all(&bytes)
578    }
579}
580
581impl<W: Write> Write for NumberWriter<W> {
582    fn write(&mut self, buf: &[u8]) -> Result<usize> {
583        self.inner.write(buf)
584    }
585
586    fn flush(&mut self) -> Result<()> {
587        self.inner.flush()
588    }
589}