Compare commits
9
Commits
a243b860d2
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e645bbcc08 | ||
|
|
70b2f1386d | ||
|
|
27559a8d31 | ||
|
|
f59b164095 | ||
|
|
e9a4f3de75 | ||
|
|
fbd47eba43 | ||
|
|
1a511523f4 | ||
|
|
c9ad723e79 | ||
|
|
5401d624bd |
@@ -24,3 +24,4 @@ bincode = { version = "2.0.0-rc.3", default-features = false, features = [
|
||||
simple_logger = "5.0.0"
|
||||
rp2040-hal = "0.10.2"
|
||||
rp2040-pac = "0.6.0"
|
||||
mio-serial = "=5.0.5"
|
||||
|
||||
@@ -41,7 +41,9 @@ impl App for Example {
|
||||
ExampleCmd::Noop => info!("NOOP command received"),
|
||||
ExampleCmd::Reset => {
|
||||
info!("RESET command received");
|
||||
let perf = self.data.hk.perf;
|
||||
self.data = Default::default();
|
||||
self.data.hk.perf = perf;
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
|
||||
@@ -5,7 +5,9 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rfe.path = "../../rfe"
|
||||
rfe.features = ["std"]
|
||||
rfe.features = ["std", "reflect"]
|
||||
anyhow.workspace = true
|
||||
simple_logger = "5.0.0"
|
||||
log.workspace = true
|
||||
egui = "0.30.0"
|
||||
eframe = "0.30.0"
|
||||
|
||||
+198
-11
@@ -1,30 +1,217 @@
|
||||
#![feature(thread_sleep_until)]
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
|
||||
|
||||
use std::{
|
||||
thread::sleep_until,
|
||||
collections::HashMap,
|
||||
thread::{sleep, spawn},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
use connector::{Connector, UdpConnector};
|
||||
use egui::{Layout, Ui};
|
||||
use log::*;
|
||||
use msg::Msg;
|
||||
use reflect::*;
|
||||
use rfe::macros::Reflect;
|
||||
use rfe::*;
|
||||
extern crate alloc;
|
||||
use simple_logger::SimpleLogger;
|
||||
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
struct TestStruct {
|
||||
counter: i8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
enum EnumTest {
|
||||
#[default]
|
||||
None,
|
||||
Test(TestStruct),
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
SimpleLogger::new()
|
||||
.with_level(LevelFilter::Debug)
|
||||
.init()
|
||||
.unwrap();
|
||||
|
||||
let mut udp = UdpConnector::new("127.0.0.1", 7011, "127.0.0.1", 7010)?;
|
||||
spawn(|| {
|
||||
let mut udp = UdpConnector::new("127.0.0.1", 7011, "127.0.0.1", 7010).unwrap();
|
||||
|
||||
let mut next_time = Instant::now() + Duration::from_millis(10);
|
||||
loop {
|
||||
sleep_until(next_time);
|
||||
let mut next_time = Instant::now() + Duration::from_millis(10);
|
||||
loop {
|
||||
sleep(next_time - Instant::now());
|
||||
|
||||
while let Some(msgs) = udp.recv() {
|
||||
for msg in msgs {
|
||||
info!("got msg {:?}", msg);
|
||||
while let Some(msgs) = udp.recv() {
|
||||
for msg in msgs {
|
||||
info!("got msg {:?}", msg);
|
||||
}
|
||||
}
|
||||
next_time += Duration::from_millis(10);
|
||||
}
|
||||
});
|
||||
|
||||
let options = eframe::NativeOptions {
|
||||
viewport: egui::ViewportBuilder::default().with_inner_size([560.0, 480.0]),
|
||||
..Default::default()
|
||||
};
|
||||
eframe::run_native(
|
||||
"RFE Ground",
|
||||
options,
|
||||
Box::new(|_cc| Ok(Box::<MyApp>::default())),
|
||||
)
|
||||
.or(Err(anyhow!("eframe failed")))?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
struct MyApp {
|
||||
command: Msg,
|
||||
values: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Default for MyApp {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
command: Msg::None,
|
||||
values: HashMap::new(),
|
||||
}
|
||||
next_time += Duration::from_millis(10);
|
||||
}
|
||||
}
|
||||
|
||||
fn build_command_ui_value_number(ui: &mut Ui, name: &str, cmd: &mut dyn Reflect) {
|
||||
let mut r = cmd.get_value().str();
|
||||
ui.with_layout(
|
||||
Layout::left_to_right(egui::Align::Min)
|
||||
.with_main_wrap(true)
|
||||
.with_main_justify(false),
|
||||
|ui| {
|
||||
ui.label(name);
|
||||
ui.text_edit_singleline(&mut r);
|
||||
cmd.set_value(ReflectValue::Str(r));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn build_command_ui(ui: &mut Ui, name: &str, cmd: &mut dyn Reflect) {
|
||||
// ui.separator();
|
||||
match cmd.reflect_type() {
|
||||
ReflectType::Value => match cmd.get_value() {
|
||||
ReflectValue::None => {}
|
||||
ReflectValue::U8(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::U16(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::U32(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::U64(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::I8(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::I16(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::I32(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::I64(_) => build_command_ui_value_number(ui, name, cmd),
|
||||
ReflectValue::Vec(_vec) => {
|
||||
ui.with_layout(Layout::top_down(egui::Align::Min), |ui| {
|
||||
ui.with_layout(
|
||||
Layout::left_to_right(egui::Align::Min).with_main_wrap(true),
|
||||
|ui| {
|
||||
ui.label(name);
|
||||
if ui.button("+").clicked() {
|
||||
cmd.vec_add();
|
||||
}
|
||||
if ui.button("-").clicked() {
|
||||
cmd.vec_remove();
|
||||
}
|
||||
},
|
||||
);
|
||||
if let Some(v) = cmd.as_vec() {
|
||||
ui.with_layout(
|
||||
Layout::left_to_right(egui::Align::Min).with_main_wrap(true),
|
||||
|ui| {
|
||||
for (i, cmd) in v.into_iter().enumerate() {
|
||||
build_command_ui(ui, &format!("[{i}]"), cmd);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
ReflectValue::Str(_) => {}
|
||||
ReflectValue::Bool(_) => {}
|
||||
},
|
||||
ReflectType::Enumeration => {
|
||||
// variants
|
||||
ui.with_layout(
|
||||
Layout::left_to_right(egui::Align::Min)
|
||||
.with_main_wrap(true)
|
||||
.with_main_justify(false),
|
||||
|ui| {
|
||||
for (i, (name, _v)) in cmd.variants().into_iter().enumerate() {
|
||||
if ui.button(name).clicked() {
|
||||
cmd.convert_variant(i);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// values
|
||||
if let Some((name, cmd)) = cmd.unwrap_variant() {
|
||||
build_command_ui(ui, name, cmd);
|
||||
}
|
||||
}
|
||||
ReflectType::Structure => {
|
||||
ui.with_layout(
|
||||
Layout::left_to_right(egui::Align::Min)
|
||||
.with_main_wrap(true)
|
||||
.with_main_justify(false),
|
||||
|ui| {
|
||||
for (name, cmd) in cmd.fields().into_iter() {
|
||||
build_command_ui(ui, name, cmd);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl eframe::App for MyApp {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading(format!("Command: {:?}", self.command));
|
||||
if ui.button("X").clicked() {
|
||||
self.command = Msg::None;
|
||||
}
|
||||
|
||||
build_command_ui(ui, "Msg", &mut self.command);
|
||||
|
||||
// if self
|
||||
// .command_path
|
||||
// .as_bytes()
|
||||
// .iter()
|
||||
// .filter(|x| **x == b'.')
|
||||
// .count()
|
||||
// >= 2
|
||||
// {
|
||||
// for item in &self.tree.get_add_path(&self.command_path).children {
|
||||
// for c in &item.children {
|
||||
// if c.is_last() {
|
||||
// if !self.values.contains_key(&c.name) {
|
||||
// self.values.insert(c.name.clone(), String::new());
|
||||
// }
|
||||
// let sref = self.values.get_mut(&c.name).unwrap();
|
||||
// ui.horizontal(|ui| {
|
||||
// ui.label(format!("{} : {}", item.name, c.name.clone()));
|
||||
// ui.text_edit_singleline(sref);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ui.button("send").clicked() {
|
||||
// info!("sending {}", self.command_path);
|
||||
// }
|
||||
// } else {
|
||||
// for item in &self.tree.get_add_path(&self.command_path).children {
|
||||
// if ui.button(item.name.clone()).clicked() {
|
||||
// self.command_path = format!("{}.{}", self.command_path, item.name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -8,6 +8,7 @@ embassy-usb-logger = { git = "https://github.com/embassy-rs/embassy.git" }
|
||||
rfe = { path = "../../rfe", default-features = false, features = ["rp2040"] }
|
||||
to = { path = "../../apps/to", default-features = false }
|
||||
hs = { path = "../../apps/hs", default-features = false, features = ["rp2040"] }
|
||||
example = { path = "../../apps/example" }
|
||||
anyhow.workspace = true
|
||||
anyhow.default_features = false
|
||||
embedded-alloc = "0.6.0"
|
||||
|
||||
@@ -15,10 +15,11 @@ mod app {
|
||||
usb::{self, Driver},
|
||||
};
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use example::Example;
|
||||
use fugit::Duration;
|
||||
use hs::{Hs, HsConfig, Rp2040Watchdog, StubSystemInfoGrabber};
|
||||
use log::info;
|
||||
use msg::{ExampleHk, Instance, MsgKind, MsgPacket, TargetMsg, TlmSetItem, ToTlmSet};
|
||||
use msg::{Instance, MsgKind, MsgPacket, TargetMsg, TlmSetItem, ToTlmSet};
|
||||
use rfe::{connector::Connector, Rate, *};
|
||||
use rp_pico::hal::{
|
||||
clocks,
|
||||
@@ -69,19 +70,13 @@ mod app {
|
||||
self.counter += 1;
|
||||
self.on = !self.on;
|
||||
if self.on {
|
||||
info!("led on!");
|
||||
self.led_pin.set_high().ok();
|
||||
} else {
|
||||
info!("led off!");
|
||||
self.led_pin.set_low().ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn hk(&mut self, rfe: &mut Rfe) {
|
||||
rfe.send(msg::Msg::ExampleHk(ExampleHk {
|
||||
counter: self.counter,
|
||||
}));
|
||||
}
|
||||
fn hk(&mut self, _rfe: &mut Rfe) {}
|
||||
|
||||
fn out_data(&mut self, _rfe: &mut Rfe) {}
|
||||
|
||||
@@ -198,7 +193,9 @@ mod app {
|
||||
},
|
||||
);
|
||||
let mut to = To::new(&mut log_connector, tlmsets);
|
||||
let mut example = Example::new();
|
||||
let mut wd = Rp2040Watchdog::new(ctx.local.wd.take().unwrap());
|
||||
|
||||
let mut grabber = StubSystemInfoGrabber::new();
|
||||
let mut hs = Hs::new(
|
||||
HsConfig {
|
||||
@@ -218,6 +215,7 @@ mod app {
|
||||
instance.add_app("blink_app", &mut blink_app).unwrap();
|
||||
instance.add_app("to", &mut to).unwrap();
|
||||
instance.add_app("hs", &mut hs).unwrap();
|
||||
instance.add_app("example", &mut example).unwrap();
|
||||
|
||||
let mut next_time = Mono::now() + Duration::<u64, 1, 1000000>::from_ticks(10000);
|
||||
|
||||
|
||||
+3
-2
@@ -5,9 +5,9 @@ edition = "2021"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
std = ["dep:mio"]
|
||||
std = ["dep:mio", "dep:mio-serial"]
|
||||
rp2040 = ["dep:rp2040-hal", "dep:rp2040-pac"]
|
||||
to_csv = []
|
||||
reflect = []
|
||||
|
||||
[dependencies]
|
||||
bincode.workspace = true
|
||||
@@ -18,3 +18,4 @@ mio = { version = "1.0.2", features = ["net", "os-poll"], optional = true }
|
||||
rp2040-hal = { workspace = true, optional = true }
|
||||
rp2040-pac = { workspace = true, optional = true }
|
||||
macros.path = "macros"
|
||||
mio-serial = { workspace = true, optional = true }
|
||||
|
||||
+168
-40
@@ -31,6 +31,25 @@ pub fn kind_derive(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
});
|
||||
|
||||
let kind_to_default_arms = variants.iter().map(|variant| {
|
||||
let variant_name = &variant.ident;
|
||||
match &variant.fields {
|
||||
Fields::Unit => {
|
||||
quote! {
|
||||
#kind_name::#variant_name => #name::#variant_name,
|
||||
}
|
||||
}
|
||||
Fields::Unnamed(_) => {
|
||||
quote! {
|
||||
#kind_name::#variant_name => #name::#variant_name(Default::default()),
|
||||
}
|
||||
}
|
||||
Fields::Named(_) => {
|
||||
panic!("Named fields not supported by Kind");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let kind_arms = variants.iter().map(|variant| {
|
||||
let variant_name = &variant.ident;
|
||||
match &variant.fields {
|
||||
@@ -51,9 +70,10 @@ pub fn kind_derive(input: TokenStream) -> TokenStream {
|
||||
});
|
||||
|
||||
let expanded = quote! {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub enum #kind_name {
|
||||
#[default]
|
||||
#(#kind_enum_arms)*
|
||||
}
|
||||
|
||||
@@ -63,6 +83,12 @@ pub fn kind_derive(input: TokenStream) -> TokenStream {
|
||||
#(#kind_enum_vec_arms)*
|
||||
]
|
||||
}
|
||||
|
||||
pub fn to_default(&self) -> #name {
|
||||
match self {
|
||||
#(#kind_to_default_arms)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl #name {
|
||||
@@ -77,8 +103,9 @@ pub fn kind_derive(input: TokenStream) -> TokenStream {
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(ToCsv)]
|
||||
pub fn to_csv_derive(input: TokenStream) -> TokenStream {
|
||||
|
||||
#[proc_macro_derive(Reflect)]
|
||||
pub fn reflect_derive(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
let name = input.ident;
|
||||
@@ -88,82 +115,183 @@ pub fn to_csv_derive(input: TokenStream) -> TokenStream {
|
||||
Data::Struct(data_struct) => {
|
||||
let fields = data_struct.fields;
|
||||
|
||||
let arms = fields.iter().map(|field| {
|
||||
let field_arms = fields.iter().map(|field| {
|
||||
let field_ident = field.clone().ident.unwrap();
|
||||
let field_name = field_ident.to_string();
|
||||
|
||||
quote! { {
|
||||
let mut field_csvs: alloc::vec::Vec<String> = (&self.#field_ident as &dyn ToCsv).to_csv();
|
||||
for entry in &mut field_csvs {
|
||||
*entry = format!("{}.{}", #field_name, &entry);
|
||||
}
|
||||
values.extend(field_csvs);
|
||||
fields.push((#field_name, &mut self.#field_ident as &mut dyn rfe::reflect::Reflect));
|
||||
} }
|
||||
});
|
||||
|
||||
quote! {
|
||||
impl ToCsv for #name {
|
||||
fn to_csv(&self) -> alloc::vec::Vec<String> {
|
||||
extern crate alloc;
|
||||
use alloc::format;
|
||||
impl rfe::reflect::Reflect for #name {
|
||||
fn reflect_type(&self) -> rfe::reflect::ReflectType {
|
||||
rfe::reflect::ReflectType::Structure
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
#name_s
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> alloc::vec::Vec<(&str, &mut dyn rfe::reflect::Reflect)> {
|
||||
let mut fields = alloc::vec::Vec::new();
|
||||
#(#field_arms)*
|
||||
fields
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: rfe::reflect::ReflectValue) {
|
||||
}
|
||||
|
||||
fn get_value(&self) -> rfe::reflect::ReflectValue {
|
||||
rfe::reflect::ReflectValue::None
|
||||
}
|
||||
|
||||
fn variants(&self) -> alloc::vec::Vec<(&'static str, alloc::boxed::Box<dyn rfe::reflect::Reflect>)> {
|
||||
alloc::vec::Vec::new()
|
||||
}
|
||||
|
||||
let mut values:alloc::vec::Vec<String> = alloc::vec::Vec::new();
|
||||
#(#arms)*
|
||||
for value in &mut values {
|
||||
*value = format!("{}", value);
|
||||
}
|
||||
return values;
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn rfe::reflect::Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<alloc::vec::Vec<&mut dyn rfe::reflect::Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Data::Enum(data_enum) => {
|
||||
let variants = data_enum.variants;
|
||||
let arms = variants.iter().map(|variant| {
|
||||
let convert_arms = variants.iter().enumerate().map(|(i, variant)| {
|
||||
let variant_name = &variant.ident;
|
||||
|
||||
match &variant.fields {
|
||||
Fields::Unit => {
|
||||
quote! {
|
||||
if _i == #i {
|
||||
*self = Self::#variant_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
Fields::Unnamed(_) => {
|
||||
quote! {
|
||||
if _i == #i {
|
||||
*self = Self::#variant_name(Default::default());
|
||||
}
|
||||
}
|
||||
}
|
||||
Fields::Named(_) => {
|
||||
panic!("Named fields not supported by Reflect");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let unwrap_arms = variants.iter().enumerate().map(|(_i, variant)| {
|
||||
let variant_name = &variant.ident;
|
||||
let variant_name_s = variant_name.to_string();
|
||||
|
||||
match &variant.fields {
|
||||
Fields::Unit => {
|
||||
quote! { Self::#variant_name => values.push(format!(" = {}::{}", #name_s, #variant_name_s)), }
|
||||
// quote! { Self::#variant_name => {}, }
|
||||
quote! {
|
||||
Self::#variant_name => None,
|
||||
}
|
||||
}
|
||||
Fields::Unnamed(_) => {
|
||||
quote! {Self::#variant_name(l) => {
|
||||
let mut field_csvs: alloc::vec::Vec<String> = (l as &dyn ToCsv).to_csv();
|
||||
for entry in &mut field_csvs {
|
||||
*entry = format!("{}.{}", #variant_name_s, &entry);
|
||||
}
|
||||
values.extend(field_csvs);
|
||||
},}
|
||||
quote! {
|
||||
Self::#variant_name(v) => Some((#variant_name_s, v)),
|
||||
}
|
||||
}
|
||||
Fields::Named(_) => {
|
||||
panic!("Named fields not supported by ToCsv");
|
||||
panic!("Named fields not supported by Reflect");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let variant_arms = variants.iter().map(|variant| {
|
||||
let variant_name = &variant.ident;
|
||||
let variant_name_s = variant_name.to_string();
|
||||
|
||||
match &variant.fields {
|
||||
Fields::Unit => {
|
||||
quote! {
|
||||
{
|
||||
let name: &'static str = #variant_name_s;
|
||||
let value: alloc::boxed::Box<dyn rfe::reflect::Reflect> = alloc::boxed::Box::new(Self::#variant_name);
|
||||
variants.push((name, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
Fields::Unnamed(_) => {
|
||||
quote! {
|
||||
{
|
||||
let name: &'static str = #variant_name_s;
|
||||
let value: alloc::boxed::Box<dyn rfe::reflect::Reflect> = alloc::boxed::Box::new(Self::#variant_name(Default::default()));
|
||||
variants.push((name, value));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Fields::Named(_) => {
|
||||
panic!("Named fields not supported by Reflect");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
impl ToCsv for #name {
|
||||
fn to_csv(&self) -> alloc::vec::Vec<String> {
|
||||
extern crate alloc;
|
||||
use alloc::format;
|
||||
let mut values: alloc::vec::Vec<String> = alloc::vec::Vec::new();
|
||||
impl rfe::reflect::Reflect for #name {
|
||||
fn reflect_type(&self) -> rfe::reflect::ReflectType {
|
||||
rfe::reflect::ReflectType::Enumeration
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
#name_s
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> alloc::vec::Vec<(&str, &mut dyn rfe::reflect::Reflect)> {
|
||||
alloc::vec::Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: rfe::reflect::ReflectValue) {
|
||||
}
|
||||
|
||||
fn get_value(&self) -> rfe::reflect::ReflectValue {
|
||||
rfe::reflect::ReflectValue::None
|
||||
}
|
||||
|
||||
fn variants(&self) -> alloc::vec::Vec<(&'static str, alloc::boxed::Box<dyn rfe::reflect::Reflect>)> {
|
||||
let mut variants = alloc::vec::Vec::new();
|
||||
#(#variant_arms)*
|
||||
variants
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {
|
||||
#(#convert_arms)*
|
||||
}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn rfe::reflect::Reflect)> {
|
||||
match self {
|
||||
#(#arms)*
|
||||
#(#unwrap_arms)*
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<alloc::vec::Vec<&mut dyn rfe::reflect::Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Data::Union(_data_union) => {
|
||||
return syn::Error::new_spanned(name, "ToCsv not implemented for unions")
|
||||
return syn::Error::new_spanned(name, "Reflect not implemented for unions")
|
||||
.to_compile_error()
|
||||
.into();
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -10,9 +10,11 @@ pub mod msg;
|
||||
mod rfe;
|
||||
pub use rfe::*;
|
||||
|
||||
#[cfg(feature = "to_csv")]
|
||||
pub mod to_csv;
|
||||
#[cfg(feature = "reflect")]
|
||||
pub mod reflect;
|
||||
|
||||
pub use macros;
|
||||
pub mod serial;
|
||||
pub mod time;
|
||||
pub mod utils;
|
||||
|
||||
|
||||
+10
-10
@@ -1,17 +1,16 @@
|
||||
#[cfg(feature = "to_csv")]
|
||||
use crate::to_csv::ToCsv;
|
||||
use crate::utils::PerfData;
|
||||
use bincode::{Decode, Encode};
|
||||
#[cfg(feature = "to_csv")]
|
||||
use macros::ToCsv;
|
||||
extern crate alloc;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use super::{TlmSetId, TlmSetItem};
|
||||
use crate as rfe;
|
||||
#[cfg(feature = "reflect")]
|
||||
use crate::macros::Reflect;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct DsTlmSet {
|
||||
pub items: Vec<TlmSetItem>,
|
||||
pub id: TlmSetId,
|
||||
@@ -20,23 +19,24 @@ pub struct DsTlmSet {
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct DsHk {
|
||||
pub perf: PerfData,
|
||||
pub counter: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct DsOutData {
|
||||
pub counter: u32,
|
||||
pub bytes_written: u32,
|
||||
pub bytes_written_this_cycle: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub enum DsCmd {
|
||||
#[default]
|
||||
Noop,
|
||||
Reset,
|
||||
CloseAll,
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "to_csv")]
|
||||
use crate::to_csv::ToCsv;
|
||||
use crate as rfe;
|
||||
#[cfg(feature = "reflect")]
|
||||
use crate::macros::Reflect;
|
||||
use crate::utils::PerfData;
|
||||
use bincode::{Decode, Encode};
|
||||
#[cfg(feature = "to_csv")]
|
||||
use macros::ToCsv;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct ExampleHk {
|
||||
pub perf: PerfData,
|
||||
pub counter: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct ExampleOutData {
|
||||
pub counter: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub enum ExampleCmd {
|
||||
#[default]
|
||||
Noop,
|
||||
Reset,
|
||||
}
|
||||
|
||||
+9
-8
@@ -1,14 +1,14 @@
|
||||
#[cfg(feature = "to_csv")]
|
||||
use crate::to_csv::ToCsv;
|
||||
use crate::utils::PerfData;
|
||||
use bincode::{Decode, Encode};
|
||||
#[cfg(feature = "to_csv")]
|
||||
use macros::ToCsv;
|
||||
|
||||
extern crate alloc;
|
||||
use crate as rfe;
|
||||
#[cfg(feature = "reflect")]
|
||||
use crate::macros::Reflect;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct HsHk {
|
||||
pub perf: PerfData,
|
||||
pub counter: u32,
|
||||
@@ -23,14 +23,15 @@ pub struct HsHk {
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct HsOutData {
|
||||
pub counter: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub enum HsCmd {
|
||||
#[default]
|
||||
Noop,
|
||||
Reset,
|
||||
WatchdogEnableManual(bool),
|
||||
|
||||
+20
-17
@@ -14,14 +14,13 @@ pub use to::*;
|
||||
mod ds;
|
||||
pub use ds::*;
|
||||
|
||||
use crate as rfe;
|
||||
#[cfg(feature = "reflect")]
|
||||
use crate::macros::Reflect;
|
||||
use crate::time::Timestamp;
|
||||
#[cfg(feature = "to_csv")]
|
||||
use crate::to_csv::ToCsv;
|
||||
#[cfg(feature = "to_csv")]
|
||||
use macros::ToCsv;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct TargetMsg {
|
||||
// instance is FROM for tlm, is TO for cmds
|
||||
pub instance: Instance,
|
||||
@@ -34,18 +33,21 @@ impl TargetMsg {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub enum Instance {
|
||||
#[default]
|
||||
None,
|
||||
All,
|
||||
Other,
|
||||
Example,
|
||||
Example2,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Kind, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Kind, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub enum Msg {
|
||||
#[default]
|
||||
None,
|
||||
SubRequest,
|
||||
SubList(SubList),
|
||||
@@ -66,7 +68,7 @@ pub enum Msg {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct MsgPacket {
|
||||
pub instance: Instance,
|
||||
pub msg: Msg,
|
||||
@@ -91,24 +93,25 @@ impl MsgPacket {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct SubList {
|
||||
pub subs: Vec<TargetMsg>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct ReinitAppCmd {
|
||||
app_name: String,
|
||||
}
|
||||
|
||||
pub type TlmSetId = u16;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct TlmSetItem {
|
||||
pub target: TargetMsg,
|
||||
/// decimation 0 means sends every msg, decimation 1 means sends every other, etc
|
||||
pub decimation: u16,
|
||||
pub counter: u16,
|
||||
}
|
||||
|
||||
+10
-10
@@ -1,16 +1,15 @@
|
||||
#[cfg(feature = "to_csv")]
|
||||
use crate::to_csv::ToCsv;
|
||||
use crate::utils::PerfData;
|
||||
use bincode::{Decode, Encode};
|
||||
#[cfg(feature = "to_csv")]
|
||||
use macros::ToCsv;
|
||||
extern crate alloc;
|
||||
use crate as rfe;
|
||||
#[cfg(feature = "reflect")]
|
||||
use crate::macros::Reflect;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use super::{TlmSetId, TlmSetItem};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct ToTlmSet {
|
||||
pub items: Vec<TlmSetItem>,
|
||||
pub id: TlmSetId,
|
||||
@@ -18,21 +17,22 @@ pub struct ToTlmSet {
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct ToHk {
|
||||
pub perf: PerfData,
|
||||
pub counter: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub struct ToOutData {
|
||||
pub counter: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
pub enum ToCmd {
|
||||
#[default]
|
||||
Noop,
|
||||
Reset,
|
||||
AddTlmSet(ToTlmSet),
|
||||
|
||||
@@ -0,0 +1,649 @@
|
||||
extern crate alloc;
|
||||
use core::mem::zeroed;
|
||||
use std::string::ToString;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use hashbrown::HashMap;
|
||||
|
||||
pub trait Reflect: std::fmt::Debug {
|
||||
fn reflect_type(&self) -> ReflectType;
|
||||
fn type_name(&self) -> &str;
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)>;
|
||||
fn set_value(&mut self, value: ReflectValue);
|
||||
fn get_value(&self) -> ReflectValue;
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)>;
|
||||
fn convert_variant(&mut self, i: usize);
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)>;
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>>;
|
||||
fn vec_add(&mut self) {}
|
||||
fn vec_remove(&mut self) {}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ReflectType {
|
||||
Value,
|
||||
Enumeration,
|
||||
Structure,
|
||||
}
|
||||
|
||||
pub enum ReflectValue {
|
||||
None,
|
||||
U8(u8),
|
||||
U16(u16),
|
||||
U32(u32),
|
||||
U64(u64),
|
||||
I8(i8),
|
||||
I16(i16),
|
||||
I32(i32),
|
||||
I64(i64),
|
||||
Vec(Vec<ReflectValue>),
|
||||
Str(String),
|
||||
Bool(bool),
|
||||
}
|
||||
|
||||
impl ReflectValue {
|
||||
pub fn signed(&self) -> i64 {
|
||||
match self {
|
||||
ReflectValue::None => 0,
|
||||
ReflectValue::U8(v) => *v as i64,
|
||||
ReflectValue::U16(v) => *v as i64,
|
||||
ReflectValue::U32(v) => *v as i64,
|
||||
ReflectValue::U64(v) => *v as i64,
|
||||
ReflectValue::I8(v) => *v as i64,
|
||||
ReflectValue::I16(v) => *v as i64,
|
||||
ReflectValue::I32(v) => *v as i64,
|
||||
ReflectValue::I64(v) => *v as i64,
|
||||
ReflectValue::Vec(_) => 0,
|
||||
ReflectValue::Str(s) => {
|
||||
if let Ok(v) = s.parse() {
|
||||
v
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
ReflectValue::Bool(b) => {
|
||||
if *b {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unsigned(&self) -> u64 {
|
||||
match self {
|
||||
ReflectValue::None => 0,
|
||||
ReflectValue::U8(v) => *v as u64,
|
||||
ReflectValue::U16(v) => *v as u64,
|
||||
ReflectValue::U32(v) => *v as u64,
|
||||
ReflectValue::U64(v) => *v as u64,
|
||||
ReflectValue::I8(v) => *v as u64,
|
||||
ReflectValue::I16(v) => *v as u64,
|
||||
ReflectValue::I32(v) => *v as u64,
|
||||
ReflectValue::I64(v) => *v as u64,
|
||||
ReflectValue::Vec(_) => 0,
|
||||
ReflectValue::Str(s) => {
|
||||
if let Ok(v) = s.parse() {
|
||||
v
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
ReflectValue::Bool(b) => {
|
||||
if *b {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn str(self) -> String {
|
||||
match self {
|
||||
ReflectValue::Str(s) => s,
|
||||
ReflectValue::None => "".to_string(),
|
||||
ReflectValue::U8(v) => v.to_string(),
|
||||
ReflectValue::U16(v) => v.to_string(),
|
||||
ReflectValue::U32(v) => v.to_string(),
|
||||
ReflectValue::U64(v) => v.to_string(),
|
||||
ReflectValue::I8(v) => v.to_string(),
|
||||
ReflectValue::I16(v) => v.to_string(),
|
||||
ReflectValue::I32(v) => v.to_string(),
|
||||
ReflectValue::I64(v) => v.to_string(),
|
||||
ReflectValue::Vec(_v) => "".to_string(),
|
||||
ReflectValue::Bool(v) => v.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bool(&self) -> bool {
|
||||
match self {
|
||||
ReflectValue::None => false,
|
||||
ReflectValue::U8(v) => *v == 0,
|
||||
ReflectValue::U16(v) => *v == 0,
|
||||
ReflectValue::U32(v) => *v == 0,
|
||||
ReflectValue::U64(v) => *v == 0,
|
||||
ReflectValue::I8(v) => *v == 0,
|
||||
ReflectValue::I16(v) => *v == 0,
|
||||
ReflectValue::I32(v) => *v == 0,
|
||||
ReflectValue::I64(v) => *v == 0,
|
||||
ReflectValue::Vec(_) => false,
|
||||
ReflectValue::Str(_) => false,
|
||||
ReflectValue::Bool(b) => *b,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vec(self) -> Vec<ReflectValue> {
|
||||
if let ReflectValue::Vec(v) = self {
|
||||
v
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn path_set(reflect: &mut dyn Reflect, path: &str, value: ReflectValue) {
|
||||
let mut next = reflect;
|
||||
for p in path.split(".") {
|
||||
let mut index = None;
|
||||
for (i, f) in next.fields().iter().enumerate() {
|
||||
if f.0 == p {
|
||||
index = Some(i);
|
||||
}
|
||||
}
|
||||
if let Some(i) = index {
|
||||
next = next.fields().remove(i).1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
next.set_value(value);
|
||||
}
|
||||
|
||||
pub fn path_get<'a>(reflect: &'a mut dyn Reflect, path: &str) -> Option<&'a mut dyn Reflect> {
|
||||
let mut next = reflect;
|
||||
for p in path.split(".") {
|
||||
let mut index = None;
|
||||
for (i, f) in next.fields().iter().enumerate() {
|
||||
if f.0 == p {
|
||||
index = Some(i);
|
||||
}
|
||||
}
|
||||
if let Some(i) = index {
|
||||
next = next.fields().remove(i).1;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(next)
|
||||
}
|
||||
|
||||
fn _flatten<'a>(reflect: &'a mut dyn Reflect) -> HashMap<String, &'a mut dyn Reflect> {
|
||||
let mut list = HashMap::new();
|
||||
|
||||
match reflect.reflect_type() {
|
||||
ReflectType::Value => match reflect.get_value() {
|
||||
ReflectValue::Vec(_) => {
|
||||
for (i, r) in reflect.as_vec().unwrap().into_iter().enumerate() {
|
||||
let map = _flatten(r);
|
||||
for (sn, v) in map {
|
||||
list.insert(alloc::format!("[{i}].{}", sn), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
list.insert("".to_string(), reflect);
|
||||
}
|
||||
},
|
||||
ReflectType::Enumeration => {
|
||||
if let Some((name, r)) = reflect.unwrap_variant() {
|
||||
let map = _flatten(r);
|
||||
for (sn, v) in map {
|
||||
list.insert(alloc::format!("{}.{}", name, sn), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
ReflectType::Structure => {
|
||||
for (name, r) in reflect.fields() {
|
||||
let map = _flatten(r);
|
||||
for (sn, v) in map {
|
||||
list.insert(alloc::format!("{}.{}", name, sn), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list
|
||||
}
|
||||
|
||||
pub fn flatten<'a>(reflect: &'a mut dyn Reflect) -> HashMap<String, &'a mut dyn Reflect> {
|
||||
_flatten(reflect)
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k[..k.len() - 1].to_string().replace(".[", "["), v))
|
||||
.collect()
|
||||
}
|
||||
|
||||
impl Reflect for u8 {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"u8"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.unsigned() as Self;
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::U8(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for u16 {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"u16"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.unsigned() as Self;
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::U16(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for u32 {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"u32"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.unsigned() as Self;
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::U32(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for u64 {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"u64"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.unsigned() as Self;
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::U64(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for i8 {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"i8"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.signed() as Self;
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::I8(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for i16 {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"i16"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.signed() as Self;
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::I16(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for i32 {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"i32"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.signed() as Self;
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::I32(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for i64 {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"i64"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.signed() as Self;
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::I64(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for String {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"str"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.str();
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::Str(self.to_string())
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for bool {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"bool"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
*self = value.bool();
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::Bool(*self)
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec(&mut self) -> Option<Vec<&mut dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflect + Default> Reflect for Vec<T> {
|
||||
fn reflect_type(&self) -> ReflectType {
|
||||
ReflectType::Value
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
"vec[]"
|
||||
}
|
||||
|
||||
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, value: ReflectValue) {
|
||||
if let ReflectValue::Vec(v) = value {
|
||||
*self = v
|
||||
.into_iter()
|
||||
.map(|x| {
|
||||
let mut t: T = unsafe { zeroed() };
|
||||
t.set_value(x);
|
||||
t
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
fn get_value(&self) -> ReflectValue {
|
||||
ReflectValue::Vec(self.iter().map(|x| x.get_value()).collect())
|
||||
}
|
||||
|
||||
fn variants(&self) -> Vec<(&'static str, Box<dyn Reflect>)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn convert_variant(&mut self, _i: usize) {}
|
||||
|
||||
fn unwrap_variant(&mut self) -> Option<(&str, &mut dyn Reflect)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_vec<'a>(&'a mut self) -> Option<Vec<&'a mut dyn Reflect>> {
|
||||
Some(
|
||||
self.iter_mut()
|
||||
.map(|x| {
|
||||
let v: &mut dyn Reflect = x;
|
||||
v
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn vec_add(&mut self) {
|
||||
self.push(Default::default());
|
||||
}
|
||||
|
||||
fn vec_remove(&mut self) {
|
||||
if self.len() > 0 {
|
||||
self.remove(self.len() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub trait SerialPort {
|
||||
fn open(&mut self) -> Result<()>;
|
||||
fn write(&mut self, bytes: &[u8]) -> Result<usize>;
|
||||
fn read(&mut self, bytes: &mut [u8]) -> Result<usize>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
mod serial_std {
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use mio_serial::{SerialPortBuilder, SerialPortBuilderExt, SerialStream};
|
||||
pub struct StdSerialPort {
|
||||
pub config: SerialPortBuilder,
|
||||
serial: Option<SerialStream>,
|
||||
}
|
||||
|
||||
impl StdSerialPort {
|
||||
pub fn new(config: SerialPortBuilder) -> Self {
|
||||
Self {
|
||||
config,
|
||||
serial: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::SerialPort for StdSerialPort {
|
||||
fn open(&mut self) -> anyhow::Result<()> {
|
||||
self.serial = None;
|
||||
self.serial = Some(self.config.clone().open_native_async()?);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn write(&mut self, bytes: &[u8]) -> anyhow::Result<usize> {
|
||||
Ok(self
|
||||
.serial
|
||||
.as_mut()
|
||||
.ok_or(anyhow!("port not open"))?
|
||||
.write(bytes)?)
|
||||
}
|
||||
|
||||
fn read(&mut self, bytes: &mut [u8]) -> anyhow::Result<usize> {
|
||||
Ok(self
|
||||
.serial
|
||||
.as_mut()
|
||||
.ok_or(anyhow!("port not open"))?
|
||||
.read(bytes)?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use serial_std::*;
|
||||
@@ -1,151 +0,0 @@
|
||||
extern crate alloc;
|
||||
use alloc::format;
|
||||
use alloc::string::String;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub trait ToCsv {
|
||||
fn to_csv(&self) -> Vec<String>;
|
||||
}
|
||||
|
||||
pub trait ToCsvClean {
|
||||
fn to_csv_clean(&self) -> Vec<String>;
|
||||
}
|
||||
|
||||
impl ToCsv for u8 {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for i8 {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for u16 {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for i16 {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for u32 {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for i32 {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for u64 {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for i64 {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for &str {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for String {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for bool {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
vec![format!(" = {}", self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToCsv> ToCsv for Vec<T> {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
self.iter()
|
||||
.enumerate()
|
||||
.map(|(i, x)| {
|
||||
x.to_csv()
|
||||
.iter()
|
||||
.map(|a| format!("[{}].{}", i, a))
|
||||
.collect::<Vec<String>>()
|
||||
})
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToCsv, const N: usize> ToCsv for [T; N] {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
self.iter()
|
||||
.enumerate()
|
||||
.map(|(i, x)| {
|
||||
x.to_csv()
|
||||
.iter()
|
||||
.map(|a| format!("[{}].{}", i, a))
|
||||
.collect::<Vec<String>>()
|
||||
})
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T1: ToCsv, T2: ToCsv> ToCsv for (T1, T2) {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
let mut csvs = Vec::new();
|
||||
csvs.extend(self.0.to_csv().iter().map(|x| format!("[0].{}", x)));
|
||||
csvs.extend(self.1.to_csv().iter().map(|x| format!("[1].{}", x)));
|
||||
csvs
|
||||
}
|
||||
}
|
||||
|
||||
impl<T1: ToCsv, T2: ToCsv, T3: ToCsv> ToCsv for (T1, T2, T3) {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
let mut csvs = Vec::new();
|
||||
csvs.extend(self.0.to_csv().iter().map(|x| format!("[0].{}", x)));
|
||||
csvs.extend(self.1.to_csv().iter().map(|x| format!("[1].{}", x)));
|
||||
csvs.extend(self.2.to_csv().iter().map(|x| format!("[2].{}", x)));
|
||||
csvs
|
||||
}
|
||||
}
|
||||
|
||||
impl<T1: ToCsv, T2: ToCsv, T3: ToCsv, T4: ToCsv> ToCsv for (T1, T2, T3, T4) {
|
||||
fn to_csv(&self) -> Vec<String> {
|
||||
let mut csvs = Vec::new();
|
||||
csvs.extend(self.0.to_csv().iter().map(|x| format!("[0].{}", x)));
|
||||
csvs.extend(self.1.to_csv().iter().map(|x| format!("[1].{}", x)));
|
||||
csvs.extend(self.2.to_csv().iter().map(|x| format!("[2].{}", x)));
|
||||
csvs.extend(self.3.to_csv().iter().map(|x| format!("[3].{}", x)));
|
||||
csvs
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToCsv> ToCsvClean for T {
|
||||
fn to_csv_clean(&self) -> Vec<String> {
|
||||
self.to_csv().iter().map(|x| to_csv_clean(x)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn to_csv_clean(s: &String) -> String {
|
||||
let s = s.replace(".[", "[");
|
||||
let s = s.replace(". =", " =");
|
||||
s
|
||||
}
|
||||
+6
-5
@@ -3,13 +3,14 @@ use crate::Rfe;
|
||||
use bincode::{Decode, Encode};
|
||||
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "to_csv")]
|
||||
use crate::to_csv::ToCsv;
|
||||
#[cfg(feature = "to_csv")]
|
||||
use macros::ToCsv;
|
||||
|
||||
use crate as rfe;
|
||||
#[cfg(feature = "reflect")]
|
||||
use crate::macros::Reflect;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Encode, Decode)]
|
||||
#[cfg_attr(feature = "to_csv", derive(ToCsv))]
|
||||
#[cfg_attr(feature = "reflect", derive(Reflect))]
|
||||
|
||||
pub struct PerfData {
|
||||
enter_time: Timestamp,
|
||||
elapsed: u32,
|
||||
|
||||
@@ -11,5 +11,5 @@ path = "src/decom.rs"
|
||||
anyhow.workspace = true
|
||||
log.workspace = true
|
||||
simple_logger.workspace = true
|
||||
rfe = { path = "../../rfe", features = ["to_csv"] }
|
||||
rfe = { path = "../../rfe", features = ["reflect"] }
|
||||
bincode = { workspace = true, features = ["std"] }
|
||||
|
||||
@@ -12,7 +12,6 @@ use std::{
|
||||
use anyhow::Result;
|
||||
use bincode::decode_from_std_read;
|
||||
use log::*;
|
||||
use rfe::ToCsvClean;
|
||||
use rfe::{msg::MsgPacket, BINCODE_CONFIG};
|
||||
use simple_logger::SimpleLogger;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user