1use serde::{Deserialize, Serialize};
2use std::hash::Hash;
3
4#[derive(Clone, Serialize, Deserialize, Debug)]
10pub enum TransformType {
11 Linear,
14 Arcsinh { cofactor: f32 },
19}
20
21impl TransformType {
22 pub fn create_from_str(s: Option<&str>) -> Self {
24 match s {
25 Some("linear") => TransformType::Linear,
26 Some("arcsinh") => TransformType::default(),
27 _ => TransformType::default(),
28 }
29 }
30}
31
32pub trait Transformable {
37 fn transform(&self, value: &f32) -> f32;
38 fn inverse_transform(&self, value: &f32) -> f32;
39}
40#[allow(unused)]
45pub trait Formattable {
46 fn format(&self, value: &f32) -> String;
47}
48
49impl Transformable for TransformType {
50 fn transform(&self, value: &f32) -> f32 {
51 match self {
52 TransformType::Linear => *value,
53 TransformType::Arcsinh { cofactor } => (value / cofactor).asinh(),
54 }
55 }
56 fn inverse_transform(&self, value: &f32) -> f32 {
57 match self {
58 TransformType::Linear => *value,
59 TransformType::Arcsinh { cofactor } => {
60 eprintln!(
61 "🔧 [INVERSE_TRANSFORM] Arcsinh inverse: value={}, cofactor={}",
62 value, cofactor
63 );
64 let sinh_result = value.sinh();
65 eprintln!("🔧 [INVERSE_TRANSFORM] sinh({}) = {}", value, sinh_result);
66 let final_result = sinh_result * cofactor;
67 eprintln!(
68 "🔧 [INVERSE_TRANSFORM] final result: {} * {} = {}",
69 sinh_result, cofactor, final_result
70 );
71 final_result
72 }
73 }
74 }
75}
76impl Formattable for TransformType {
77 fn format(&self, value: &f32) -> String {
78 match self {
79 TransformType::Linear => format!("{:.1e}", value),
80 TransformType::Arcsinh { cofactor: _ } => {
81 let original_value = self.inverse_transform(value);
83
84 format!("{:.1e}", original_value)
86 }
87 }
88 }
89}
90impl Default for TransformType {
91 fn default() -> Self {
92 TransformType::Arcsinh { cofactor: 200.0 }
93 }
94}
95impl Hash for TransformType {
96 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
97 match self {
98 TransformType::Linear => "linear".hash(state),
99 TransformType::Arcsinh { cofactor: _ } => "arcsinh".hash(state),
100 }
101 }
102}
103
104#[test]
105fn test_transform() {
106 let t = TransformType::Linear;
107 assert_eq!(t.transform(&1.0), 1.0);
108 assert_eq!(t.inverse_transform(&1.0), 1.0);
109
110 let t = TransformType::Arcsinh { cofactor: 200.0 };
111 assert_eq!(t.transform(&1.0), 0.005);
112 assert_eq!(t.inverse_transform(&0.005), 1.0);
113 assert!(!t.transform(&-1.0).is_nan());
115 assert!(!t.transform(&0.0).is_nan());
116 assert!(!t.transform(&-200.0).is_nan());
117}