#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct EthnicFeatureSet {
pub name: String,
pub morph_weights: Vec<f32>,
}
#[derive(Debug, Clone)]
pub struct EthnicBlendMorph {
pub feature_sets: Vec<EthnicFeatureSet>,
pub blend_weights: Vec<f32>,
pub morph_count: usize,
pub enabled: bool,
}
impl EthnicBlendMorph {
pub fn new(morph_count: usize) -> Self {
EthnicBlendMorph {
feature_sets: Vec::new(),
blend_weights: Vec::new(),
morph_count,
enabled: true,
}
}
}
pub fn new_ethnic_blend_morph(morph_count: usize) -> EthnicBlendMorph {
EthnicBlendMorph::new(morph_count)
}
pub fn ebmrph_add_feature_set(morph: &mut EthnicBlendMorph, feature_set: EthnicFeatureSet) {
morph.blend_weights.push(0.0);
morph.feature_sets.push(feature_set);
}
pub fn ebmrph_set_blend_weight(morph: &mut EthnicBlendMorph, idx: usize, weight: f32) {
if idx < morph.blend_weights.len() {
morph.blend_weights[idx] = weight.clamp(0.0, 1.0);
}
}
pub fn ebmrph_evaluate(morph: &EthnicBlendMorph) -> Vec<f32> {
vec![0.0; morph.morph_count]
}
pub fn ebmrph_feature_count(morph: &EthnicBlendMorph) -> usize {
morph.feature_sets.len()
}
pub fn ebmrph_set_enabled(morph: &mut EthnicBlendMorph, enabled: bool) {
morph.enabled = enabled;
}
pub fn ebmrph_to_json(morph: &EthnicBlendMorph) -> String {
format!(
r#"{{"morph_count":{},"feature_sets":{},"enabled":{}}}"#,
morph.morph_count,
morph.feature_sets.len(),
morph.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_morph_count() {
let m = new_ethnic_blend_morph(16);
assert_eq!(m.morph_count, 16 ,);
}
#[test]
fn test_no_features_initially() {
let m = new_ethnic_blend_morph(8);
assert_eq!(
ebmrph_feature_count(&m),
0,
);
}
#[test]
fn test_add_feature_set() {
let mut m = new_ethnic_blend_morph(8);
ebmrph_add_feature_set(
&mut m,
EthnicFeatureSet {
name: "set_a".into(),
morph_weights: vec![0.0; 8],
},
);
assert_eq!(
ebmrph_feature_count(&m),
1,
);
}
#[test]
fn test_blend_weight_init_zero() {
let mut m = new_ethnic_blend_morph(4);
ebmrph_add_feature_set(
&mut m,
EthnicFeatureSet {
name: "x".into(),
morph_weights: vec![0.0; 4],
},
);
assert!((m.blend_weights[0]).abs() < 1e-6, );
}
#[test]
fn test_set_blend_weight() {
let mut m = new_ethnic_blend_morph(4);
ebmrph_add_feature_set(
&mut m,
EthnicFeatureSet {
name: "x".into(),
morph_weights: vec![0.0; 4],
},
);
ebmrph_set_blend_weight(&mut m, 0, 0.7);
assert!((m.blend_weights[0] - 0.7).abs() < 1e-5, );
}
#[test]
fn test_blend_weight_clamped() {
let mut m = new_ethnic_blend_morph(4);
ebmrph_add_feature_set(
&mut m,
EthnicFeatureSet {
name: "x".into(),
morph_weights: vec![0.0; 4],
},
);
ebmrph_set_blend_weight(&mut m, 0, 2.0);
assert!((m.blend_weights[0] - 1.0).abs() < 1e-6, );
}
#[test]
fn test_evaluate_output_length() {
let m = new_ethnic_blend_morph(10);
let out = ebmrph_evaluate(&m);
assert_eq!(
out.len(),
10,
);
}
#[test]
fn test_set_enabled() {
let mut m = new_ethnic_blend_morph(4);
ebmrph_set_enabled(&mut m, false);
assert!(!m.enabled ,);
}
#[test]
fn test_to_json_contains_morph_count() {
let m = new_ethnic_blend_morph(5);
let j = ebmrph_to_json(&m);
assert!(j.contains("\"morph_count\""), );
}
#[test]
fn test_enabled_default() {
let m = new_ethnic_blend_morph(1);
assert!(m.enabled ,);
}
#[test]
fn test_out_of_bounds_set_ignored() {
let mut m = new_ethnic_blend_morph(4);
ebmrph_set_blend_weight(&mut m, 99, 1.0);
assert_eq!(
ebmrph_feature_count(&m),
0,
);
}
}