Repository: sharksforarms/deku
Pull request #461 (2024-07-16 03:20:27)

Add to_slice

github-actions[bot]: ## Benchmark for f979437
  <details>
    <summary>Click to view benchmark</summary>

| Test | Base         | PR               | % |
|------|--------------|------------------|---|
| deku_read_bits | 1241.4±14.49ns | 1243.0±23.13ns | +0.13% |
| deku_read_byte | 3.3±0.05ns | 3.3±0.06ns | 0.00% |
| deku_read_enum | 2.6±0.05ns | 2.6±0.06ns | 0.00% |
| deku_read_vec | 33.7±0.60ns | 34.2±0.52ns | +1.48% |
| deku_write_bits | **160.6±6.37ns** | 167.4±7.29ns | **+4.23%** |
| deku_write_byte | 22.4±0.33ns | 22.6±0.93ns | +0.89% |
| deku_write_enum | 21.4±0.31ns | 21.4±0.52ns | 0.00% |
| deku_write_vec | **336.0±6.40ns** | 394.1±5.06ns | **+17.29%** |

  </details>
  
github-actions[bot]: ## Benchmark for 5be88f4
  <details>
    <summary>Click to view benchmark</summary>

| Test | Base         | PR               | % |
|------|--------------|------------------|---|
| deku_read_bits | **1232.4±11.28ns** | 1277.5±18.10ns | **+3.66%** |
| deku_read_byte | 3.3±0.04ns | 3.3±0.03ns | 0.00% |
| deku_read_enum | 2.5±0.05ns | 2.5±0.05ns | 0.00% |
| deku_read_vec | 32.9±0.22ns | 33.1±0.99ns | +0.61% |
| deku_write_bits | 169.3±3.27ns | 166.5±5.88ns | -1.65% |
| deku_write_byte | 22.6±0.34ns | 22.4±0.33ns | -0.88% |
| deku_write_enum | 21.1±0.31ns | 21.1±0.41ns | 0.00% |
| deku_write_vec | **336.1±10.29ns** | 349.7±6.62ns | **+4.05%** |

  </details>
  
github-actions[bot]: ## Benchmark for 15f0828
  <details>
    <summary>Click to view benchmark</summary>

| Test | Base         | PR               | % |
|------|--------------|------------------|---|
| deku_read_bits | 1264.6±14.00ns | 1262.6±20.41ns | -0.16% |
| deku_read_byte | **3.4±0.40ns** | 3.5±0.08ns | **+2.94%** |
| deku_read_enum | **2.5±0.08ns** | 2.8±0.08ns | **+12.00%** |
| deku_read_vec | 34.1±0.83ns | 34.6±0.69ns | +1.47% |
| deku_write_bits | 170.1±3.31ns | 170.7±3.74ns | +0.35% |
| deku_write_byte | 22.4±0.19ns | 22.5±0.32ns | +0.45% |
| deku_write_enum | 21.1±0.35ns | 21.1±0.34ns | 0.00% |
| deku_write_vec | **345.7±6.75ns** | 386.5±5.88ns | **+11.80%** |

  </details>
  

Patch:
diff --git a/src/lib.rs b/src/lib.rs
index a5f886f..b2fec92 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -515,6 +515,33 @@ pub trait DekuContainerWrite: DekuWriter<()> {
         Ok(out_buf)
     }
 
+    /// Write struct/enum to a given slice
+    ///
+    /// ```rust
+    /// # use deku::prelude::*;
+    /// #[derive(Debug, PartialEq, DekuRead, DekuWrite)]
+    /// #[deku(endian = "little")]
+    /// struct S {
+    ///    data_00: u8,
+    ///    data_01: u16,
+    ///    data_02: u32,
+    /// }
+    ///
+    /// let mut buf = [0; 7];
+    /// let s = S { data_00: 0x01, data_01: 0x02, data_02: 0x03 };
+    /// let amt_written = s.to_slice(&mut buf).unwrap();
+    /// assert_eq!(buf, [0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00]);
+    /// assert_eq!(amt_written, 7)
+    /// ````
+    #[inline(always)]
+    fn to_slice(&self, buf: &mut [u8]) -> Result<usize, DekuError> {
+        let mut __deku_writer = Writer::new(buf);
+        DekuWriter::to_writer(self, &mut __deku_writer, ())?;
+        __deku_writer.finalize()?;
+
+        Ok(__deku_writer.bits_written / 8)
+    }
+
     /// Write struct/enum to BitVec
     ///
     /// ```rust


Test patch:
diff --git a/tests/test_alloc.rs b/tests/test_alloc.rs
index 8da0463..86072b4 100644
--- a/tests/test_alloc.rs
+++ b/tests/test_alloc.rs
@@ -78,4 +78,21 @@ mod tests {
             (2, 1, 2)
         );
     }
+
+    #[test]
+    #[cfg_attr(miri, ignore)]
+    fn test_to_slice() {
+        let input = hex!("aa_bbbb_cc_0102_dd_ffffff_aa_0100ff");
+        let t = TestDeku::from_reader((&mut input.as_slice(), 0)).unwrap().1;
+
+        let mut out = [0x00; 100];
+
+        assert_eq!(
+            count_alloc(|| {
+                t.to_slice(&mut out).unwrap();
+            })
+            .0,
+            (1, 0, 1)
+        );
+    }
 }
diff --git a/tests/test_to_slice.rs b/tests/test_to_slice.rs
new file mode 100644
index 0000000..78c6c11
--- /dev/null
+++ b/tests/test_to_slice.rs
@@ -0,0 +1,47 @@
+use deku::prelude::*;
+
+#[derive(PartialEq, Debug, DekuRead, DekuWrite)]
+pub struct A {
+    #[deku(bytes = "3", endian = "big")]
+    address: u32,
+}
+
+#[test]
+fn test_to_slice_bytes() {
+    let bytes = [0x11, 0x22, 0x33];
+    let a = A::from_bytes((&bytes, 0)).unwrap().1;
+    let new_bytes = a.to_bytes().unwrap();
+    assert_eq!(bytes, &*new_bytes);
+
+    let bytes = [0x11, 0x22, 0x33];
+    let mut out = [0x00; 3];
+    let amt_written = a.to_slice(&mut out).unwrap();
+    assert_eq!(bytes, out.as_slice());
+    assert_eq!(amt_written, 3);
+}
+
+#[derive(PartialEq, Debug, DekuRead, DekuWrite)]
+pub struct B {
+    #[deku(bits = "3", endian = "little")]
+    inner: u8,
+}
+
+#[test]
+fn test_to_slice_bits() {
+    let b = B { inner: 0b111 };
+
+    let mut out = [0x00; 1];
+    let amt_written = b.to_slice(&mut out).unwrap();
+    assert_eq!([0b1110_0000], out.as_slice());
+    assert_eq!(amt_written, 1);
+}
+
+#[test]
+#[should_panic(expected = "called `Result::unwrap()` on an `Err` value: Io(WriteZero)")]
+fn test_to_slice_panic_writer_failure() {
+    let bytes = [0x11, 0x22, 0x33];
+    let a = A::from_bytes((&bytes, 0)).unwrap().1;
+
+    let mut out = [0x00; 2];
+    a.to_slice(&mut out).unwrap();
+}