3 releases (breaking)

Uses old Rust 2015

0.3.0 Jun 28, 2019
0.2.0 May 8, 2017
0.1.0 May 4, 2017

#1247 in Parser implementations

Download history 33932/week @ 2024-06-15 43139/week @ 2024-06-22 26564/week @ 2024-06-29 32222/week @ 2024-07-06 37267/week @ 2024-07-13 39465/week @ 2024-07-20 32623/week @ 2024-07-27 31504/week @ 2024-08-03 24329/week @ 2024-08-10 25514/week @ 2024-08-17 28811/week @ 2024-08-24 25693/week @ 2024-08-31 25145/week @ 2024-09-07 22119/week @ 2024-09-14 29121/week @ 2024-09-21 20594/week @ 2024-09-28

102,670 downloads per month
Used in 65 crates (8 directly)

MIT license

15KB
253 lines

Circular

Circular is a stream abstraction designed for use with nom. It can expose the available data, a mutable slice of the available space, and it separates reading data from actually consuming it from the buffer.


lib.rs:

Circular, a stream abstraction designed for use with nom

Circular provides a Buffer type that wraps a Vec<u8> with a position and end. Compared to a stream abstraction that would use std::io::Read, it separates the reading and consuming phases. Read is designed to write the data in a mutable slice and consume it from the stream as it does that.

When used in streaming mode, nom will try to parse a slice, then tell you how much it consumed. So you don't know how much data was actually used until the parser returns. Circular::Buffer exposes a data() method that gives an immutable slice of all the currently readable data, and a consume() method to advance the position in the stream. The space() and fill() methods are the write counterparts to those methods.

extern crate circular;

use circular::Buffer;
use std::io::Write;

fn main() {

  // allocate a new Buffer
  let mut b = Buffer::with_capacity(10);
  assert_eq!(b.available_data(), 0);
  assert_eq!(b.available_space(), 10);

  let res = b.write(&b"abcd"[..]);
  assert_eq!(res.ok(), Some(4));
  assert_eq!(b.available_data(), 4);
  assert_eq!(b.available_space(), 6);

  //the 4 bytes we wrote are immediately available and usable for parsing
  assert_eq!(b.data(), &b"abcd"[..]);

  // this will advance the position from 0 to 2. it does not modify the underlying Vec
  b.consume(2);
  assert_eq!(b.available_data(), 2);
  assert_eq!(b.available_space(), 6);
  assert_eq!(b.data(), &b"cd"[..]);

  // shift moves the available data at the beginning of the buffer.
  // the position is now 0
  b.shift();
  assert_eq!(b.available_data(), 2);
  assert_eq!(b.available_space(), 8);
  assert_eq!(b.data(), &b"cd"[..]);
}

No runtime deps