#![allow(dead_code)]
use std::collections::HashMap;
#[allow(dead_code)]
#[derive(Debug, Clone)]
struct DriverRule {
input: String,
output: String,
factor: f32,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct FaceShapeDriver {
rules: Vec<DriverRule>,
}
#[allow(dead_code)]
pub fn new_face_shape_driver() -> FaceShapeDriver {
FaceShapeDriver { rules: Vec::new() }
}
#[allow(dead_code)]
pub fn add_driver_rule(driver: &mut FaceShapeDriver, input: &str, output: &str, factor: f32) {
driver.rules.push(DriverRule {
input: input.to_string(),
output: output.to_string(),
factor,
});
}
#[allow(dead_code)]
pub fn evaluate_drivers(
driver: &FaceShapeDriver,
inputs: &HashMap<String, f32>,
) -> HashMap<String, f32> {
let mut result = HashMap::new();
for rule in &driver.rules {
let input_val = inputs.get(&rule.input).copied().unwrap_or(0.0);
let entry = result.entry(rule.output.clone()).or_insert(0.0);
*entry += input_val * rule.factor;
}
result
}
#[allow(dead_code)]
pub fn driver_count(driver: &FaceShapeDriver) -> usize {
driver.rules.len()
}
#[allow(dead_code)]
pub fn driver_output(driver: &FaceShapeDriver, index: usize) -> &str {
driver.rules.get(index).map_or("", |r| &r.output)
}
#[allow(dead_code)]
pub fn driver_input(driver: &FaceShapeDriver, index: usize) -> &str {
driver.rules.get(index).map_or("", |r| &r.input)
}
#[allow(dead_code)]
pub fn drivers_to_json(driver: &FaceShapeDriver) -> String {
let entries: Vec<String> = driver
.rules
.iter()
.map(|r| {
format!(
"{{\"input\":\"{}\",\"output\":\"{}\",\"factor\":{}}}",
r.input, r.output, r.factor
)
})
.collect();
format!("{{\"rules\":[{}]}}", entries.join(","))
}
#[allow(dead_code)]
pub fn clear_drivers(driver: &mut FaceShapeDriver) {
driver.rules.clear();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_driver() {
let d = new_face_shape_driver();
assert_eq!(driver_count(&d), 0);
}
#[test]
fn test_add_rule() {
let mut d = new_face_shape_driver();
add_driver_rule(&mut d, "jaw_open", "chin_down", 0.5);
assert_eq!(driver_count(&d), 1);
}
#[test]
fn test_evaluate_single() {
let mut d = new_face_shape_driver();
add_driver_rule(&mut d, "a", "b", 2.0);
let mut inputs = HashMap::new();
inputs.insert("a".to_string(), 0.5);
let out = evaluate_drivers(&d, &inputs);
assert!((out["b"] - 1.0).abs() < 1e-6);
}
#[test]
fn test_evaluate_missing_input() {
let mut d = new_face_shape_driver();
add_driver_rule(&mut d, "x", "y", 1.0);
let inputs = HashMap::new();
let out = evaluate_drivers(&d, &inputs);
assert!((out["y"] - 0.0).abs() < 1e-6);
}
#[test]
fn test_driver_output_name() {
let mut d = new_face_shape_driver();
add_driver_rule(&mut d, "in", "out", 1.0);
assert_eq!(driver_output(&d, 0), "out");
assert_eq!(driver_output(&d, 99), "");
}
#[test]
fn test_driver_input_name() {
let mut d = new_face_shape_driver();
add_driver_rule(&mut d, "in", "out", 1.0);
assert_eq!(driver_input(&d, 0), "in");
}
#[test]
fn test_drivers_to_json() {
let d = new_face_shape_driver();
let json = drivers_to_json(&d);
assert!(json.contains("\"rules\":[]"));
}
#[test]
fn test_clear_drivers() {
let mut d = new_face_shape_driver();
add_driver_rule(&mut d, "a", "b", 1.0);
clear_drivers(&mut d);
assert_eq!(driver_count(&d), 0);
}
#[test]
fn test_multiple_rules_same_output() {
let mut d = new_face_shape_driver();
add_driver_rule(&mut d, "a", "out", 1.0);
add_driver_rule(&mut d, "b", "out", 1.0);
let mut inputs = HashMap::new();
inputs.insert("a".to_string(), 0.3);
inputs.insert("b".to_string(), 0.7);
let out = evaluate_drivers(&d, &inputs);
assert!((out["out"] - 1.0).abs() < 1e-6);
}
#[test]
fn test_evaluate_empty() {
let d = new_face_shape_driver();
let inputs = HashMap::new();
let out = evaluate_drivers(&d, &inputs);
assert!(out.is_empty());
}
}