#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(dead_code)]
use crate::ported::hashtable::{Hashtable, Hashtable_foreach, Hashtable_get};
use crate::ported::object::{Object, ObjectClass, Object_class};
pub struct DynamicScreen {
pub name: String,
pub heading: Option<String>,
pub columnKeys: Option<String>,
pub direction: i32,
}
static DynamicScreen_class: ObjectClass = ObjectClass {
extends: Some(&Object_class),
};
impl Object for DynamicScreen {
fn klass(&self) -> &'static ObjectClass {
&DynamicScreen_class
}
}
pub struct DynamicIterator<'a> {
pub name: &'a str,
pub key: u32,
pub found: bool,
}
pub fn DynamicScreen_compare(key: u32, value: &DynamicScreen, iter: &mut DynamicIterator) {
if iter.name == value.name {
iter.found = true;
iter.key = key;
}
}
pub fn DynamicScreens_new() {
todo!("port of DynamicScreen.c:22: needs Platform_dynamicScreens (unported Platform layer)")
}
pub fn DynamicScreens_delete() {
todo!("port of DynamicScreen.c:26: needs Platform_dynamicScreensDone (unported Platform layer); Hashtable_delete is itself a Drop-based stub")
}
pub fn DynamicScreen_done(this: DynamicScreen) {
let _ = this;
}
pub fn DynamicScreen_search(
screens: Option<&Hashtable>,
name: &str,
key: Option<&mut u32>,
) -> bool {
let mut iter = DynamicIterator {
key: 0,
name,
found: false,
};
if let Some(screens) = screens {
Hashtable_foreach(screens, &mut |k, value| {
let any: &dyn core::any::Any = value;
let screen = any
.downcast_ref::<DynamicScreen>()
.expect("value is a DynamicScreen");
DynamicScreen_compare(k, screen, &mut iter);
});
}
if let Some(key) = key {
*key = iter.key;
}
iter.found
}
pub fn DynamicScreen_lookup(screens: &Hashtable, key: u32) -> Option<&str> {
Hashtable_get(screens, key).map(|value| {
let any: &dyn core::any::Any = value;
any.downcast_ref::<DynamicScreen>()
.expect("value is a DynamicScreen")
.name
.as_str()
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ported::hashtable::{Hashtable_new, Hashtable_put};
fn screen(name: &str) -> DynamicScreen {
DynamicScreen {
name: name.to_string(),
heading: None,
columnKeys: None,
direction: 1,
}
}
#[test]
fn compare_records_match_and_key() {
let cpu = screen("cpu");
let mut iter = DynamicIterator {
name: "cpu",
key: 0,
found: false,
};
DynamicScreen_compare(7, &cpu, &mut iter);
assert!(iter.found);
assert_eq!(iter.key, 7);
}
#[test]
fn compare_ignores_non_match() {
let mem = screen("mem");
let mut iter = DynamicIterator {
name: "cpu",
key: 0,
found: false,
};
DynamicScreen_compare(3, &mem, &mut iter);
assert!(!iter.found);
assert_eq!(iter.key, 0);
}
#[test]
fn compare_is_exact_case_sensitive_strcmp() {
let upper = screen("CPU");
let mut iter = DynamicIterator {
name: "cpu",
key: 0,
found: false,
};
DynamicScreen_compare(9, &upper, &mut iter);
assert!(!iter.found);
assert_eq!(iter.key, 0);
}
#[test]
fn compare_last_match_wins() {
let a = screen("dup");
let b = screen("dup");
let mut iter = DynamicIterator {
name: "dup",
key: 0,
found: false,
};
DynamicScreen_compare(1, &a, &mut iter);
DynamicScreen_compare(2, &b, &mut iter);
assert!(iter.found);
assert_eq!(iter.key, 2);
}
fn registry(entries: &[(u32, &str)]) -> Hashtable {
let mut ht = Hashtable_new(0, true);
for &(k, name) in entries {
Hashtable_put(&mut ht, k, Box::new(screen(name)));
}
ht
}
#[test]
fn search_finds_entry_and_writes_key() {
let ht = registry(&[(11, "cpu"), (22, "mem"), (33, "disk")]);
let mut key = 0u32;
let found = DynamicScreen_search(Some(&ht), "mem", Some(&mut key));
assert!(found);
assert_eq!(key, 22);
}
#[test]
fn search_absent_name_returns_false_and_zero_key() {
let ht = registry(&[(11, "cpu"), (22, "mem")]);
let mut key = 999u32;
let found = DynamicScreen_search(Some(&ht), "gpu", Some(&mut key));
assert!(!found);
assert_eq!(key, 0);
}
#[test]
fn search_null_key_out_param_is_ignored() {
let ht = registry(&[(5, "cpu")]);
assert!(DynamicScreen_search(Some(&ht), "cpu", None));
assert!(!DynamicScreen_search(Some(&ht), "nope", None));
}
#[test]
fn search_none_registry_returns_false() {
let mut key = 42u32;
let found = DynamicScreen_search(None, "cpu", Some(&mut key));
assert!(!found);
assert_eq!(key, 0);
}
#[test]
fn search_is_case_sensitive() {
let ht = registry(&[(7, "CPU")]);
assert!(!DynamicScreen_search(Some(&ht), "cpu", None));
assert!(DynamicScreen_search(Some(&ht), "CPU", None));
}
#[test]
fn lookup_returns_name_for_key() {
let ht = registry(&[(11, "cpu"), (22, "mem"), (33, "disk")]);
assert_eq!(DynamicScreen_lookup(&ht, 11), Some("cpu"));
assert_eq!(DynamicScreen_lookup(&ht, 22), Some("mem"));
assert_eq!(DynamicScreen_lookup(&ht, 33), Some("disk"));
}
#[test]
fn lookup_absent_key_returns_none() {
let ht = registry(&[(11, "cpu")]);
assert_eq!(DynamicScreen_lookup(&ht, 999), None);
}
#[test]
fn search_then_lookup_roundtrip() {
let ht = registry(&[(100, "cpu"), (200, "mem"), (300, "net")]);
let mut key = 0u32;
assert!(DynamicScreen_search(Some(&ht), "net", Some(&mut key)));
assert_eq!(key, 300);
assert_eq!(DynamicScreen_lookup(&ht, key), Some("net"));
}
}