jeff/reader/value.rs
1//! "Values" represent wire types in the jeff language with associated metadata.
2//!
3//! There are two types of values:
4//!
5//! - [`WireValue`]s that correspond to typed hyperedges in dataflow regions.
6//! - [`FunctionIOValue`]s, describing the inputs and outputs of a function.
7//!
8//! All regions inside a function share a single [`ValueTable`] listing all the
9//! hyperedges in the function. These are indexed by their [`ValueId`]s.
10
11mod function_io;
12mod wire_value;
13
14pub use function_io::FunctionIOValue;
15pub use wire_value::WireValue;
16
17use crate::capnp::jeff_capnp;
18
19use super::string_table::StringTable;
20use super::ReadError;
21
22/// The ID of a value hyperedge in the function's value table.
23pub type ValueId = u32;
24
25/// Table of values / typed hyperedges contained in a function.
26#[derive(Clone, Copy, Debug)]
27pub struct ValueTable<'a> {
28 /// Internal capnproto value table.
29 values: capnp::struct_list::Reader<'a, jeff_capnp::value::Owned>,
30 /// Module-level register of reused strings.
31 strings: StringTable<'a>,
32}
33
34impl<'a> ValueTable<'a> {
35 /// Create a new value table view from a capnp reader.
36 pub(crate) fn read_capnp(
37 values: capnp::struct_list::Reader<'a, jeff_capnp::value::Owned>,
38 strings: StringTable<'a>,
39 ) -> Self {
40 Self { values, strings }
41 }
42
43 /// Returns the wire value at the given index.
44 ///
45 /// # Errors
46 ///
47 /// - [`ReadError::ValueOutOfBounds`] if the index is out of bounds.
48 pub fn get(&self, idx: ValueId) -> Result<WireValue<'a>, ReadError> {
49 let value = self
50 .values
51 .try_get(idx)
52 .ok_or_else(|| ReadError::ValueOutOfBounds {
53 idx,
54 count: self.len(),
55 })?;
56
57 Ok(WireValue::read_capnp(idx, value, self.strings))
58 }
59
60 /// Returns an iterator over the wire values in this table.
61 pub fn iter(&self) -> impl Iterator<Item = (ValueId, WireValue<'a>)> + '_ {
62 self.values.iter().enumerate().map(move |(idx, value)| {
63 (
64 idx as ValueId,
65 WireValue::read_capnp(idx as ValueId, value, self.strings),
66 )
67 })
68 }
69
70 /// Returns the number of strings in this table.
71 pub fn len(&self) -> usize {
72 self.values.len() as usize
73 }
74
75 /// Returns `true` if the table is empty.
76 pub fn is_empty(&self) -> bool {
77 self.values.len() == 0
78 }
79}