-
Notifications
You must be signed in to change notification settings - Fork 0
feat: #760 polish — metadata, ranked alternatives, dead code cleanup #791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1960cda
f2e21eb
b48a573
5e18f41
ab20fcb
b33c845
fd51763
a3ce2ed
72685b1
0d83917
1273f4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2248,6 +2248,32 @@ pub struct DiscoveredPort { | |
| pub direction: String, | ||
| pub binding: Option<String>, | ||
| pub connected: bool, | ||
| /// Port metadata (always includes display_name; HID ports add manufacturer, vendor_id, product_id) | ||
| #[serde(default)] | ||
| pub metadata: std::collections::HashMap<String, String>, | ||
|
Comment on lines
+2251
to
+2253
|
||
| } | ||
|
|
||
| /// Extract metadata from a port name. Strips OS-appended instance suffixes | ||
| /// (" #2", " Port 3") while preserving model numbers (e.g., "nanoKONTROL2"). | ||
| fn port_metadata(name: &str) -> std::collections::HashMap<String, String> { | ||
| let mut meta = std::collections::HashMap::new(); | ||
| let base = if let Some((prefix, suffix)) = name.rsplit_once(" #") { | ||
| if suffix.chars().all(|c| c.is_ascii_digit()) { | ||
| prefix | ||
| } else { | ||
| name | ||
| } | ||
| } else if let Some((prefix, suffix)) = name.rsplit_once(" Port ") { | ||
| if suffix.chars().all(|c| c.is_ascii_digit()) { | ||
| prefix | ||
| } else { | ||
| name | ||
| } | ||
| } else { | ||
| name | ||
| }; | ||
| meta.insert("display_name".to_string(), base.to_string()); | ||
| meta | ||
| } | ||
|
|
||
| /// Get all discovered ports across protocols with binding status (ADR-022 Phase 2A) | ||
|
|
@@ -2281,12 +2307,14 @@ pub fn get_discovered_ports() -> Result<Vec<DiscoveredPort>, String> { | |
| }) | ||
| .map(|d| d.alias.clone()) | ||
| }); | ||
| let metadata = port_metadata(&name); | ||
| ports.push(DiscoveredPort { | ||
| name, | ||
| protocol: "midi".to_string(), | ||
| direction: "receive".to_string(), | ||
| binding, | ||
| connected: true, | ||
| metadata, | ||
| }); | ||
| } | ||
| } | ||
|
|
@@ -2308,12 +2336,14 @@ pub fn get_discovered_ports() -> Result<Vec<DiscoveredPort>, String> { | |
| }) | ||
| .map(|d| d.alias.clone()) | ||
| }); | ||
| let metadata = port_metadata(&name); | ||
| ports.push(DiscoveredPort { | ||
| name, | ||
| protocol: "midi".to_string(), | ||
| direction: "send".to_string(), | ||
| binding, | ||
| connected: true, | ||
| metadata, | ||
| }); | ||
| } | ||
| } | ||
|
|
@@ -2348,12 +2378,19 @@ pub fn get_discovered_ports() -> Result<Vec<DiscoveredPort>, String> { | |
| }) | ||
| .map(|d| d.alias.clone()) | ||
| }); | ||
| let mut metadata = port_metadata(name); | ||
| if let Some(mfg) = device_info.manufacturer_string() { | ||
| metadata.insert("manufacturer".to_string(), mfg.to_string()); | ||
| } | ||
| metadata.insert("vendor_id".to_string(), format!("0x{:04X}", vid)); | ||
| metadata.insert("product_id".to_string(), format!("0x{:04X}", pid)); | ||
| ports.push(DiscoveredPort { | ||
| name: name.to_string(), | ||
| protocol: "hid".to_string(), | ||
| direction: "receive".to_string(), | ||
| binding, | ||
| connected: true, | ||
| metadata, | ||
| }); | ||
| } | ||
| } | ||
|
|
@@ -2750,4 +2787,34 @@ mod tests { | |
| .contains("must be within the midimon config directory") | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_port_metadata_preserves_model_numbers() { | ||
| let meta = port_metadata("nanoKONTROL2"); | ||
| assert_eq!(meta["display_name"], "nanoKONTROL2"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_port_metadata_strips_instance_suffix() { | ||
| let meta = port_metadata("Maschine Mikro MK3 #2"); | ||
| assert_eq!(meta["display_name"], "Maschine Mikro MK3"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_port_metadata_strips_port_suffix() { | ||
| let meta = port_metadata("USB MIDI Port 3"); | ||
| assert_eq!(meta["display_name"], "USB MIDI"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_port_metadata_no_suffix() { | ||
| let meta = port_metadata("Launchpad Mini MK3 MIDI"); | ||
| assert_eq!(meta["display_name"], "Launchpad Mini MK3 MIDI"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_port_metadata_preserves_apc40() { | ||
| let meta = port_metadata("APC40"); | ||
| assert_eq!(meta["display_name"], "APC40"); | ||
| } | ||
| } | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
alternativesassertions only cover cases where the primary confidence is > 0 (e.g., names that match the heuristic seeds). It would be good to add a regression test for an “unknown/insufficient data” port name (primary confidence 0.0) to ensure alternatives are either omitted or never exceed the primary confidence.