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