use craft_codec::{Compression, Config, Decoder, Encoder, Encryption, Error, Framing, Metadata};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut metadata = Metadata::new(Config::new(
Framing::Fixed(8),
Compression::None,
Encryption::None,
)?);
let mut encoder: Encoder = (&metadata).try_into()?;
let original = b"small independent frames";
let mut object = Vec::new();
let mut buffer = Vec::new();
for (index, raw) in original.chunks(8).enumerate() {
buffer.clear();
buffer.extend_from_slice(raw);
let sizes = encoder.encode_frame(index as u64, &mut buffer)?;
object.extend_from_slice(&buffer);
metadata.push(sizes)?;
}
let metadata = Metadata::from_parts(metadata.into_parts())?;
let mut decoder = Decoder::try_from(&metadata)?;
let (query, frames) = metadata.range(3, Some(19))?;
let start = usize::try_from(query.start).map_err(|_| Error::Overflow)?;
let end = usize::try_from(query.end).map_err(|_| Error::Overflow)?;
let mut source = object.get(start..end).ok_or(Error::InvalidStoredLength)?;
let mut selected = Vec::new();
for frame in frames {
buffer.resize(frame.spec.stored_len(), 0);
std::io::Read::read_exact(&mut source, &mut buffer)?;
decoder.decode_frame(frame.spec, &mut buffer)?;
selected.extend_from_slice(buffer.get(frame.selected).ok_or(Error::InvalidRange)?);
}
if original.get(3..19) != Some(selected.as_slice()) {
return Err(Error::InvalidMetadata.into());
}
println!("{}", String::from_utf8(selected)?);
Ok(())
}