#![allow(dead_code)]
use std::collections::HashMap;
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq)]
pub enum PropertyValue {
Int(i64),
Float(f64),
Text(String),
Bool(bool),
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct PropertyMap {
entries: HashMap<String, PropertyValue>,
}
#[allow(dead_code)]
pub fn new_property_map() -> PropertyMap {
PropertyMap {
entries: HashMap::new(),
}
}
#[allow(dead_code)]
pub fn set_property(map: &mut PropertyMap, key: &str, value: PropertyValue) {
map.entries.insert(key.to_string(), value);
}
#[allow(dead_code)]
pub fn get_property<'a>(map: &'a PropertyMap, key: &str) -> Option<&'a PropertyValue> {
map.entries.get(key)
}
#[allow(dead_code)]
pub fn has_property(map: &PropertyMap, key: &str) -> bool {
map.entries.contains_key(key)
}
#[allow(dead_code)]
pub fn property_count(map: &PropertyMap) -> usize {
map.entries.len()
}
#[allow(dead_code)]
pub fn remove_property(map: &mut PropertyMap, key: &str) -> Option<PropertyValue> {
map.entries.remove(key)
}
#[allow(dead_code)]
pub fn property_keys(map: &PropertyMap) -> Vec<String> {
let mut keys: Vec<String> = map.entries.keys().cloned().collect();
keys.sort();
keys
}
#[allow(dead_code)]
pub fn properties_to_json(map: &PropertyMap) -> String {
let mut parts: Vec<String> = Vec::new();
let mut keys: Vec<&String> = map.entries.keys().collect();
keys.sort();
for key in keys {
let val = &map.entries[key];
let v = match val {
PropertyValue::Int(i) => format!("{i}"),
PropertyValue::Float(f) => format!("{f}"),
PropertyValue::Text(s) => format!("\"{s}\""),
PropertyValue::Bool(b) => format!("{b}"),
};
parts.push(format!("\"{key}\":{v}"));
}
format!("{{{}}}", parts.join(","))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_property_map() {
let map = new_property_map();
assert_eq!(property_count(&map), 0);
}
#[test]
fn test_set_get() {
let mut map = new_property_map();
set_property(&mut map, "name", PropertyValue::Text("test".into()));
assert_eq!(
get_property(&map, "name"),
Some(&PropertyValue::Text("test".into()))
);
}
#[test]
fn test_has_property() {
let mut map = new_property_map();
set_property(&mut map, "x", PropertyValue::Int(42));
assert!(has_property(&map, "x"));
assert!(!has_property(&map, "y"));
}
#[test]
fn test_property_count() {
let mut map = new_property_map();
set_property(&mut map, "a", PropertyValue::Int(1));
set_property(&mut map, "b", PropertyValue::Float(2.0));
assert_eq!(property_count(&map), 2);
}
#[test]
fn test_remove() {
let mut map = new_property_map();
set_property(&mut map, "k", PropertyValue::Bool(true));
let removed = remove_property(&mut map, "k");
assert_eq!(removed, Some(PropertyValue::Bool(true)));
assert!(!has_property(&map, "k"));
}
#[test]
fn test_property_keys() {
let mut map = new_property_map();
set_property(&mut map, "b", PropertyValue::Int(2));
set_property(&mut map, "a", PropertyValue::Int(1));
assert_eq!(property_keys(&map), vec!["a", "b"]);
}
#[test]
fn test_properties_to_json() {
let mut map = new_property_map();
set_property(&mut map, "x", PropertyValue::Int(10));
let json = properties_to_json(&map);
assert!(json.contains("\"x\":10"));
}
#[test]
fn test_overwrite() {
let mut map = new_property_map();
set_property(&mut map, "k", PropertyValue::Int(1));
set_property(&mut map, "k", PropertyValue::Int(2));
assert_eq!(get_property(&map, "k"), Some(&PropertyValue::Int(2)));
assert_eq!(property_count(&map), 1);
}
#[test]
fn test_remove_nonexistent() {
let mut map = new_property_map();
assert!(remove_property(&mut map, "nope").is_none());
}
#[test]
fn test_multiple_types() {
let mut map = new_property_map();
set_property(&mut map, "i", PropertyValue::Int(1));
set_property(&mut map, "f", PropertyValue::Float(1.5));
set_property(&mut map, "s", PropertyValue::Text("hi".into()));
set_property(&mut map, "b", PropertyValue::Bool(false));
assert_eq!(property_count(&map), 4);
}
}