Struct RotatingBuffer

Source
pub struct RotatingBuffer<T: Default + Copy, const S: usize> {
    pub inner: [T; S],
    /* private fields */
}

Fields§

§inner: [T; S]

Implementations§

Source§

impl<T: Default + Copy, const S: usize> RotatingBuffer<T, S>

Source

pub fn new() -> RotatingBuffer<T, S>

Examples found in repository?
examples/read_to_eof.rs (line 10)
7fn main() -> std::io::Result<()> {
8    // Unusually small, but we're just proving a point here. Let's just assume we have incredibly
9    // limited bandwidth and flexible value lengths, separated by a comma
10    let mut buf = RotatingBuffer::<u8, 5>::new();
11
12    let mut stream = TcpStream::connect("127.0.0.1:34254")?;
13
14    loop {
15        let read_size = stream.read(buf.get_append_only())?;
16        if read_size != 0 {
17            // read_size and _buf_size may diverge because add_len extends data that was
18            // right-rotated previously
19            let _buf_size = buf.add_len(read_size);
20        }
21
22        // .as_slice() will provide a slice combining previous right-rotated
23        // data as well as newly written data
24        let incoming = str::from_utf8(buf.as_slice()).unwrap();
25
26        // Print every comma separated value on a separate line, even if the buffer is too small to
27        // hold the entire value, except if it's "EOF\n"
28        if !incoming.ends_with("EOF\n") && read_size != 0 || incoming.len() > 4 {
29            if let Some(index) = incoming.rfind(',') {
30                for value in incoming[..index].split(',') {
31                    println!("{}", value);
32                }
33                // Do not include the comma when rotating and resizing
34                buf.rotate_right_and_resize_at(index + 1);
35            } else {
36                // Here we could push to a heap-allocated structure if appropriate, but we'd need to
37                // adapt the logic above to account for when this value is completed by a comma
38                print!("{}", incoming);
39                buf.resize(0);
40            }
41        } else {
42            return Ok(());
43        }
44    }
45}
Source

pub fn as_slice(&self) -> &[T]

Extracts slice with the length of the buffer’s internally tracked size

§Example
let mut buf = RotatingBuffer::<u128, 20>::new();
assert_eq!(buf.as_slice().len(), 0);

buf.add_len(15);
assert_eq!(buf.as_slice().len(), 15);
Examples found in repository?
examples/read_to_eof.rs (line 24)
7fn main() -> std::io::Result<()> {
8    // Unusually small, but we're just proving a point here. Let's just assume we have incredibly
9    // limited bandwidth and flexible value lengths, separated by a comma
10    let mut buf = RotatingBuffer::<u8, 5>::new();
11
12    let mut stream = TcpStream::connect("127.0.0.1:34254")?;
13
14    loop {
15        let read_size = stream.read(buf.get_append_only())?;
16        if read_size != 0 {
17            // read_size and _buf_size may diverge because add_len extends data that was
18            // right-rotated previously
19            let _buf_size = buf.add_len(read_size);
20        }
21
22        // .as_slice() will provide a slice combining previous right-rotated
23        // data as well as newly written data
24        let incoming = str::from_utf8(buf.as_slice()).unwrap();
25
26        // Print every comma separated value on a separate line, even if the buffer is too small to
27        // hold the entire value, except if it's "EOF\n"
28        if !incoming.ends_with("EOF\n") && read_size != 0 || incoming.len() > 4 {
29            if let Some(index) = incoming.rfind(',') {
30                for value in incoming[..index].split(',') {
31                    println!("{}", value);
32                }
33                // Do not include the comma when rotating and resizing
34                buf.rotate_right_and_resize_at(index + 1);
35            } else {
36                // Here we could push to a heap-allocated structure if appropriate, but we'd need to
37                // adapt the logic above to account for when this value is completed by a comma
38                print!("{}", incoming);
39                buf.resize(0);
40            }
41        } else {
42            return Ok(());
43        }
44    }
45}
Source

pub fn get_append_only(&mut self) -> &mut [T]

Returns a mutable slice with the length of the currently “unused” allocation of the buffer

§Example
let mut buf = RotatingBuffer::<u8, 5>::new();
buf.add_len(3);

assert_eq!(buf.get_append_only().len(), 2);
buf.get_append_only()[0] = 50;
assert_eq!(buf.inner, [0, 0, 0, 50, 0]);
Examples found in repository?
examples/read_to_eof.rs (line 15)
7fn main() -> std::io::Result<()> {
8    // Unusually small, but we're just proving a point here. Let's just assume we have incredibly
9    // limited bandwidth and flexible value lengths, separated by a comma
10    let mut buf = RotatingBuffer::<u8, 5>::new();
11
12    let mut stream = TcpStream::connect("127.0.0.1:34254")?;
13
14    loop {
15        let read_size = stream.read(buf.get_append_only())?;
16        if read_size != 0 {
17            // read_size and _buf_size may diverge because add_len extends data that was
18            // right-rotated previously
19            let _buf_size = buf.add_len(read_size);
20        }
21
22        // .as_slice() will provide a slice combining previous right-rotated
23        // data as well as newly written data
24        let incoming = str::from_utf8(buf.as_slice()).unwrap();
25
26        // Print every comma separated value on a separate line, even if the buffer is too small to
27        // hold the entire value, except if it's "EOF\n"
28        if !incoming.ends_with("EOF\n") && read_size != 0 || incoming.len() > 4 {
29            if let Some(index) = incoming.rfind(',') {
30                for value in incoming[..index].split(',') {
31                    println!("{}", value);
32                }
33                // Do not include the comma when rotating and resizing
34                buf.rotate_right_and_resize_at(index + 1);
35            } else {
36                // Here we could push to a heap-allocated structure if appropriate, but we'd need to
37                // adapt the logic above to account for when this value is completed by a comma
38                print!("{}", incoming);
39                buf.resize(0);
40            }
41        } else {
42            return Ok(());
43        }
44    }
45}
Source

pub fn is_empty(&self) -> bool

Returns true if the buffer’s internal size is 0

Source

pub fn len(&self) -> usize

Returns internally tracked length

Source

pub fn capacity(&self) -> usize

Returns the capacity of this buffer

Source

pub fn resize(&mut self, new_len: usize)

Manually set the internal size of the buffer

§Panics

Panics if the new size is bigger than its capacity

Examples found in repository?
examples/read_to_eof.rs (line 39)
7fn main() -> std::io::Result<()> {
8    // Unusually small, but we're just proving a point here. Let's just assume we have incredibly
9    // limited bandwidth and flexible value lengths, separated by a comma
10    let mut buf = RotatingBuffer::<u8, 5>::new();
11
12    let mut stream = TcpStream::connect("127.0.0.1:34254")?;
13
14    loop {
15        let read_size = stream.read(buf.get_append_only())?;
16        if read_size != 0 {
17            // read_size and _buf_size may diverge because add_len extends data that was
18            // right-rotated previously
19            let _buf_size = buf.add_len(read_size);
20        }
21
22        // .as_slice() will provide a slice combining previous right-rotated
23        // data as well as newly written data
24        let incoming = str::from_utf8(buf.as_slice()).unwrap();
25
26        // Print every comma separated value on a separate line, even if the buffer is too small to
27        // hold the entire value, except if it's "EOF\n"
28        if !incoming.ends_with("EOF\n") && read_size != 0 || incoming.len() > 4 {
29            if let Some(index) = incoming.rfind(',') {
30                for value in incoming[..index].split(',') {
31                    println!("{}", value);
32                }
33                // Do not include the comma when rotating and resizing
34                buf.rotate_right_and_resize_at(index + 1);
35            } else {
36                // Here we could push to a heap-allocated structure if appropriate, but we'd need to
37                // adapt the logic above to account for when this value is completed by a comma
38                print!("{}", incoming);
39                buf.resize(0);
40            }
41        } else {
42            return Ok(());
43        }
44    }
45}
Source

pub fn add_len(&mut self, new_len: usize) -> usize

Add to the current internal length of the buffer

§Example
let mut buf = RotatingBuffer::<u8, 5>::new();
assert_eq!(buf.len(), 0);

buf.add_len(3);
assert_eq!(buf.len(), 3);
buf.add_len(1);
assert_eq!(buf.len(), 4);
Examples found in repository?
examples/read_to_eof.rs (line 19)
7fn main() -> std::io::Result<()> {
8    // Unusually small, but we're just proving a point here. Let's just assume we have incredibly
9    // limited bandwidth and flexible value lengths, separated by a comma
10    let mut buf = RotatingBuffer::<u8, 5>::new();
11
12    let mut stream = TcpStream::connect("127.0.0.1:34254")?;
13
14    loop {
15        let read_size = stream.read(buf.get_append_only())?;
16        if read_size != 0 {
17            // read_size and _buf_size may diverge because add_len extends data that was
18            // right-rotated previously
19            let _buf_size = buf.add_len(read_size);
20        }
21
22        // .as_slice() will provide a slice combining previous right-rotated
23        // data as well as newly written data
24        let incoming = str::from_utf8(buf.as_slice()).unwrap();
25
26        // Print every comma separated value on a separate line, even if the buffer is too small to
27        // hold the entire value, except if it's "EOF\n"
28        if !incoming.ends_with("EOF\n") && read_size != 0 || incoming.len() > 4 {
29            if let Some(index) = incoming.rfind(',') {
30                for value in incoming[..index].split(',') {
31                    println!("{}", value);
32                }
33                // Do not include the comma when rotating and resizing
34                buf.rotate_right_and_resize_at(index + 1);
35            } else {
36                // Here we could push to a heap-allocated structure if appropriate, but we'd need to
37                // adapt the logic above to account for when this value is completed by a comma
38                print!("{}", incoming);
39                buf.resize(0);
40            }
41        } else {
42            return Ok(());
43        }
44    }
45}
Source

pub fn rotate_right_and_resize(&mut self, k: usize)

Rotates the buffer contents in place (see core::slice::rotate_right) and subsequently changes the buffer’s internal length to however much was rotated

§Example
let mut buf = RotatingBuffer::<bool, 5>::new();
buf.get_append_only()[3] = true;
buf.add_len(5);

buf.rotate_right_and_resize(2);
assert_eq!(buf.as_slice()[0], true);
assert_eq!(buf.len(), 2);
Source

pub fn rotate_right_and_resize_at(&mut self, index: usize)

Rotate and resize buffer by supplying an index rather than a length

§Example
let mut buf = RotatingBuffer::<bool, 5>::new();
buf.get_append_only()[3] = true;
buf.add_len(5);

buf.rotate_right_and_resize_at(3);
assert_eq!(buf.as_slice()[0], true);
assert_eq!(buf.len(), 2);
Examples found in repository?
examples/read_to_eof.rs (line 34)
7fn main() -> std::io::Result<()> {
8    // Unusually small, but we're just proving a point here. Let's just assume we have incredibly
9    // limited bandwidth and flexible value lengths, separated by a comma
10    let mut buf = RotatingBuffer::<u8, 5>::new();
11
12    let mut stream = TcpStream::connect("127.0.0.1:34254")?;
13
14    loop {
15        let read_size = stream.read(buf.get_append_only())?;
16        if read_size != 0 {
17            // read_size and _buf_size may diverge because add_len extends data that was
18            // right-rotated previously
19            let _buf_size = buf.add_len(read_size);
20        }
21
22        // .as_slice() will provide a slice combining previous right-rotated
23        // data as well as newly written data
24        let incoming = str::from_utf8(buf.as_slice()).unwrap();
25
26        // Print every comma separated value on a separate line, even if the buffer is too small to
27        // hold the entire value, except if it's "EOF\n"
28        if !incoming.ends_with("EOF\n") && read_size != 0 || incoming.len() > 4 {
29            if let Some(index) = incoming.rfind(',') {
30                for value in incoming[..index].split(',') {
31                    println!("{}", value);
32                }
33                // Do not include the comma when rotating and resizing
34                buf.rotate_right_and_resize_at(index + 1);
35            } else {
36                // Here we could push to a heap-allocated structure if appropriate, but we'd need to
37                // adapt the logic above to account for when this value is completed by a comma
38                print!("{}", incoming);
39                buf.resize(0);
40            }
41        } else {
42            return Ok(());
43        }
44    }
45}

Trait Implementations§

Source§

impl<T: Clone + Default + Copy, const S: usize> Clone for RotatingBuffer<T, S>

Source§

fn clone(&self) -> RotatingBuffer<T, S>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + Default + Copy, const S: usize> Debug for RotatingBuffer<T, S>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default + Copy, const S: usize> Default for RotatingBuffer<T, S>

Maybe just to allow RotatingBuffer<RotatingBuffer<T, S>, S> 😄

§Example

let mut buf = RotatingBuffer::<RotatingBuffer<u8, 10>, 5>::new();
buf.add_len(2);
let slice = buf.as_slice();
assert_eq!(slice[0].inner, slice[1].inner);

But why!

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T: Copy + Default + Copy, const S: usize> Copy for RotatingBuffer<T, S>

Auto Trait Implementations§

§

impl<T, const S: usize> Freeze for RotatingBuffer<T, S>
where T: Freeze,

§

impl<T, const S: usize> RefUnwindSafe for RotatingBuffer<T, S>
where T: RefUnwindSafe,

§

impl<T, const S: usize> Send for RotatingBuffer<T, S>
where T: Send,

§

impl<T, const S: usize> Sync for RotatingBuffer<T, S>
where T: Sync,

§

impl<T, const S: usize> Unpin for RotatingBuffer<T, S>
where T: Unpin,

§

impl<T, const S: usize> UnwindSafe for RotatingBuffer<T, S>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.