1use crate::capnp::jeff_capnp;
3use crate::reader::value::{ValueTable, WireValue};
4use crate::Direction;
5
6use super::metadata::sealed::HasMetadataSealed;
7use super::op::Operation;
8use super::string_table::StringTable;
9use super::value::ValueId;
10use super::ReadError;
11
12#[derive(Clone, Copy, Debug)]
14pub struct Region<'a> {
15 region: jeff_capnp::region::Reader<'a>,
17 strings: StringTable<'a>,
19 values: ValueTable<'a>,
21}
22
23impl<'a> Region<'a> {
24 pub(crate) fn read_capnp(
26 region: jeff_capnp::region::Reader<'a>,
27 strings: StringTable<'a>,
28 values: ValueTable<'a>,
29 ) -> Self {
30 Self {
31 region,
32 strings,
33 values,
34 }
35 }
36
37 pub fn boundary(
43 &self,
44 direction: Direction,
45 ) -> impl Iterator<Item = Result<WireValue<'a>, ReadError>> {
46 let value_table = self.values;
47 let values = match direction {
48 Direction::Incoming => self.region.get_sources(),
49 Direction::Outgoing => self.region.get_targets(),
50 }
51 .expect("Boundary should be present");
52 values.iter().map(move |idx| value_table.get(idx))
53 }
54
55 pub fn sources(&self) -> impl Iterator<Item = Result<WireValue<'a>, ReadError>> {
61 self.boundary(Direction::Incoming)
62 }
63
64 pub fn targets(&self) -> impl Iterator<Item = Result<WireValue<'a>, ReadError>> {
70 self.boundary(Direction::Outgoing)
71 }
72
73 pub fn boundary_count(&self, direction: Direction) -> usize {
75 match direction {
76 Direction::Incoming => self.region.get_sources(),
77 Direction::Outgoing => self.region.get_targets(),
78 }
79 .expect("Boundary should be present")
80 .len() as usize
81 }
82
83 pub fn source_count(&self) -> usize {
85 self.boundary_count(Direction::Incoming)
86 }
87
88 pub fn target_count(&self) -> usize {
90 self.boundary_count(Direction::Outgoing)
91 }
92
93 pub fn boundary_value(
100 &self,
101 direction: Direction,
102 idx: usize,
103 ) -> Option<Result<WireValue<'a>, ReadError>> {
104 let values = match direction {
105 Direction::Incoming => self.region.get_sources(),
106 Direction::Outgoing => self.region.get_targets(),
107 }
108 .expect("Boundary should be present");
109 if idx >= values.len() as usize {
110 return None;
111 }
112 Some(self.values.get(values.get(idx as ValueId)))
113 }
114
115 pub fn source(&self, idx: usize) -> Option<Result<WireValue<'a>, ReadError>> {
122 self.boundary_value(Direction::Incoming, idx)
123 }
124
125 pub fn target(&self, idx: usize) -> Option<Result<WireValue<'a>, ReadError>> {
132 self.boundary_value(Direction::Outgoing, idx)
133 }
134
135 pub fn operations(&self) -> impl Iterator<Item = Operation<'a>> {
137 let strings_table = self.strings;
138 let value_table = self.values;
139 self.region
140 .get_operations()
141 .expect("Ops should be present")
142 .iter()
143 .map(move |op| Operation::read_capnp(op, strings_table, value_table))
144 }
145
146 pub fn operation_count(&self) -> usize {
148 self.region
149 .get_operations()
150 .expect("Ops should be present")
151 .len() as usize
152 }
153
154 pub fn operation(&self, n: usize) -> Operation<'a> {
160 Operation::read_capnp(
161 self.region
162 .get_operations()
163 .expect("Ops should be present")
164 .get(n as u32),
165 self.strings,
166 self.values,
167 )
168 }
169}
170
171impl<'a> HasMetadataSealed for Region<'a> {
172 fn strings(&self) -> StringTable<'a> {
173 self.strings
174 }
175
176 fn metadata_reader(&self) -> capnp::struct_list::Reader<'a, jeff_capnp::meta::Owned> {
177 self.region
178 .get_metadata()
179 .expect("Metadata should be present")
180 }
181}