163 lines
4.5 KiB
Rust
163 lines
4.5 KiB
Rust
use crate::errors::Result;
|
|
use encoding_rs::WINDOWS_1252;
|
|
use std::fs;
|
|
use std::path::{Path, PathBuf};
|
|
mod btable;
|
|
mod dtable;
|
|
|
|
pub use btable::BTable;
|
|
pub use dtable::DTable;
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum TableType {
|
|
A,
|
|
B,
|
|
C,
|
|
D,
|
|
}
|
|
|
|
pub struct BUFRTable;
|
|
pub trait TableTrait {
|
|
fn file_path(table_type: TableType, sub_center: Option<u32>, table_version: u8) -> PathBuf;
|
|
}
|
|
|
|
impl BUFRTable {
|
|
pub fn file_path(table_type: TableType, table_version: u8) -> PathBuf {
|
|
let base_dir = Path::new("tables/bufr");
|
|
let file_name = match table_type {
|
|
TableType::A => format!("bufrtaba_{}.csv", table_version),
|
|
TableType::B => format!("bufrtabb_{}.csv", table_version),
|
|
TableType::C => format!("bufrtabc_{}.csv", table_version),
|
|
TableType::D => format!("bufrtabd_{}.csv", table_version),
|
|
};
|
|
base_dir.join(file_name)
|
|
}
|
|
}
|
|
|
|
pub struct LocalTable;
|
|
|
|
impl LocalTable {
|
|
pub fn file_path(table_type: TableType, sub_center: u32, table_version: u8) -> PathBuf {
|
|
let base_dir = Path::new("tables/local");
|
|
let file_name = match table_type {
|
|
TableType::A => format!("loctaba_{}_{}.csv", sub_center * 256, table_version),
|
|
TableType::B => format!("loctabb_{}_{}.csv", sub_center * 256, table_version),
|
|
TableType::C => format!("loctabc_{}_{}.csv", sub_center * 256, table_version),
|
|
TableType::D => format!("loctabd_{}_{}.csv", sub_center * 256, table_version),
|
|
};
|
|
base_dir.join(file_name)
|
|
}
|
|
}
|
|
|
|
impl TableTrait for BUFRTable {
|
|
fn file_path(table_type: TableType, sub_center: Option<u32>, table_version: u8) -> PathBuf {
|
|
BUFRTable::file_path(table_type, table_version)
|
|
}
|
|
}
|
|
|
|
impl TableTrait for LocalTable {
|
|
fn file_path(table_type: TableType, sub_center: Option<u32>, table_version: u8) -> PathBuf {
|
|
let sub_center = sub_center.expect("Sub-center must be provided for LocalTable");
|
|
LocalTable::file_path(table_type, sub_center, table_version)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct TableLoader<T: TableT> {
|
|
sequences: Vec<T::Seq>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum TT {
|
|
Localized(u32), // sub_center
|
|
Standard,
|
|
}
|
|
|
|
impl<T: TableT> TableLoader<T> {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
sequences: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn load_table(&mut self, table_type: TT, table_version: u8) -> Result<Vec<T::Seq>> {
|
|
let table_kind = T::table_type();
|
|
|
|
let local_table_path = match table_type {
|
|
TT::Localized(sc) => LocalTable::file_path(table_kind, sc, table_version),
|
|
TT::Standard => BUFRTable::file_path(table_kind, table_version),
|
|
};
|
|
|
|
// Here you would add code to actually load and parse the table from the file at `path`.
|
|
println!("Loading table from path: {:?}", local_table_path);
|
|
let raw = fs::read(&local_table_path)?;
|
|
|
|
let fixed = normalize_dashes(raw);
|
|
let text = decode_tabd_text(fixed);
|
|
|
|
let mut table = T::default();
|
|
|
|
for line in text.lines() {
|
|
if let Some(seq) = table.parse_line(line) {
|
|
self.sequences.push(seq);
|
|
}
|
|
}
|
|
|
|
if let Some(seq) = table.finish() {
|
|
self.sequences.push(seq);
|
|
}
|
|
|
|
let mut sequences = Vec::new();
|
|
std::mem::swap(&mut sequences, &mut self.sequences);
|
|
|
|
Ok(sequences)
|
|
}
|
|
}
|
|
|
|
fn normalize_dashes(mut bytes: Vec<u8>) -> Vec<u8> {
|
|
for b in &mut bytes {
|
|
match *b {
|
|
0x96 | 0x97 => *b = b'-', // EN / EM dash → '-'
|
|
_ => {}
|
|
}
|
|
}
|
|
bytes
|
|
}
|
|
|
|
fn decode_tabd_text(bytes: Vec<u8>) -> String {
|
|
let (text, _, _) = WINDOWS_1252.decode(&bytes);
|
|
text.into_owned()
|
|
}
|
|
|
|
pub trait TableT: Default {
|
|
type Seq;
|
|
|
|
fn table_type() -> TableType;
|
|
fn parse_line(&mut self, line: &str) -> Option<Self::Seq>;
|
|
fn finish(&mut self) -> Option<Self::Seq> {
|
|
None
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Descriptor {
|
|
pub f: i32,
|
|
pub x: i32,
|
|
pub y: i32,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use crate::discriptor_table::{TableLoader, btable::BTable, dtable::DTable};
|
|
|
|
#[test]
|
|
fn test_read_table() {
|
|
// let mut bufr_table: super::Table<super::BUFRTable> = super::Table::new();
|
|
let mut bufr_table = TableLoader::<BTable>::new();
|
|
bufr_table.load_table(super::TT::Standard, 11).unwrap();
|
|
|
|
println!("{:#?}", bufr_table.sequences);
|
|
}
|
|
}
|