Expand description
A library for decoding (“chiselling”) structures out of a byte-stream.
This crate primarily provides the Chisel type,
an abstraction for reading values of primitive type.
§Usage
First, create a Chisel, e.g. from an array of bytes:
use byte_chisel::prelude::*;
let bytes = [ 239, 190, 173, 222 ];
let mut chisel = Chisel::from_array(&bytes);You can then read a u32 from the array via:
let value = chisel.u32(Endianness::Little)?;
assert_eq!(value, 0xDEADBEEF);If you provide more data, you can read multiple values:
let bytes = [ 239, 190, 173, 222, 103, 10 ];
let mut chisel = Chisel::from_array(&bytes);
let val1 = chisel.u32(Endianness::Little)?;
let val2 = chisel.u16(Endianness::Little)?;
assert_eq!(val1, 0xDEADBEEF);
assert_eq!(val2, 0x0A67);Most formats use a consistent endianness. You can use a wrapper to avoid repeating it:
let mut chisel_be = chisel.big_endian();
// both of these `u16` are read as big-endian
let hi = chisel_be.u16()?;
let lo = chisel_be.u16()?;§Errors
This crate distinguishes between three types of errors during chiselling: Format Errors, Source Errors and EndOfInput. The byte offset an error occurred at is included for ease of debugging.
See the documentation on ChiselError for details.
§“Breaking”
In most cases, when a chiselling operation returns an error, the Chisel is said to “break”.
(This is called out in the documentation with the phrase “the chisel breaks” and a link to this section.)
A “broken” Chisel no longer accurately tracks the underlying byte-stream:
- Some bytes that are present in the byte-stream are “lost” and inaccessible.
- The tracked byte offset no longer reflects the position in the byte-stream.
Continuing to use a “broken” Chisel is discouraged.
Note that idiomatic use of the ? operator prevents broken Chisel usage.
§API Considerations
For composability, it is recommended that chiselling functions take the input Chisel by mutable reference:
fn chisel_resource_header<S : ChiselSource>(
	chisel: &mut Chisel<S>
) -> ChiselResult<ResourceHeader, HeaderError, S> {
	todo!()
}This allows using such functions as part of larger decodings:
let count = chisel.u16(Endianness::Little).forward()?;
let mut headers = Vec::with_capacity(count as usize);
for _ in 0..count {
	let header = chisel_resource_header(&mut chisel)
		.map_err(|e| e.map(FileError::BadHeader))?
	;
	headers.push(header)
}
/* parse the rest of the file... */§Examples
Decode (“chisel”) a simple resource header consisting of
- a little-endian 32-bit integer id
- a 1-byte tag and
- a null-terminated name
use byte_chisel::prelude::*;
 
fn chisel_resource_header<S : ChiselSource>(
	chisel: &mut Chisel<S>
) -> ChiselResult<ResourceHeader, HeaderError, S> {
	// read the id
	let id = chisel.u32(Endianness::Little).forward()?;
	// read the type tag
	let typ = chisel.u8().forward()?;
	// parse the type tag, only allowing ones we support
	let typ = match typ {
		0 => ResourceType::Image,
		// ...
		5 => ResourceType::Text,
		// if we encounter an unknown type, report a format error
		ty => return Err(chisel.error(HeaderError::UnknownType(ty), 1))
	};
	
	// save the name offaet for reporting later
	let name_offset = chisel.offset();
	let mut name = Vec::new();
	// read the name as a null-terminated string
	// note that `name` will not contain the terminating null!
	chisel.read_until(0, &mut name).forward()?;
	// convert to `String` for ease of use
	let name = String::from_utf8(name).map_err(
		// if the conversion fails (due to invalid utf-8), report a format error
		|_| ChiselError::format(name_offset, HeaderError::IllegalName)
	)?;
	
	Ok(ResourceHeader {
		id,
		typ,
		name
	})
}Re-exports§
- pub use source::ChiselSource;
- pub use source::ChiselSourceError;
Modules§
Structs§
- Chisel
- An object providing structured access to an underlying byte-stream.
- ChiselBigEndian 
- A Chisel, with big-endian byte order.
- ChiselError 
- The error type for chiseling operations.
- ChiselLittle Endian 
- A Chisel, with little-endian byte order.
Enums§
- ChiselError Data 
- The error data type for chiseling operations.
- Endianness
- Used to define byte order or “endianness”.
- ReadUntil Stop Reason 
- Used to indicate why a read_until_or_endoperation stopped.
Traits§
- InfalliableFormat Result Ext 
- Extension trait for InfallibleFormatResult.
Type Aliases§
- ChiselResult 
- The result type of attempting to chisel a Tfrom a sourceS, with format errors described byE.
- InfallibleFormat Error 
- The error type of attempting to chisel a value from a source S; where all byte sequences produce valid values (“infallible format”).
- InfallibleFormat Result 
- The error type of attempting to chisel a Tfrom a sourceS. All byte sequences produce validTs (“infallible format”).