sat-rs/satrs-mib/src/res_code.rs

170 lines
5.0 KiB
Rust
Raw Normal View History

2022-11-27 22:30:38 +01:00
#[cfg(feature = "std")]
pub use stdmod::*;
2022-11-27 22:05:42 +01:00
pub use satrs_shared::res_code::ResultU16;
2022-11-27 22:30:38 +01:00
2022-11-27 22:05:42 +01:00
use serde::{Deserialize, Serialize};
use serde_hex::{SerHex, StrictCapPfx};
#[derive(Debug, Copy, Clone, Serialize)]
pub struct ResultU16Info {
pub name: &'static str,
pub result: &'static ResultU16,
pub group_str: &'static str,
pub info: &'static str,
}
impl ResultU16Info {
pub const fn const_new(
name: &'static str,
result: &'static ResultU16,
group_str: &'static str,
info: &'static str,
) -> Self {
Self {
name,
result,
group_str,
info,
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ResultU16InfoSerializable {
#[serde(with = "SerHex::<StrictCapPfx>")]
raw: u16,
#[serde(with = "SerHex::<StrictCapPfx>")]
group_id: u8,
#[serde(with = "SerHex::<StrictCapPfx>")]
unique_id: u8,
name: &'static str,
group_str: &'static str,
info: &'static str,
}
impl From<ResultU16Info> for ResultU16InfoSerializable {
fn from(v: ResultU16Info) -> Self {
Self {
raw: v.result.raw(),
group_id: v.result.group_id(),
unique_id: v.result.unique_id(),
name: v.name,
group_str: v.group_str,
info: v.info,
}
}
}
2022-11-27 22:30:38 +01:00
#[cfg(feature = "std")]
pub mod stdmod {
use super::*;
2022-12-04 20:00:57 +01:00
use std::fs::File;
2022-11-27 22:32:10 +01:00
use std::io;
2022-11-27 22:30:38 +01:00
2022-12-04 20:00:57 +01:00
pub fn print_resultcodes_as_csv(
writer_builder: csv::WriterBuilder,
codes: &[ResultU16Info],
) -> Result<(), csv::Error> {
2022-11-27 22:44:40 +01:00
let mut wtr = writer_builder.from_writer(io::stdout());
2022-11-27 22:32:10 +01:00
for result in codes {
wtr.serialize(ResultU16InfoSerializable::from(*result))?;
}
wtr.flush()?;
Ok(())
2022-11-27 22:05:42 +01:00
}
2024-02-12 18:10:33 +01:00
/// This function exports a slice of result code information objects to a CSV file.
2022-11-27 22:32:10 +01:00
pub fn write_resultcodes_to_csv(
2022-11-27 22:44:40 +01:00
writer_builder: csv::WriterBuilder,
2022-11-27 22:32:10 +01:00
results: &[ResultU16Info],
2022-11-27 22:44:40 +01:00
file: File,
2022-11-27 22:32:10 +01:00
) -> Result<(), csv::Error> {
2022-11-27 22:44:40 +01:00
let mut wtr = writer_builder.from_writer(file);
2022-11-27 22:32:10 +01:00
for result_code in results {
wtr.serialize(ResultU16InfoSerializable::from(*result_code))?;
}
wtr.flush()?;
Ok(())
2022-11-27 22:05:42 +01:00
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::io::{BufRead, BufReader};
2022-11-27 22:32:10 +01:00
use std::path::Path;
2022-11-27 22:05:42 +01:00
// Special solution for this crate because the code generated by a macro will use
// satrs_mib::res_code::*
use crate as satrs_mib;
2022-11-27 22:30:38 +01:00
use satrs_mib::resultcode;
use satrs_shared::res_code::ResultU16;
2022-11-27 22:05:42 +01:00
#[derive(Debug)]
#[allow(dead_code)]
pub enum GroupId {
Tmtc = 0,
}
#[resultcode]
pub const INVALID_PUS_SERVICE: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 0);
2022-11-27 22:05:42 +01:00
#[resultcode]
pub const INVALID_PUS_SUBSERVICE: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 1);
2022-11-27 22:05:42 +01:00
#[resultcode(info = "Not enough data inside the TC application data field")]
pub const NOT_ENOUGH_APP_DATA: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 2);
2022-11-27 22:05:42 +01:00
pub const TMTC_RESULTS: &[ResultU16Info] = &[
INVALID_PUS_SERVICE_EXT,
INVALID_PUS_SUBSERVICE_EXT,
NOT_ENOUGH_APP_DATA_EXT,
];
const CSV_NAME: &str = "dummy.csv";
2022-11-27 22:05:42 +01:00
#[test]
fn test_printout() {
2022-11-27 22:44:40 +01:00
let mut wtrb = csv::WriterBuilder::new();
wtrb.delimiter(b';');
2022-11-27 22:44:40 +01:00
print_resultcodes_as_csv(wtrb, TMTC_RESULTS).expect("Priting result codes failed");
2022-11-27 22:05:42 +01:00
}
#[test]
fn test_csv_export() {
let csvpath = Path::new(CSV_NAME);
2022-11-27 22:44:40 +01:00
let mut wtrb = csv::WriterBuilder::new();
let file = File::create(csvpath).expect("Creating CSV file failed");
wtrb.delimiter(b';');
2022-11-27 22:44:40 +01:00
write_resultcodes_to_csv(wtrb, TMTC_RESULTS, file).expect("CSV export failed");
2022-11-27 22:05:42 +01:00
assert!(csvpath.exists());
let file = File::open(csvpath).expect("Opening CSV file failed");
let buf_reader = BufReader::new(file);
for (idx, line) in buf_reader.lines().enumerate() {
match idx {
0 => {
assert!(line.is_ok());
let line = line.unwrap();
2022-11-27 22:44:40 +01:00
assert_eq!(line, "raw;group_id;unique_id;name;group_str;info");
2022-11-27 22:05:42 +01:00
}
1 => {
assert!(line.is_ok());
let line = line.unwrap();
2022-11-27 22:44:40 +01:00
assert_eq!(line, "0x0000;0x00;0x00;INVALID_PUS_SERVICE;;");
2022-11-27 22:05:42 +01:00
}
2 => {
assert!(line.is_ok());
let line = line.unwrap();
2022-11-27 22:44:40 +01:00
assert_eq!(line, "0x0001;0x00;0x01;INVALID_PUS_SUBSERVICE;;");
2022-11-27 22:05:42 +01:00
}
3 => {
assert!(line.is_ok());
let line = line.unwrap();
2022-11-27 22:44:40 +01:00
assert_eq!(line, "0x0002;0x00;0x02;NOT_ENOUGH_APP_DATA;;Not enough data inside the TC application data field");
2022-11-27 22:05:42 +01:00
}
_ => (),
}
}
std::fs::remove_file(Path::new("dummy.csv")).expect("Removing dummy csv failed");
}
}