ironwork_rt/module/
mod.rs1pub mod codec;
4mod container;
5pub mod crc;
6pub mod leb;
7mod programs;
8mod strings;
9
10use std::fmt;
11
12pub use codec::{Decode, Encode, Reader, Writer};
13pub use container::{EXTENSIONS, MAGIC, Module, ModuleWriter, OPTIONAL, Section, SectionEntry, Version};
14pub use programs::{DirectoryEntry, LoadedModule, read, write, write_with};
15pub use strings::StringTable;
16
17#[derive(Clone, Debug, PartialEq, Eq)]
18pub enum ModuleError {
19 NotAModule,
21 Version(Version),
23 Feature(u32),
25 Truncated {
27 expected: u64,
28 actual: u64,
29 },
30 TrailingBytes {
32 expected: u64,
33 actual: u64,
34 },
35 HeaderChecksum {
36 computed: u32,
37 stored: u32,
38 },
39 SectionChecksum {
40 id: u32,
41 computed: u32,
42 stored: u32,
43 },
44 UnknownSection(u32),
46 MissingSection(u32),
47 Malformed {
49 section: &'static str,
50 offset: usize,
51 reason: String,
52 },
53}
54
55fn section_name(id: u32) -> String {
56 Section::by_id(id).map_or_else(|| format!("{id:#x}"), |s| s.name.to_owned())
57}
58
59impl fmt::Display for ModuleError {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 Self::NotAModule => write!(f, "not an ironwork load module"),
63 Self::Version(found) => {
64 let reads = Version::CURRENT;
65 write!(f, "load module format {}.{}; this ironwork reads ", found.major, found.minor)?;
66 if reads.major == 0 {
67 write!(f, "0.{}", reads.minor)?
68 } else {
69 write!(f, "{}.x", reads.major)?
70 }
71 write!(f, ". Compile the source again")
72 }
73 Self::Feature(bits) => write!(f, "load module needs features {bits:#010x}, which this ironwork lacks"),
74 Self::Truncated { expected, actual } => write!(f, "truncated: {actual} bytes of {expected}"),
75 Self::TrailingBytes { expected, actual } => {
76 write!(f, "{} bytes after the end of the module at {expected}", actual.saturating_sub(*expected))
77 }
78 Self::HeaderChecksum { computed, stored } => {
79 write!(f, "header is corrupt (checksum {computed:08X}, expected {stored:08X})")
80 }
81 Self::SectionChecksum { id, computed, stored } => {
82 write!(f, "section {} is corrupt (checksum {computed:08X}, expected {stored:08X})", section_name(*id))
83 }
84 Self::UnknownSection(id) => write!(f, "required section {id:#x} is unknown to this ironwork"),
85 Self::MissingSection(id) => write!(f, "required section {} is missing", section_name(*id)),
86 Self::Malformed { section, offset, reason } => {
87 write!(f, "{section} is malformed at byte {offset}: {reason}")
88 }
89 }
90 }
91}
92
93impl std::error::Error for ModuleError {}