1use crate::capnp::jeff_capnp;
3
4use super::function::FunctionId;
5use super::metadata::sealed::HasMetadataSealed;
6use super::string_table::StringTable;
7use super::Function;
8
9#[derive(Clone, Copy, Debug)]
11pub struct Module<'a> {
12 module: jeff_capnp::module::Reader<'a>,
14}
15
16impl<'a> Module<'a> {
17 pub(crate) fn read_capnp(module: jeff_capnp::module::Reader<'a>) -> Self {
19 Self { module }
20 }
21
22 pub fn version(&self) -> semver::Version {
24 let major = self.module.get_version() as u64;
25 let minor = self.module.get_version_minor() as u64;
26 let patch = self.module.get_version_patch() as u64;
27 semver::Version::new(major, minor, patch)
28 }
29
30 fn functions_reader(&self) -> capnp::struct_list::Reader<'a, jeff_capnp::function::Owned> {
32 self.module
33 .get_functions()
34 .expect("Functions should be present")
35 }
36
37 pub fn functions(&self) -> impl Iterator<Item = Function<'a>> {
39 let string_table = self.strings();
40 self.functions_reader()
41 .iter()
42 .map(move |f| Function::read_capnp(f, string_table))
43 }
44
45 pub fn function_count(&self) -> usize {
47 self.functions_reader().len() as usize
48 }
49
50 pub fn function(&self, n: FunctionId) -> Function<'a> {
56 Function::read_capnp(self.functions_reader().get(n), self.strings())
57 }
58
59 pub fn try_function(&self, n: FunctionId) -> Option<Function<'a>> {
61 let f = self.functions_reader().try_get(n)?;
62 Some(Function::read_capnp(f, self.strings()))
63 }
64
65 pub fn strings(&self) -> StringTable<'a> {
67 StringTable::read_capnp(
68 self.module
69 .get_strings()
70 .expect("Strings should be present"),
71 )
72 }
73
74 pub fn entrypoint_id(&self) -> FunctionId {
76 self.module.get_entrypoint() as FunctionId
77 }
78
79 pub fn entrypoint(&self) -> Function<'a> {
85 self.functions().nth(self.entrypoint_id() as usize).unwrap()
86 }
87
88 pub fn tool(&self) -> &str {
92 self.module
93 .get_tool()
94 .ok()
95 .and_then(|r| r.to_str().ok())
96 .unwrap_or("")
97 }
98
99 pub fn tool_version(&self) -> &str {
103 self.module
104 .get_tool_version()
105 .ok()
106 .and_then(|r| r.to_str().ok())
107 .unwrap_or("")
108 }
109}
110
111impl<'a> HasMetadataSealed for Module<'a> {
112 fn strings(&self) -> StringTable<'a> {
113 self.strings()
114 }
115
116 fn metadata_reader(&self) -> capnp::struct_list::Reader<'a, jeff_capnp::meta::Owned> {
117 self.module
118 .get_metadata()
119 .expect("Metadata should be present")
120 }
121}