parsec_interface/requests/request/
request_body.rs

1// Copyright 2019 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::requests::Result;
4#[cfg(feature = "fuzz")]
5use arbitrary::Arbitrary;
6use std::io::{Read, Write};
7use std::ops::{Deref, DerefMut};
8use zeroize::Zeroize;
9
10/// Wrapper around the body of a request.
11///
12/// Hides the contents and keeps them immutable.
13#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
14#[derive(Debug, PartialEq, Eq, Zeroize)]
15#[zeroize(drop)]
16pub struct RequestBody {
17    buffer: Vec<u8>,
18}
19
20impl Deref for RequestBody {
21    type Target = [u8];
22
23    fn deref(&self) -> &Self::Target {
24        &self.buffer
25    }
26}
27
28impl DerefMut for RequestBody {
29    fn deref_mut(&mut self) -> &mut Self::Target {
30        &mut self.buffer
31    }
32}
33
34impl RequestBody {
35    /// Create a new, emtpy request body field.
36    /// Available for testing only.
37    #[cfg(feature = "testing")]
38    pub(super) fn new() -> RequestBody {
39        RequestBody { buffer: Vec::new() }
40    }
41
42    /// Read the request body from a stream, given the length of the content.
43    pub(super) fn read_from_stream(mut stream: &mut impl Read, len: usize) -> Result<RequestBody> {
44        let buffer = get_from_stream!(stream; len);
45        Ok(RequestBody { buffer })
46    }
47
48    /// Write the request body to a stream.
49    pub(super) fn write_to_stream(&self, stream: &mut impl Write) -> Result<()> {
50        stream.write_all(&self.buffer)?;
51        Ok(())
52    }
53
54    /// Create a `RequestBody` from a vector of bytes.
55    pub(crate) fn from_bytes(buffer: Vec<u8>) -> RequestBody {
56        RequestBody { buffer }
57    }
58
59    /// Get the body as a slice of bytes.
60    pub fn bytes(&self) -> &[u8] {
61        &self.buffer
62    }
63
64    /// Get size of body.
65    pub fn len(&self) -> usize {
66        self.buffer.len()
67    }
68
69    /// Check if body is empty.
70    pub fn is_empty(&self) -> bool {
71        self.buffer.is_empty()
72    }
73
74    /// Create a `RequestBody` from the provided bytes.
75    ///
76    /// Must only be used for testing purposes.
77    #[cfg(feature = "testing")]
78    pub fn _from_bytes(buffer: Vec<u8>) -> RequestBody {
79        RequestBody { buffer }
80    }
81}