pub mod codec;
mod container;
pub mod crc;
pub mod leb;
mod programs;
mod strings;
use std::fmt;
pub use codec::{Decode, Encode, Reader, Writer};
pub use container::{EXTENSIONS, MAGIC, Module, ModuleWriter, OPTIONAL, Section, SectionEntry, Version};
pub use programs::{DirectoryEntry, LoadedModule, read, write, write_with};
pub use strings::StringTable;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ModuleError {
NotAModule,
Version(Version),
Feature(u32),
Truncated {
expected: u64,
actual: u64,
},
TrailingBytes {
expected: u64,
actual: u64,
},
HeaderChecksum {
computed: u32,
stored: u32,
},
SectionChecksum {
id: u32,
computed: u32,
stored: u32,
},
UnknownSection(u32),
MissingSection(u32),
Malformed {
section: &'static str,
offset: usize,
reason: String,
},
}
fn section_name(id: u32) -> String {
Section::by_id(id).map_or_else(|| format!("{id:#x}"), |s| s.name.to_owned())
}
impl fmt::Display for ModuleError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotAModule => write!(f, "not an ironwork load module"),
Self::Version(found) => {
let reads = Version::CURRENT;
write!(f, "load module format {}.{}; this ironwork reads ", found.major, found.minor)?;
if reads.major == 0 {
write!(f, "0.{}", reads.minor)?
} else {
write!(f, "{}.x", reads.major)?
}
write!(f, ". Compile the source again")
}
Self::Feature(bits) => write!(f, "load module needs features {bits:#010x}, which this ironwork lacks"),
Self::Truncated { expected, actual } => write!(f, "truncated: {actual} bytes of {expected}"),
Self::TrailingBytes { expected, actual } => {
write!(f, "{} bytes after the end of the module at {expected}", actual.saturating_sub(*expected))
}
Self::HeaderChecksum { computed, stored } => {
write!(f, "header is corrupt (checksum {computed:08X}, expected {stored:08X})")
}
Self::SectionChecksum { id, computed, stored } => {
write!(f, "section {} is corrupt (checksum {computed:08X}, expected {stored:08X})", section_name(*id))
}
Self::UnknownSection(id) => write!(f, "required section {id:#x} is unknown to this ironwork"),
Self::MissingSection(id) => write!(f, "required section {} is missing", section_name(*id)),
Self::Malformed { section, offset, reason } => {
write!(f, "{section} is malformed at byte {offset}: {reason}")
}
}
}
}
impl std::error::Error for ModuleError {}