1use crate::capnp::jeff_capnp;
3use crate::reader::Value;
4
5use super::metadata::sealed::HasMetadataSealed;
6use super::string_table::StringTable;
7use super::{ReadError, Region, ValueTable};
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<Value<'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(&self) -> impl Iterator<Item = Result<Value<'a>, ReadError>> + '_ {
104 match self {
105 Function::Declaration(decl) => itertools::Either::Left(decl.output_types()),
106 Function::Definition(def) => itertools::Either::Right(def.output_types()),
107 }
108 }
109}
110
111impl<'a> FunctionDefinition<'a> {
112 pub fn name(&self) -> &str {
118 self.strings
119 .get(self.function.get_name(), "function name")
120 .expect("Invalid function name definition")
121 }
122
123 pub fn body(&self) -> Region<'a> {
125 Region::read_capnp(self.body, self.strings, self.values())
126 }
127
128 pub fn values(&self) -> ValueTable<'a> {
130 self.values
131 }
132
133 pub fn input_types(&self) -> impl Iterator<Item = Result<Value<'a>, ReadError>> + 'a {
135 self.body().sources()
136 }
137
138 pub fn output_types(&self) -> impl Iterator<Item = Result<Value<'a>, ReadError>> + 'a {
140 self.body().targets()
141 }
142}
143
144impl<'a> FunctionDeclaration<'a> {
145 pub fn name(&self) -> &str {
151 self.strings
152 .get(self.function.get_name(), "function name")
153 .expect("Invalid function name definition")
154 }
155
156 pub fn input_types(&self) -> impl Iterator<Item = Result<Value<'a>, ReadError>> + '_ {
158 self.inputs
159 .iter()
160 .map(move |value| Ok(Value::read_capnp(None, value, self.strings)))
161 }
162
163 pub fn output_types(&self) -> impl Iterator<Item = Result<Value<'a>, ReadError>> + '_ {
165 self.outputs
166 .iter()
167 .map(move |value| Ok(Value::read_capnp(None, value, self.strings)))
168 }
169}
170
171impl<'a> HasMetadataSealed for Function<'a> {
172 fn strings(&self) -> StringTable<'a> {
173 match self {
174 Function::Declaration(decl) => decl.strings,
175 Function::Definition(def) => def.strings,
176 }
177 }
178
179 fn metadata_reader(&self) -> capnp::struct_list::Reader<'_, jeff_capnp::meta::Owned> {
180 match self {
181 Function::Declaration(decl) => decl.metadata_reader(),
182 Function::Definition(def) => def.metadata_reader(),
183 }
184 }
185}
186
187impl<'a> HasMetadataSealed for FunctionDeclaration<'a> {
188 fn strings(&self) -> StringTable<'a> {
189 self.strings
190 }
191
192 fn metadata_reader(&self) -> capnp::struct_list::Reader<'_, jeff_capnp::meta::Owned> {
193 self.function
194 .get_metadata()
195 .expect("Metadata should be present")
196 }
197}
198
199impl<'a> HasMetadataSealed for FunctionDefinition<'a> {
200 fn strings(&self) -> StringTable<'a> {
201 self.strings
202 }
203
204 fn metadata_reader(&self) -> capnp::struct_list::Reader<'_, jeff_capnp::meta::Owned> {
205 self.function
206 .get_metadata()
207 .expect("Metadata should be present")
208 }
209}