1use super::{
6 elem_type::{Endianness, IntegerRepresentation, Sign},
7 interface::{IInteger, INode, IRegister, ISelector, IncrementMode},
8 node_base::{NodeAttributeBase, NodeBase},
9 register_base::RegisterBase,
10 store::{CacheStore, NodeId, NodeStore, ValueStore},
11 utils, Device, GenApiError, GenApiResult, ValueCtxt,
12};
13
14#[derive(Debug, Clone)]
15pub struct IntRegNode {
16 pub(crate) attr_base: NodeAttributeBase,
17 pub(crate) register_base: RegisterBase,
18
19 pub(crate) sign: Sign,
20 pub(crate) endianness: Endianness,
21 pub(crate) unit: Option<String>,
22 pub(crate) representation: IntegerRepresentation,
23 pub(crate) p_selected: Vec<NodeId>,
24}
25
26impl IntRegNode {
27 #[must_use]
28 pub fn register_base(&self) -> &RegisterBase {
29 &self.register_base
30 }
31
32 #[must_use]
33 pub fn sign(&self) -> Sign {
34 self.sign
35 }
36
37 #[must_use]
38 pub fn endianness(&self) -> Endianness {
39 self.endianness
40 }
41
42 #[must_use]
43 pub fn unit_elem(&self) -> Option<&str> {
44 self.unit.as_deref()
45 }
46
47 #[must_use]
48 pub fn representation_elem(&self) -> IntegerRepresentation {
49 self.representation
50 }
51
52 #[must_use]
53 pub fn p_selected(&self) -> &[NodeId] {
54 &self.p_selected
55 }
56}
57
58impl INode for IntRegNode {
59 fn node_base(&self) -> NodeBase {
60 let elem_base = &self.register_base.elem_base;
61 NodeBase::new(&self.attr_base, elem_base)
62 }
63
64 fn streamable(&self) -> bool {
65 self.register_base().streamable()
66 }
67}
68
69impl IInteger for IntRegNode {
70 #[tracing::instrument(skip(self, device, store, cx),
71 level = "trace",
72 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
73 fn value<T: ValueStore, U: CacheStore>(
74 &self,
75 device: &mut impl Device,
76 store: &impl NodeStore,
77 cx: &mut ValueCtxt<T, U>,
78 ) -> GenApiResult<i64> {
79 let nid = self.node_base().id();
80 let reg = self.register_base();
81 reg.with_cache_or_read(nid, device, store, cx, |data| {
82 utils::int_from_slice(data, self.endianness, self.sign)
83 })
84 }
85
86 #[tracing::instrument(skip(self, device, store, cx),
87 level = "trace",
88 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
89 fn set_value<T: ValueStore, U: CacheStore>(
90 &self,
91 value: i64,
92 device: &mut impl Device,
93 store: &impl NodeStore,
94 cx: &mut ValueCtxt<T, U>,
95 ) -> GenApiResult<()> {
96 let nid = self.node_base().id();
97 cx.invalidate_cache_by(nid);
98
99 let reg = self.register_base();
100 let len = reg.length(device, store, cx)?;
101 let mut buf = vec![0; len as usize];
102 utils::bytes_from_int(value, &mut buf, self.endianness, self.sign)?;
103 reg.write_and_cache(nid, &buf, device, store, cx)?;
104 Ok(())
105 }
106
107 fn min<T: ValueStore, U: CacheStore>(
108 &self,
109 _: &mut impl Device,
110 _: &impl NodeStore,
111 _: &mut ValueCtxt<T, U>,
112 ) -> GenApiResult<i64> {
113 match self.sign {
114 Sign::Signed => Ok(i64::MIN),
115 Sign::Unsigned => Ok(0),
116 }
117 }
118
119 fn max<T: ValueStore, U: CacheStore>(
120 &self,
121 _: &mut impl Device,
122 _: &impl NodeStore,
123 _: &mut ValueCtxt<T, U>,
124 ) -> GenApiResult<i64> {
125 Ok(i64::MAX)
126 }
127
128 fn inc_mode(&self, _: &impl NodeStore) -> Option<IncrementMode> {
129 None
130 }
131
132 fn inc<T: ValueStore, U: CacheStore>(
133 &self,
134 _: &mut impl Device,
135 _: &impl NodeStore,
136 _: &mut ValueCtxt<T, U>,
137 ) -> GenApiResult<Option<i64>> {
138 Ok(None)
139 }
140
141 fn valid_value_set(&self, _: &impl NodeStore) -> &[i64] {
142 &[]
143 }
144
145 fn representation(&self, _: &impl NodeStore) -> IntegerRepresentation {
146 self.representation_elem()
147 }
148
149 fn unit(&self, _: &impl NodeStore) -> Option<&str> {
150 self.unit_elem()
151 }
152
153 #[tracing::instrument(skip(self, store),
154 level = "trace",
155 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
156 fn set_min<T: ValueStore, U: CacheStore>(
157 &self,
158 _: i64,
159 _: &mut impl Device,
160 store: &impl NodeStore,
161 _: &mut ValueCtxt<T, U>,
162 ) -> GenApiResult<()> {
163 Err(GenApiError::not_writable())
164 }
165
166 #[tracing::instrument(skip(self, store),
167 level = "trace",
168 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
169 fn set_max<T: ValueStore, U: CacheStore>(
170 &self,
171 _: i64,
172 _: &mut impl Device,
173 store: &impl NodeStore,
174 _: &mut ValueCtxt<T, U>,
175 ) -> GenApiResult<()> {
176 Err(GenApiError::not_writable())
177 }
178
179 fn is_readable<T: ValueStore, U: CacheStore>(
180 &self,
181 device: &mut impl Device,
182 store: &impl NodeStore,
183 cx: &mut ValueCtxt<T, U>,
184 ) -> GenApiResult<bool> {
185 self.register_base().is_readable(device, store, cx)
186 }
187
188 fn is_writable<T: ValueStore, U: CacheStore>(
189 &self,
190 device: &mut impl Device,
191 store: &impl NodeStore,
192 cx: &mut ValueCtxt<T, U>,
193 ) -> GenApiResult<bool> {
194 self.register_base().is_writable(device, store, cx)
195 }
196}
197
198impl IRegister for IntRegNode {
199 fn read<T: ValueStore, U: CacheStore>(
200 &self,
201 buf: &mut [u8],
202 device: &mut impl Device,
203 store: &impl NodeStore,
204 cx: &mut ValueCtxt<T, U>,
205 ) -> GenApiResult<()> {
206 let address = self.address(device, store, cx)?;
207 let length = self.length(device, store, cx)?;
208 self.register_base().read_and_cache(
209 self.node_base().id(),
210 address,
211 length,
212 buf,
213 device,
214 store,
215 cx,
216 )
217 }
218
219 fn write<T: ValueStore, U: CacheStore>(
220 &self,
221 buf: &[u8],
222 device: &mut impl Device,
223 store: &impl NodeStore,
224 cx: &mut ValueCtxt<T, U>,
225 ) -> GenApiResult<()> {
226 self.register_base()
227 .write_and_cache(self.node_base().id(), buf, device, store, cx)
228 }
229
230 fn address<T: ValueStore, U: CacheStore>(
231 &self,
232 device: &mut impl Device,
233 store: &impl NodeStore,
234 cx: &mut ValueCtxt<T, U>,
235 ) -> GenApiResult<i64> {
236 self.register_base().address(device, store, cx)
237 }
238
239 fn length<T: ValueStore, U: CacheStore>(
240 &self,
241 device: &mut impl Device,
242 store: &impl NodeStore,
243 cx: &mut ValueCtxt<T, U>,
244 ) -> GenApiResult<i64> {
245 self.register_base().length(device, store, cx)
246 }
247}
248
249impl ISelector for IntRegNode {
250 fn selecting_nodes(&self, _: &impl NodeStore) -> GenApiResult<&[NodeId]> {
251 Ok(self.p_selected())
252 }
253}