oxihuman_morph/
hydration_morph.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone, Copy, PartialEq)]
9pub enum HydrationLevel {
10 Dehydrated,
11 Dry,
12 Normal,
13 Hydrated,
14 Overhydrated,
15}
16
17#[derive(Debug, Clone)]
19pub struct HydrationMorph {
20 pub level: HydrationLevel,
21 pub intensity: f32,
22 pub morph_count: usize,
23 pub enabled: bool,
24}
25
26impl HydrationMorph {
27 pub fn new(morph_count: usize) -> Self {
28 HydrationMorph {
29 level: HydrationLevel::Normal,
30 intensity: 0.5,
31 morph_count,
32 enabled: true,
33 }
34 }
35}
36
37pub fn new_hydration_morph(morph_count: usize) -> HydrationMorph {
39 HydrationMorph::new(morph_count)
40}
41
42pub fn hym_set_level(morph: &mut HydrationMorph, level: HydrationLevel) {
44 morph.level = level;
45}
46
47pub fn hym_set_intensity(morph: &mut HydrationMorph, intensity: f32) {
49 morph.intensity = intensity.clamp(0.0, 1.0);
50}
51
52pub fn hym_evaluate(morph: &HydrationMorph) -> Vec<f32> {
54 if !morph.enabled || morph.morph_count == 0 {
56 return vec![];
57 }
58 vec![morph.intensity; morph.morph_count]
59}
60
61pub fn hym_set_enabled(morph: &mut HydrationMorph, enabled: bool) {
63 morph.enabled = enabled;
64}
65
66pub fn hym_to_json(morph: &HydrationMorph) -> String {
68 let lvl = match morph.level {
69 HydrationLevel::Dehydrated => "dehydrated",
70 HydrationLevel::Dry => "dry",
71 HydrationLevel::Normal => "normal",
72 HydrationLevel::Hydrated => "hydrated",
73 HydrationLevel::Overhydrated => "overhydrated",
74 };
75 format!(
76 r#"{{"level":"{}","intensity":{},"morph_count":{},"enabled":{}}}"#,
77 lvl, morph.intensity, morph.morph_count, morph.enabled
78 )
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_default_level() {
87 let m = new_hydration_morph(4);
88 assert_eq!(
89 m.level,
90 HydrationLevel::Normal );
92 }
93
94 #[test]
95 fn test_set_level() {
96 let mut m = new_hydration_morph(4);
97 hym_set_level(&mut m, HydrationLevel::Dry);
98 assert_eq!(m.level, HydrationLevel::Dry );
99 }
100
101 #[test]
102 fn test_intensity_clamp_high() {
103 let mut m = new_hydration_morph(4);
104 hym_set_intensity(&mut m, 2.0);
105 assert!((m.intensity - 1.0).abs() < 1e-6 );
106 }
107
108 #[test]
109 fn test_intensity_clamp_low() {
110 let mut m = new_hydration_morph(4);
111 hym_set_intensity(&mut m, -0.5);
112 assert!(m.intensity.abs() < 1e-6 );
113 }
114
115 #[test]
116 fn test_evaluate_length() {
117 let m = new_hydration_morph(5);
118 assert_eq!(
119 hym_evaluate(&m).len(),
120 5 );
122 }
123
124 #[test]
125 fn test_evaluate_disabled() {
126 let mut m = new_hydration_morph(4);
127 hym_set_enabled(&mut m, false);
128 assert!(hym_evaluate(&m).is_empty() );
129 }
130
131 #[test]
132 fn test_evaluate_zero_count() {
133 let m = new_hydration_morph(0);
134 assert!(hym_evaluate(&m).is_empty() );
135 }
136
137 #[test]
138 fn test_to_json_has_level() {
139 let m = new_hydration_morph(4);
140 let j = hym_to_json(&m);
141 assert!(j.contains("\"level\"") );
142 }
143
144 #[test]
145 fn test_enabled_default() {
146 let m = new_hydration_morph(4);
147 assert!(m.enabled );
148 }
149
150 #[test]
151 fn test_evaluate_matches_intensity() {
152 let mut m = new_hydration_morph(3);
153 hym_set_intensity(&mut m, 0.7);
154 let out = hym_evaluate(&m);
155 assert!((out[0] - 0.7).abs() < 1e-5 );
156 }
157}