Skip to content

Commit 31f8162

Browse files
committed
Make Read trait and helpers public
Allows users of the crate to have their own Read implementations and create the equivalent of the `from_*` functions. Specifically, if the bytes to read are actually a continuous stream of bencoded data (so a dictionary followed by another dictionary for instance), then the library user can create a reader which does not check that it reached the end of all the bytes after reading one value. For instance: ``` use std::{cell::RefCell, rc::Rc}; pub(crate) struct SliceReadView<'a> { reader: Rc<RefCell<bt_bencode::read::SliceRead<'a>>>, } impl<'a> SliceReadView<'a> { pub(crate) fn new(reader: Rc<RefCell<bt_bencode::read::SliceRead<'a>>>) -> Self { Self { reader } } } impl<'a> bt_bencode::read::Read<'a> for SliceReadView<'a> { #[inline] fn next(&mut self) -> Option<Result<u8, bt_bencode::Error>> { self.reader.borrow_mut().next() } #[inline] fn peek(&mut self) -> Option<Result<u8, bt_bencode::Error>> { self.reader.borrow_mut().peek() } #[inline] fn byte_offset(&self) -> usize { self.reader.borrow().byte_offset() } } ``` To read multiple values: ``` let reader = std::rc::Rc::new(std::cell::RefCell::new(bt_bencode::read::SliceRead::new( &bytes[..], ))); loop { let mut de = bt_bencode::Deserializer::new(SliceReadView::new(reader.clone())); use bt_bencode::read::Read; use serde::de::Deserialize; match bt_bencode::Value::deserialize(&mut de) { Ok(value) => { // Process the decoded `value` } Err(e) => match e { bt_bencode::Error::EofWhileParsingValue if reader.clone().borrow_mut().peek().is_none() => { // The end of file was reached as expected break; } _ => { // An unexpected error occured during processing dbg!(e); } }, } } ```
1 parent bb15790 commit 31f8162

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# CHANGELOG
22

3+
## v0.3.0
4+
5+
### Added
6+
7+
* `Read` trait and helper implementations are made public.
8+
39
## v0.2.0
410

511
### Added

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ extern crate serde;
7777

7878
mod de;
7979
mod error;
80-
mod read;
80+
pub mod read;
8181
#[cfg(feature = "std")]
8282
mod ser;
8383
pub mod value;

src/read.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
1+
//! `Read` trait and helpers to read bytes for the deserializer.
2+
13
#[cfg(feature = "std")]
24
use crate::error::Error;
35
#[cfg(feature = "std")]
46
use std::io;
57

68
use crate::error::Result;
79

10+
/// Trait used by the `de::Deserializer` to read bytes.
811
pub trait Read<'de> {
12+
/// Consumes and returns the next read byte.
913
fn next(&mut self) -> Option<Result<u8>>;
14+
/// Returns the next byte but does not consume.
15+
///
16+
/// Repeated peeks (with no `next()` call) should return the same byte.
1017
fn peek(&mut self) -> Option<Result<u8>>;
18+
/// Returns the position in the stream of bytes.
1119
fn byte_offset(&self) -> usize;
1220
}
1321

22+
/// A wrapper to implement this crate's `Read` trait for `std::io::Read` trait implementations.
1423
#[cfg(feature = "std")]
15-
pub(crate) struct IoRead<R>
24+
pub struct IoRead<R>
1625
where
1726
R: io::Read,
1827
{
@@ -26,6 +35,7 @@ impl<R> IoRead<R>
2635
where
2736
R: io::Read,
2837
{
38+
/// Instantiates a new reader.
2939
pub fn new(reader: R) -> Self {
3040
IoRead {
3141
iter: reader.bytes(),
@@ -79,12 +89,14 @@ where
7989
}
8090
}
8191

82-
pub(crate) struct SliceRead<'a> {
92+
/// A wrapper to implement this crate's `Read` trait for byte slices.
93+
pub struct SliceRead<'a> {
8394
slice: &'a [u8],
8495
byte_offset: usize,
8596
}
8697

8798
impl<'a> SliceRead<'a> {
99+
/// Instantiates a new reader.
88100
pub fn new(slice: &'a [u8]) -> Self {
89101
SliceRead {
90102
slice,

0 commit comments

Comments
 (0)