Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:35:37.848Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

serde_helper.rs

136 lines · 4.1 KB · rust
1use serde::Serializer;
2
3/// Serializes an f32 value with 2 decimal places of precision.
4///
5/// This function rounds the value to 2 decimal places and formats it as a string,
6/// then parses it back to f64 before serialization. This ensures clean JSON output
7/// without IEEE 754 floating-point artifacts.
8///
9/// # Arguments
10///
11/// * `value` - The f32 value to serialize
12/// * `serializer` - The serde serializer to use
13///
14/// # Returns
15///
16/// Result of the serialization operation
17///
18/// # Usage
19///
20/// This function can be used with Serde's `serialize_with` attribute:
21/// ```
22/// use serde::Serialize;
23/// use settings_content::serialize_f32_with_two_decimal_places;
24///
25/// #[derive(Serialize)]
26/// struct ExampleStruct(#[serde(serialize_with = "serialize_f32_with_two_decimal_places")] f32);
27/// ```
28pub fn serialize_f32_with_two_decimal_places<S>(
29    value: &f32,
30    serializer: S,
31) -> Result<S::Ok, S::Error>
32where
33    S: Serializer,
34{
35    let rounded = (value * 100.0).round() / 100.0;
36    let formatted = format!("{:.2}", rounded);
37    let clean_value: f64 = formatted.parse().unwrap_or(rounded as f64);
38    serializer.serialize_f64(clean_value)
39}
40
41/// Serializes an optional f32 value with 2 decimal places of precision.
42///
43/// This function handles `Option<f32>` types, serializing `Some` values with 2 decimal
44/// places of precision and `None` values as null. For `Some` values, it rounds to 2 decimal
45/// places and formats as a string, then parses back to f64 before serialization. This ensures
46/// clean JSON output without IEEE 754 floating-point artifacts.
47///
48/// # Arguments
49///
50/// * `value` - The optional f32 value to serialize
51/// * `serializer` - The serde serializer to use
52///
53/// # Returns
54///
55/// Result of the serialization operation
56///
57/// # Behavior
58///
59/// * `Some(v)` - Serializes the value rounded to 2 decimal places
60/// * `None` - Serializes as JSON null
61///
62/// # Usage
63///
64/// This function can be used with Serde's `serialize_with` attribute:
65/// ```
66/// use serde::Serialize;
67/// use settings_content::serialize_optional_f32_with_two_decimal_places;
68///
69/// #[derive(Serialize)]
70/// struct ExampleStruct {
71///     #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
72///     optional_value: Option<f32>,
73/// }
74/// ```
75pub fn serialize_optional_f32_with_two_decimal_places<S>(
76    value: &Option<f32>,
77    serializer: S,
78) -> Result<S::Ok, S::Error>
79where
80    S: Serializer,
81{
82    match value {
83        Some(v) => {
84            let rounded = (v * 100.0).round() / 100.0;
85            let formatted = format!("{:.2}", rounded);
86            let clean_value: f64 = formatted.parse().unwrap_or(rounded as f64);
87            serializer.serialize_some(&clean_value)
88        }
89        None => serializer.serialize_none(),
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96    use serde::{Deserialize, Serialize};
97
98    #[derive(Serialize, Deserialize)]
99    struct TestOptional {
100        #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
101        value: Option<f32>,
102    }
103
104    #[derive(Serialize, Deserialize)]
105    struct TestNonOptional {
106        #[serde(serialize_with = "serialize_f32_with_two_decimal_places")]
107        value: f32,
108    }
109
110    #[test]
111    fn test_serialize_optional_f32_with_two_decimal_places() {
112        let cases = [
113            (Some(123.456789), r#"{"value":123.46}"#),
114            (Some(1.2), r#"{"value":1.2}"#),
115            (Some(300.00000), r#"{"value":300.0}"#),
116        ];
117        for (value, expected) in cases {
118            let value = TestOptional { value };
119            assert_eq!(serde_json::to_string(&value).unwrap(), expected);
120        }
121    }
122
123    #[test]
124    fn test_serialize_f32_with_two_decimal_places() {
125        let cases = [
126            (123.456789, r#"{"value":123.46}"#),
127            (1.200, r#"{"value":1.2}"#),
128            (300.00000, r#"{"value":300.0}"#),
129        ];
130        for (value, expected) in cases {
131            let value = TestNonOptional { value };
132            assert_eq!(serde_json::to_string(&value).unwrap(), expected);
133        }
134    }
135}
136
Served at tenant.openagents/omega Member data and write actions are omitted.