embytes_buffer/
write.rs

1use core::{cell::Cell, ops::{Deref, DerefMut}};
2
3use crate::{Buffer, BufferError};
4
5/// A Writer to write to a [`Buffer`] as it is a writeable slice
6pub trait BufferWriter: DerefMut<Target = [u8]> {
7
8    /// After writing th bytes to `self` the user must tell teh buffer how many bytes have bee written. 
9    /// This increases the write_position of the buffer by `n`
10    fn commit(&self, n: usize) -> Result<(), BufferError>;
11
12    /// Return the number of bytes that can be written without an error
13    fn remaining_capacity(&self) -> usize;
14
15    /// Returns `true` if the writer has remaining capacity to write to
16    fn has_remaining_capacity(&self) -> bool {
17        self.remaining_capacity() > 0
18    }
19}
20
21/// An implementation of [`BufferWriter`] for [`Buffer`]
22pub struct Write<'a, T: AsMut<[u8]> + AsRef<[u8]>> {
23    buffer: &'a mut Buffer<T>,
24    bytes_written: Cell<usize>
25}
26
27impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> Write<'a, T> {
28    pub(crate) fn new(buffer: &'a mut Buffer<T>) -> Self {
29        Self {
30            buffer,
31            bytes_written: Cell::new(0)
32        }
33    }
34}
35
36impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> BufferWriter for Write<'a, T> {
37
38    fn commit(&self, n: usize) -> Result<(), BufferError> {
39        if self.remaining_capacity() < n {
40            Err(BufferError::NoCapacity)
41        } else {
42            self.bytes_written.set(
43                self.bytes_written.get() + n
44            );
45            Ok(())
46        }
47    }
48
49    fn remaining_capacity(&self) -> usize {
50        self.buffer.capacity() - self.buffer.write_position - self.bytes_written.get()
51    }
52}
53
54impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> Drop for Write<'a, T> {
55    fn drop(&mut self) {
56        
57        self.buffer.write_position += self.bytes_written.get();
58        if self.buffer.write_position > self.buffer.source.as_ref().len() {
59            panic!("illegal state: Write<'a, T> committed more bytes than available!")
60        }
61
62    }
63}
64
65impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> Deref for Write<'a, T>{
66    type Target = [u8];
67
68    fn deref(&self) -> &Self::Target {
69        let tgt = self.buffer.source.as_ref();
70        let offset = self.buffer.write_position + self.bytes_written.get();
71        &tgt[offset..]
72    }
73}
74
75impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> DerefMut for Write<'a, T>{
76    fn deref_mut(&mut self) -> &mut Self::Target {
77        let tgt = self.buffer.source.as_mut();
78        let offset = self.buffer.write_position + self.bytes_written.get();
79        &mut tgt[offset..]
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use crate::{Buffer, BufferWriter, ReadWrite};
86
87
88    #[test]
89    fn test_write() {
90        let mut b = [0u8; 8];
91        let mut buf = Buffer::new(&mut b);
92
93        buf.write_base(&[1, 2]).unwrap();
94
95
96        let mut write = buf.create_writer();
97        write[0] = 3;
98        write[1] = 4;
99
100        write.commit(2).unwrap();
101        drop(write);
102
103        assert_eq!(buf.data(), &[1, 2, 3, 4]);
104    }
105
106    #[test]
107    fn test_multi_write() {
108        let mut b = [0u8; 8];
109        let mut buf = Buffer::new(&mut b);
110
111        let mut write = buf.create_writer();
112        write[0] = 1;
113        write[1] = 2;
114        write.commit(2).unwrap();
115        drop(write);
116
117        let mut write = buf.create_writer();
118        write[0] = 3;
119        write[1] = 4;
120        write.commit(2).unwrap();
121        drop(write);
122
123        assert_eq!(buf.data(), &[1, 2, 3, 4]);
124        assert_eq!(buf.write_position, 4);
125    }
126
127}