oxihuman_morph/
freckle_morph.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone, Copy, PartialEq)]
9pub enum FrecklePattern {
10 Sparse,
11 Moderate,
12 Dense,
13 Solar,
14}
15
16#[derive(Debug, Clone)]
18pub struct FreckileMorph {
19 pub pattern: FrecklePattern,
20 pub density: f32,
21 pub size: f32,
22 pub morph_count: usize,
23 pub enabled: bool,
24}
25
26impl FreckileMorph {
27 pub fn new(morph_count: usize) -> Self {
28 FreckileMorph {
29 pattern: FrecklePattern::Sparse,
30 density: 0.3,
31 size: 0.5,
32 morph_count,
33 enabled: true,
34 }
35 }
36}
37
38pub fn new_freckle_morph(morph_count: usize) -> FreckileMorph {
40 FreckileMorph::new(morph_count)
41}
42
43pub fn fkm_set_pattern(morph: &mut FreckileMorph, pattern: FrecklePattern) {
45 morph.pattern = pattern;
46}
47
48pub fn fkm_set_density(morph: &mut FreckileMorph, density: f32) {
50 morph.density = density.clamp(0.0, 1.0);
51}
52
53pub fn fkm_set_size(morph: &mut FreckileMorph, size: f32) {
55 morph.size = size.clamp(0.0, 1.0);
56}
57
58pub fn fkm_evaluate(morph: &FreckileMorph) -> Vec<f32> {
60 if !morph.enabled || morph.morph_count == 0 {
62 return vec![];
63 }
64 vec![morph.density; morph.morph_count]
65}
66
67pub fn fkm_set_enabled(morph: &mut FreckileMorph, enabled: bool) {
69 morph.enabled = enabled;
70}
71
72pub fn fkm_to_json(morph: &FreckileMorph) -> String {
74 let pat = match morph.pattern {
75 FrecklePattern::Sparse => "sparse",
76 FrecklePattern::Moderate => "moderate",
77 FrecklePattern::Dense => "dense",
78 FrecklePattern::Solar => "solar",
79 };
80 format!(
81 r#"{{"pattern":"{}","density":{},"size":{},"morph_count":{},"enabled":{}}}"#,
82 pat, morph.density, morph.size, morph.morph_count, morph.enabled
83 )
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn test_default_pattern() {
92 let m = new_freckle_morph(4);
93 assert_eq!(
94 m.pattern,
95 FrecklePattern::Sparse );
97 }
98
99 #[test]
100 fn test_set_pattern() {
101 let mut m = new_freckle_morph(4);
102 fkm_set_pattern(&mut m, FrecklePattern::Dense);
103 assert_eq!(
104 m.pattern,
105 FrecklePattern::Dense );
107 }
108
109 #[test]
110 fn test_density_clamp() {
111 let mut m = new_freckle_morph(4);
112 fkm_set_density(&mut m, 1.5);
113 assert!((m.density - 1.0).abs() < 1e-6 );
114 }
115
116 #[test]
117 fn test_size_clamp() {
118 let mut m = new_freckle_morph(4);
119 fkm_set_size(&mut m, -0.5);
120 assert!(m.size.abs() < 1e-6 );
121 }
122
123 #[test]
124 fn test_evaluate_length() {
125 let m = new_freckle_morph(5);
126 assert_eq!(
127 fkm_evaluate(&m).len(),
128 5 );
130 }
131
132 #[test]
133 fn test_evaluate_disabled() {
134 let mut m = new_freckle_morph(4);
135 fkm_set_enabled(&mut m, false);
136 assert!(fkm_evaluate(&m).is_empty() );
137 }
138
139 #[test]
140 fn test_to_json_has_pattern() {
141 let m = new_freckle_morph(4);
142 let j = fkm_to_json(&m);
143 assert!(j.contains("\"pattern\"") );
144 }
145
146 #[test]
147 fn test_enabled_default() {
148 let m = new_freckle_morph(4);
149 assert!(m.enabled );
150 }
151
152 #[test]
153 fn test_evaluate_matches_density() {
154 let mut m = new_freckle_morph(3);
155 fkm_set_density(&mut m, 0.6);
156 let out = fkm_evaluate(&m);
157 assert!((out[0] - 0.6).abs() < 1e-5 );
158 }
159}