1#![allow(
6 clippy::module_name_repetitions,
7 clippy::similar_names,
8 clippy::missing_errors_doc,
9 clippy::missing_panics_doc,
10 clippy::option_if_let_else,
11 clippy::cast_sign_loss,
12 clippy::cast_possible_truncation
13)]
14
15pub mod builder;
16pub mod elem_type;
17pub mod formula;
18pub mod interface;
19pub mod parser;
20pub mod store;
21
22mod boolean;
23mod category;
24mod command;
25mod converter;
26mod enumeration;
27mod float;
28mod float_reg;
29mod int_converter;
30mod int_reg;
31mod int_swiss_knife;
32mod integer;
33mod ivalue;
34mod masked_int_reg;
35mod node;
36mod node_base;
37mod port;
38mod register;
39mod register_base;
40mod register_description;
41mod string;
42mod string_reg;
43mod swiss_knife;
44mod utils;
45
46pub use boolean::BooleanNode;
47pub use category::CategoryNode;
48pub use command::CommandNode;
49pub use converter::ConverterNode;
50pub use enumeration::{EnumEntryNode, EnumerationNode};
51pub use float::FloatNode;
52pub use float_reg::FloatRegNode;
53pub use int_converter::IntConverterNode;
54pub use int_reg::IntRegNode;
55pub use int_swiss_knife::IntSwissKnifeNode;
56pub use integer::IntegerNode;
57pub use masked_int_reg::MaskedIntRegNode;
58pub use node::Node;
59pub use node_base::NodeBase;
60pub use port::PortNode;
61pub use register::RegisterNode;
62pub use register_base::RegisterBase;
63pub use register_description::RegisterDescription;
64pub use store::{CacheStore, NodeId, NodeStore, ValueStore};
65pub use string::StringNode;
66pub use string_reg::StringRegNode;
67pub use swiss_knife::SwissKnifeNode;
68
69use std::borrow::Cow;
70
71use auto_impl::auto_impl;
72use tracing::error;
73
74pub mod prelude {
75 pub use super::interface::{
76 IBoolean, ICategory, ICommand, IEnumeration, IFloat, IInteger, INode, IPort, IRegister,
77 ISelector, IString,
78 };
79}
80
81#[auto_impl(&mut, Box)]
82pub trait Device {
83 fn read_mem(
84 &mut self,
85 address: i64,
86 buf: &mut [u8],
87 ) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
88
89 fn write_mem(
90 &mut self,
91 address: i64,
92 data: &[u8],
93 ) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
94}
95
96#[derive(Debug, thiserror::Error)]
97pub enum GenApiError {
98 #[error("device I/O error: {0}")]
99 Device(Box<dyn std::error::Error + Send + Sync>),
100
101 #[error("attempt to write a value to non writable node")]
103 NotWritable,
104
105 #[error("invalid node: {0}")]
107 InvalidNode(Cow<'static, str>),
108
109 #[error("invalid data: {0}")]
113 InvalidData(Cow<'static, str>),
114
115 #[error("chunk data missing")]
117 ChunkDataMissing,
118
119 #[error("invalid buffer: {0}")]
121 InvalidBuffer(Cow<'static, str>),
122}
123
124impl GenApiError {
125 fn device(inner: Box<dyn std::error::Error + Send + Sync>) -> Self {
126 let err = GenApiError::Device(inner);
127 error!("{}", err);
128 err
129 }
130
131 fn not_writable() -> Self {
132 let err = GenApiError::NotWritable;
133 error!("{}", err);
134 err
135 }
136
137 fn invalid_node(inner: Cow<'static, str>) -> Self {
138 let err = GenApiError::InvalidNode(inner);
139 error!("{}", err);
140 err
141 }
142
143 fn invalid_data(inner: Cow<'static, str>) -> Self {
144 let err = GenApiError::InvalidData(inner);
145 error!("{}", err);
146 err
147 }
148
149 fn chunk_data_missing() -> Self {
150 let err = GenApiError::ChunkDataMissing;
151 error!("{}", err);
152 err
153 }
154
155 fn invalid_buffer(inner: Cow<'static, str>) -> Self {
156 let err = GenApiError::InvalidBuffer(inner);
157 error!("{}", err);
158 err
159 }
160}
161
162pub type GenApiResult<T> = std::result::Result<T, GenApiError>;
163
164#[derive(Clone, Debug)]
165pub struct ValueCtxt<T, U> {
166 pub value_store: T,
167 pub cache_store: U,
168}
169
170impl<T, U> ValueCtxt<T, U> {
171 pub fn new(value_store: T, cache_store: U) -> Self {
172 Self {
173 value_store,
174 cache_store,
175 }
176 }
177
178 pub fn value_store(&self) -> &T {
179 &self.value_store
180 }
181
182 pub fn value_store_mut(&mut self) -> &mut T {
183 &mut self.value_store
184 }
185
186 pub fn cache_store(&mut self) -> &U
187 where
188 T: store::ValueStore,
189 U: store::CacheStore,
190 {
191 &self.cache_store
192 }
193
194 pub fn cache_store_mut(&mut self) -> &mut U {
195 &mut self.cache_store
196 }
197
198 pub fn cache_data(&mut self, nid: store::NodeId, address: i64, length: i64, value: &[u8])
199 where
200 U: store::CacheStore,
201 {
202 self.cache_store.cache(nid, address, length, value);
203 }
204
205 pub fn get_cache(&self, nid: store::NodeId, address: i64, length: i64) -> Option<&[u8]>
206 where
207 U: store::CacheStore,
208 {
209 self.cache_store.get_cache(nid, address, length)
210 }
211
212 pub fn invalidate_cache_by(&mut self, nid: store::NodeId)
213 where
214 U: store::CacheStore,
215 {
216 self.cache_store.invalidate_by(nid)
217 }
218
219 pub fn invalidate_cache_of(&mut self, nid: store::NodeId)
220 where
221 U: store::CacheStore,
222 {
223 self.cache_store.invalidate_of(nid)
224 }
225
226 pub fn clear_cache(&mut self)
227 where
228 U: store::CacheStore,
229 {
230 self.cache_store.clear()
231 }
232}