You can think of a SubCursor
as slices for Read
ers or Write
rs.
A SubCursor
provides a more efficient way, to handle data in apis.
Let's imagine you have an archive, that requires files:
use std::io::{self, Cursor, Read, Seek};
pub struct Archive<T> {
files: Vec<T>,
}
impl<T: Read + Seek> Archive<T> {
pub fn new() -> Self {
Self {
files: vec![]
}
}
pub fn push(&mut self, value: T) {
self.files.push(value)
}
}
fn main() -> io::Result<()> {
let mut archive = Archive::new();
// imagine, that these are Files instead of Cursor
archive.push(Cursor::new(b"This is an example file".to_vec()));
archive.push(Cursor::new(b"This is another example file".to_vec()));
Ok(())
}
Now you have a single file, that contains many smaller files (for example a .zip
) and you want to add them to the Archive
, without reading the entire file into memory and wrapping each of them in a Cursor
.
This can be achieved with a SubCursor
, which is like slices, but for Read
er and Write
er.
use std::io::{self, Seek, Read, Cursor};
use std::sync::{Arc, Mutex};
use sub_cursor::SubCursor;
pub struct Archive<T> {
files: Vec<T>,
}
impl<T: Read + Seek> Archive<T> {
pub fn new() -> Self {
Self {
files: vec![]
}
}
pub fn push(&mut self, value: T) {
self.files.push(value)
}
pub fn print_files(&mut self) -> io::Result<()> {
for file in &mut self.files {
let mut string = String::new();
file.read_to_string(&mut string)?;
println!("{}", string);
}
Ok(())
}
}
fn main() -> io::Result<()> {
let mut archive = Archive::new();
archive.push(SubCursor::from(b"This is an example file".to_vec()));
archive.push(SubCursor::from(b"This is another example file".to_vec()));
let file = Arc::new(Mutex::new(Cursor::new(b"file1,file2,file3".to_vec())));
archive.push(
SubCursor::from(file.clone())
// first file starts at index 0
.start(0)
// and ends at 5
.end(5)
);
archive.push(
SubCursor::from(file.clone())
.start(7)
.end(11)
);
archive.push(
// the end will be set automatically
SubCursor::from(file.clone()).start(12)
);
archive.print_files()?;
Ok(())
}
Add the following to your Cargo.toml
:
[dependencies]
sub_cursor = "0.1"
You can find the documentation here.
This project is loosely inspired by slice
.
This project is licensed under either of
at your option.