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}