finance_query/models/quote/
formatted_value.rs1use serde::{Deserialize, Serialize};
25
26#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
31#[serde(rename_all = "camelCase")]
32pub struct FormattedValue<T> {
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub fmt: Option<String>,
36
37 #[serde(skip_serializing_if = "Option::is_none")]
39 pub long_fmt: Option<String>,
40
41 #[serde(default)]
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub raw: Option<T>,
45}
46
47impl<T> FormattedValue<T> {
48 pub fn new(raw: T) -> Self {
50 Self {
51 fmt: None,
52 long_fmt: None,
53 raw: Some(raw),
54 }
55 }
56
57 pub fn with_fmt(raw: T, fmt: String) -> Self {
59 Self {
60 fmt: Some(fmt),
61 long_fmt: None,
62 raw: Some(raw),
63 }
64 }
65
66 pub fn with_all(raw: T, fmt: String, long_fmt: String) -> Self {
68 Self {
69 fmt: Some(fmt),
70 long_fmt: Some(long_fmt),
71 raw: Some(raw),
72 }
73 }
74
75 pub fn value(&self) -> Option<&T> {
77 self.raw.as_ref()
78 }
79
80 pub fn formatted(&self) -> Option<&str> {
82 self.fmt.as_deref().or(self.long_fmt.as_deref())
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn test_deserialize_simple() {
92 let json = r#"{"fmt": "276.97", "raw": 276.97}"#;
93 let value: FormattedValue<f64> = serde_json::from_str(json).unwrap();
94 assert_eq!(value.raw, Some(276.97));
95 assert_eq!(value.fmt.as_deref(), Some("276.97"));
96 assert_eq!(value.long_fmt, None);
97 }
98
99 #[test]
100 fn test_deserialize_with_long_fmt() {
101 let json = r#"{"fmt": "14.78B", "longFmt": "14,776,353,000", "raw": 14776353000}"#;
102 let value: FormattedValue<i64> = serde_json::from_str(json).unwrap();
103 assert_eq!(value.raw, Some(14776353000));
104 assert_eq!(value.fmt.as_deref(), Some("14.78B"));
105 assert_eq!(value.long_fmt.as_deref(), Some("14,776,353,000"));
106 }
107
108 #[test]
109 fn test_formatted_helper() {
110 let value = FormattedValue::with_fmt(100.5, "100.50".to_string());
111 assert_eq!(value.formatted(), Some("100.50"));
112
113 let value = FormattedValue::new(100.5);
114 assert_eq!(value.formatted(), None);
115 }
116}
117
118#[cfg(test)]
119mod test_empty_object {
120 use super::*;
121
122 #[test]
123 fn test_empty_object_deserializes() {
124 let json = "{}";
125 let result: Result<FormattedValue<f64>, _> = serde_json::from_str(json);
126 assert!(
127 result.is_ok(),
128 "Empty object should deserialize: {:?}",
129 result.err()
130 );
131
132 let fv = result.unwrap();
133 assert_eq!(fv.raw, None);
134 assert_eq!(fv.fmt, None);
135 assert_eq!(fv.long_fmt, None);
136 }
137}