use std::io::{Read, Write};
use subversion::io::{backend::*, Stream};
struct LoggingBackend<T> {
inner: T,
log_prefix: String,
}
impl<T> LoggingBackend<T> {
fn new(inner: T, prefix: &str) -> Self {
Self {
inner,
log_prefix: prefix.to_string(),
}
}
}
impl<T: Read + Write + Send + 'static> StreamBackend for LoggingBackend<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, subversion::Error<'static>> {
println!("{}: Reading up to {} bytes", self.log_prefix, buf.len());
let n = self
.inner
.read(buf)
.map_err(|e| subversion::Error::from_message(&e.to_string()))?;
println!("{}: Read {} bytes", self.log_prefix, n);
Ok(n)
}
fn write(&mut self, buf: &[u8]) -> Result<usize, subversion::Error<'static>> {
println!("{}: Writing {} bytes", self.log_prefix, buf.len());
let n = self
.inner
.write(buf)
.map_err(|e| subversion::Error::from_message(&e.to_string()))?;
println!("{}: Wrote {} bytes", self.log_prefix, n);
Ok(n)
}
fn close(&mut self) -> Result<(), subversion::Error<'static>> {
println!("{}: Closing stream", self.log_prefix);
self.inner
.flush()
.map_err(|e| subversion::Error::from_message(&e.to_string()))?;
Ok(())
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Custom Stream Backend Examples ===\n");
println!("1. Using BufferBackend with IntoStream:");
use subversion::io::IntoStream;
let backend = BufferBackend::from_vec(b"Hello, Subversion!".to_vec());
let mut stream = backend.into_stream()?;
let mut buf = vec![0u8; 18];
let n = stream.read(&mut buf)?;
println!(" Read {} bytes: {:?}", n, std::str::from_utf8(&buf[..n])?);
println!("\n2. Using LoggingBackend:");
let buffer = std::io::Cursor::new(b"Logged data".to_vec());
let logging_backend = LoggingBackend::new(buffer, "LOG");
let mut stream = Stream::from_backend(logging_backend)?;
let mut buf = vec![0u8; 11];
stream.read(&mut buf)?;
println!(" Result: {:?}", std::str::from_utf8(&buf)?);
println!("\n3. Using BufferBackend with write:");
let backend = BufferBackend::new();
let mut stream = Stream::from_backend(backend)?;
use std::io::Write;
stream.write_all(b"Written data")?;
stream.flush()?;
println!(" Data successfully written to buffer backend");
println!("\n4. Using StreamBuilder:");
use subversion::io::builder::StreamBuilder;
let backend = BufferBackend::from_vec(b"Built with builder".to_vec());
let mut stream = StreamBuilder::new(backend).buffer_size(1024).build()?;
let mut buffer = vec![0u8; 18];
let bytes_read = stream.read(&mut buffer)?;
println!(" Stream created with builder pattern");
println!(
" Read {} bytes: {:?}",
bytes_read,
String::from_utf8_lossy(&buffer[..bytes_read])
);
println!("\n5. Using specialized backends:");
let data = b"Read-only data";
let reader = std::io::Cursor::new(data);
let readonly = ReadOnlyBackend::new(reader);
let mut stream = Stream::from_backend(readonly)?;
let mut buf = vec![0u8; 14];
let n = stream.read(&mut buf)?;
println!(" Read-only: {:?}", std::str::from_utf8(&buf[..n])?);
let writer = Vec::new();
let writeonly = WriteOnlyBackend::new(writer);
let mut stream = Stream::from_backend(writeonly)?;
stream.write_all(b"Write-only data")?;
println!(" Write-only: Data written successfully");
println!("\n=== All examples completed successfully ===");
Ok(())
}