1use crate::capnp::jeff_capnp;
3use crate::reader::value::{FunctionIOValue, ValueTable};
4
5use super::metadata::sealed::HasMetadataSealed;
6use super::string_table::StringTable;
7use super::{ReadError, Region};
8
9pub type FunctionId = u32;
11
12#[derive(Clone, Copy, Debug)]
14pub enum Function<'a> {
15 Definition(FunctionDefinition<'a>),
17 Declaration(FunctionDeclaration<'a>),
19}
20
21#[derive(Clone, Copy, Debug)]
23pub struct FunctionDefinition<'a> {
24 function: jeff_capnp::function::Reader<'a>,
26 body: jeff_capnp::region::Reader<'a>,
28 values: ValueTable<'a>,
30 strings: StringTable<'a>,
32}
33
34#[derive(Clone, Copy, Debug)]
36pub struct FunctionDeclaration<'a> {
37 function: jeff_capnp::function::Reader<'a>,
39 inputs: capnp::struct_list::Reader<'a, jeff_capnp::value::Owned>,
41 outputs: capnp::struct_list::Reader<'a, jeff_capnp::value::Owned>,
43 strings: StringTable<'a>,
45}
46
47impl<'a> Function<'a> {
48 pub(crate) fn read_capnp(
50 function: jeff_capnp::function::Reader<'a>,
51 strings: StringTable<'a>,
52 ) -> Self {
53 match function.which().expect("Function should be valid") {
54 jeff_capnp::function::Which::Definition(def) => {
55 let body = def.get_body().expect("Body should be present");
56 let values = ValueTable::read_capnp(
57 def.get_values().expect("Values should be present"),
58 strings,
59 );
60 let def = FunctionDefinition {
61 function,
62 body,
63 values,
64 strings,
65 };
66 Self::Definition(def)
67 }
68 jeff_capnp::function::Which::Declaration(decl) => {
69 let inputs = decl.get_inputs().expect("Inputs should be present");
70 let outputs = decl.get_outputs().expect("Outputs should be present");
71 let decl = FunctionDeclaration {
72 function,
73 inputs,
74 outputs,
75 strings,
76 };
77 Self::Declaration(decl)
78 }
79 }
80 }
81
82 pub fn name(&self) -> &str {
88 match self {
89 Function::Declaration(decl) => decl.name(),
90 Function::Definition(def) => def.name(),
91 }
92 }
93
94 pub fn input_types(&self) -> impl Iterator<Item = Result<FunctionIOValue<'a>, ReadError>> + '_ {
96 match self {
97 Function::Declaration(decl) => itertools::Either::Left(decl.input_types()),
98 Function::Definition(def) => itertools::Either::Right(def.input_types()),
99 }
100 }
101
102 pub fn output_types(
104 &self,
105 ) -> impl Iterator<Item = Result<FunctionIOValue<'a>, ReadError>> + '_ {
106 match self {
107 Function::Declaration(decl) => itertools::Either::Left(decl.output_types()),
108 Function::Definition(def) => itertools::Either::Right(def.output_types()),
109 }
110 }
111}
112
113impl<'a> FunctionDefinition<'a> {
114 pub fn name(&self) -> &str {
120 self.strings
121 .get(self.function.get_name(), "function name")
122 .expect("Invalid function name definition")
123 }
124
125 pub fn body(&self) -> Region<'a> {
127 Region::read_capnp(self.body, self.strings, self.values())
128 }
129
130 pub fn values(&self) -> ValueTable<'a> {
132 self.values
133 }
134
135 pub fn input_types(&self) -> impl Iterator<Item = Result<FunctionIOValue<'a>, ReadError>> + 'a {
137 self.body().sources().map(|v| Ok(v?.into()))
138 }
139
140 pub fn output_types(
142 &self,
143 ) -> impl Iterator<Item = Result<FunctionIOValue<'a>, ReadError>> + 'a {
144 self.body().targets().map(|v| Ok(v?.into()))
145 }
146}
147
148impl<'a> FunctionDeclaration<'a> {
149 pub fn name(&self) -> &str {
155 self.strings
156 .get(self.function.get_name(), "function name")
157 .expect("Invalid function name definition")
158 }
159
160 pub fn input_types(&self) -> impl Iterator<Item = Result<FunctionIOValue<'a>, ReadError>> + '_ {
162 self.inputs
163 .iter()
164 .map(move |value| Ok(FunctionIOValue::read_capnp(value, self.strings)))
165 }
166
167 pub fn output_types(
169 &self,
170 ) -> impl Iterator<Item = Result<FunctionIOValue<'a>, ReadError>> + '_ {
171 self.outputs
172 .iter()
173 .map(move |value| Ok(FunctionIOValue::read_capnp(value, self.strings)))
174 }
175}
176
177impl<'a> HasMetadataSealed for Function<'a> {
178 fn strings(&self) -> StringTable<'a> {
179 match self {
180 Function::Declaration(decl) => decl.strings,
181 Function::Definition(def) => def.strings,
182 }
183 }
184
185 fn metadata_reader(&self) -> capnp::struct_list::Reader<'_, jeff_capnp::meta::Owned> {
186 match self {
187 Function::Declaration(decl) => decl.metadata_reader(),
188 Function::Definition(def) => def.metadata_reader(),
189 }
190 }
191}
192
193impl<'a> HasMetadataSealed for FunctionDeclaration<'a> {
194 fn strings(&self) -> StringTable<'a> {
195 self.strings
196 }
197
198 fn metadata_reader(&self) -> capnp::struct_list::Reader<'_, jeff_capnp::meta::Owned> {
199 self.function
200 .get_metadata()
201 .expect("Metadata should be present")
202 }
203}
204
205impl<'a> HasMetadataSealed for FunctionDefinition<'a> {
206 fn strings(&self) -> StringTable<'a> {
207 self.strings
208 }
209
210 fn metadata_reader(&self) -> capnp::struct_list::Reader<'_, jeff_capnp::meta::Owned> {
211 self.function
212 .get_metadata()
213 .expect("Metadata should be present")
214 }
215}