From cf933a89def7c86f8f17c5c6764f12b1c6dc6e56 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:29:34 +0200 Subject: [PATCH] add proper sorting --- Cargo.lock | 2 ++ stm32-data-serde/Cargo.toml | 2 ++ stm32-data-serde/src/lib.rs | 52 ++++++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 422156a..32449e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -620,6 +620,8 @@ version = "0.1.0" dependencies = [ "itertools", "rayon", + "ref_thread_local", + "regex", "serde", "serde_json", ] diff --git a/stm32-data-serde/Cargo.toml b/stm32-data-serde/Cargo.toml index ebab5d8..4968317 100644 --- a/stm32-data-serde/Cargo.toml +++ b/stm32-data-serde/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" [dependencies] serde = { version = "1.0.157", features = ["derive"] } +regex = "1.7.1" +ref_thread_local = "0.1.1" [dev-dependencies] itertools = "0.10.5" diff --git a/stm32-data-serde/src/lib.rs b/stm32-data-serde/src/lib.rs index 39d8638..b95a3b1 100644 --- a/stm32-data-serde/src/lib.rs +++ b/stm32-data-serde/src/lib.rs @@ -1,5 +1,15 @@ use serde::{Deserialize, Serialize}; +#[macro_export] +macro_rules! regex { + ($re:literal) => {{ + ::ref_thread_local::ref_thread_local! { + static managed REGEX: ::regex::Regex = ::regex::Regex::new($re).unwrap(); + } + >::borrow(®EX) + }}; +} + #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct Chip { pub name: String, @@ -121,7 +131,7 @@ pub mod chip { } } - #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] + #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] pub struct Pin { pub pin: String, pub signal: String, @@ -129,6 +139,46 @@ pub mod chip { pub af: Option, } + fn extract_port_and_pin(pin: &str) -> (char, u8) { + let captures = regex!(r"^P([A-Z])(\d+)(?:_C)?") + .captures(pin) + .expect("Could not match regex on pin"); + let port = captures + .get(1) + .expect("Could not extract port") + .as_str() + .chars() + .next() + .expect("Empty port"); + let pin_number = captures + .get(2) + .expect("Could not extract pin number") + .as_str() + .parse::() + .expect("Could not parse pin number to u8"); + (port, pin_number) + } + + impl Ord for Pin { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + let (port_a, pin_number_a) = extract_port_and_pin(&self.pin); + let (port_b, pin_number_b) = extract_port_and_pin(&other.pin); + + if port_a != port_b { + port_a.cmp(&port_b) + } else if pin_number_a != pin_number_b { + pin_number_a.cmp(&pin_number_b) + } else { + self.signal.cmp(&other.signal) + } + } + } + impl PartialOrd for Pin { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct Interrupt { pub signal: String,