oxihuman_morph/
flush_morph.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone, Copy, PartialEq)]
9pub enum FlushCause {
10 Emotion,
11 Heat,
12 Exercise,
13 Alcohol,
14 Rosacea,
15}
16
17#[derive(Debug, Clone)]
19pub struct FlushMorph {
20 pub cause: FlushCause,
21 pub intensity: f32,
22 pub spread: f32,
23 pub morph_count: usize,
24 pub enabled: bool,
25}
26
27impl FlushMorph {
28 pub fn new(morph_count: usize) -> Self {
29 FlushMorph {
30 cause: FlushCause::Emotion,
31 intensity: 0.0,
32 spread: 0.5,
33 morph_count,
34 enabled: true,
35 }
36 }
37}
38
39pub fn new_flush_morph(morph_count: usize) -> FlushMorph {
41 FlushMorph::new(morph_count)
42}
43
44pub fn flm_set_cause(morph: &mut FlushMorph, cause: FlushCause) {
46 morph.cause = cause;
47}
48
49pub fn flm_set_intensity(morph: &mut FlushMorph, intensity: f32) {
51 morph.intensity = intensity.clamp(0.0, 1.0);
52}
53
54pub fn flm_set_spread(morph: &mut FlushMorph, spread: f32) {
56 morph.spread = spread.clamp(0.0, 1.0);
57}
58
59pub fn flm_evaluate(morph: &FlushMorph) -> Vec<f32> {
61 if !morph.enabled || morph.morph_count == 0 {
63 return vec![];
64 }
65 vec![morph.intensity; morph.morph_count]
66}
67
68pub fn flm_set_enabled(morph: &mut FlushMorph, enabled: bool) {
70 morph.enabled = enabled;
71}
72
73pub fn flm_to_json(morph: &FlushMorph) -> String {
75 let cause = match morph.cause {
76 FlushCause::Emotion => "emotion",
77 FlushCause::Heat => "heat",
78 FlushCause::Exercise => "exercise",
79 FlushCause::Alcohol => "alcohol",
80 FlushCause::Rosacea => "rosacea",
81 };
82 format!(
83 r#"{{"cause":"{}","intensity":{},"spread":{},"morph_count":{},"enabled":{}}}"#,
84 cause, morph.intensity, morph.spread, morph.morph_count, morph.enabled
85 )
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn test_default_cause() {
94 let m = new_flush_morph(4);
95 assert_eq!(
96 m.cause,
97 FlushCause::Emotion );
99 }
100
101 #[test]
102 fn test_set_cause() {
103 let mut m = new_flush_morph(4);
104 flm_set_cause(&mut m, FlushCause::Exercise);
105 assert_eq!(m.cause, FlushCause::Exercise );
106 }
107
108 #[test]
109 fn test_intensity_clamp() {
110 let mut m = new_flush_morph(4);
111 flm_set_intensity(&mut m, 1.5);
112 assert!((m.intensity - 1.0).abs() < 1e-6 );
113 }
114
115 #[test]
116 fn test_spread_clamp() {
117 let mut m = new_flush_morph(4);
118 flm_set_spread(&mut m, -0.5);
119 assert!(m.spread.abs() < 1e-6 );
120 }
121
122 #[test]
123 fn test_evaluate_length() {
124 let mut m = new_flush_morph(5);
125 flm_set_intensity(&mut m, 0.4);
126 assert_eq!(
127 flm_evaluate(&m).len(),
128 5 );
130 }
131
132 #[test]
133 fn test_evaluate_disabled() {
134 let mut m = new_flush_morph(4);
135 flm_set_enabled(&mut m, false);
136 assert!(flm_evaluate(&m).is_empty() );
137 }
138
139 #[test]
140 fn test_to_json_has_cause() {
141 let m = new_flush_morph(4);
142 let j = flm_to_json(&m);
143 assert!(j.contains("\"cause\"") );
144 }
145
146 #[test]
147 fn test_enabled_default() {
148 let m = new_flush_morph(4);
149 assert!(m.enabled );
150 }
151
152 #[test]
153 fn test_evaluate_matches_intensity() {
154 let mut m = new_flush_morph(3);
155 flm_set_intensity(&mut m, 0.8);
156 let out = flm_evaluate(&m);
157 assert!((out[0] - 0.8).abs() < 1e-5 );
158 }
159}