1use crate::Value;
2
3use std::{
4 any::TypeId,
5 collections::HashMap,
6 fmt::{self, Display, Formatter},
7 sync::OnceLock,
8};
9
10pub trait ValueFormatter: Send + Sync {
11 fn format(&self, value: &dyn std::any::Any, f: &mut Formatter) -> fmt::Result;
12}
13
14pub struct FormatterRegistry {
15 formatters: HashMap<TypeId, Box<dyn ValueFormatter>>,
16}
17
18impl FormatterRegistry {
19 fn new() -> Self { Self { formatters: HashMap::new() } }
20
21 fn register<T: 'static>(&mut self, formatter: Box<dyn ValueFormatter>) { self.formatters.insert(TypeId::of::<T>(), formatter); }
22
23 pub fn get(&self, type_id: TypeId) -> Option<&dyn ValueFormatter> { self.formatters.get(&type_id).map(|boxed| boxed.as_ref()) }
24}
25
26pub static FORMATTER_REGISTRY: OnceLock<FormatterRegistry> = OnceLock::new();
27
28pub fn init_registry() -> FormatterRegistry {
29 let mut registry = FormatterRegistry::new();
30
31 registry.register::<()>(Box::new(NullFormatter));
32 registry.register::<bool>(Box::new(SimpleFormatter));
33 registry.register::<usize>(Box::new(SimpleFormatter));
34 registry.register::<f64>(Box::new(SimpleFormatter));
35 registry.register::<String>(Box::new(StringFormatter));
36 registry.register::<&'static str>(Box::new(StringFormatter));
37 registry.register::<Vec<Value>>(Box::new(SequenceFormatter::new("[", "]")));
38 registry.register::<&'static [Value]>(Box::new(SequenceFormatter::new("[", "]")));
39 registry.register::<HashMap<String, Value>>(Box::new(MapFormatter));
40
41 registry
42}
43
44struct NullFormatter;
45impl ValueFormatter for NullFormatter {
46 fn format(&self, _: &dyn std::any::Any, f: &mut Formatter) -> fmt::Result { f.write_str("null") }
47}
48
49struct SimpleFormatter;
50impl ValueFormatter for SimpleFormatter {
51 fn format(&self, value: &dyn std::any::Any, f: &mut Formatter) -> fmt::Result {
52 if let Some(v) = value.downcast_ref::<bool>() {
53 v.fmt(f)
54 } else if let Some(v) = value.downcast_ref::<usize>() {
55 v.fmt(f)
56 } else if let Some(v) = value.downcast_ref::<f64>() {
57 v.fmt(f)
58 } else {
59 Err(fmt::Error)
60 }
61 }
62}
63
64struct StringFormatter;
65impl ValueFormatter for StringFormatter {
66 fn format(&self, value: &dyn std::any::Any, f: &mut Formatter) -> fmt::Result {
67 if let Some(s) = value.downcast_ref::<String>() {
68 write!(f, "{s}")
69 } else if let Some(s) = value.downcast_ref::<&'static str>() {
70 write!(f, "{s}")
71 } else {
72 Err(fmt::Error)
73 }
74 }
75}
76
77struct SequenceFormatter {
78 start: &'static str,
79 end: &'static str,
80}
81
82impl SequenceFormatter {
83 fn new(start: &'static str, end: &'static str) -> Self { Self { start, end } }
84}
85
86impl ValueFormatter for SequenceFormatter {
87 fn format(&self, value: &dyn std::any::Any, f: &mut Formatter) -> fmt::Result {
88 f.write_str(self.start)?;
89 let mut first = true;
90
91 if let Some(vec) = value.downcast_ref::<Vec<Value>>() {
92 for item in vec.iter() {
93 if !first {
94 f.write_str(", ")?;
95 }
96 item.fmt(f)?;
97 first = false;
98 }
99 } else if let Some(slice) = value.downcast_ref::<&'static [Value]>() {
100 for item in *slice {
101 if !first {
102 f.write_str(", ")?;
103 }
104 item.fmt(f)?;
105 first = false;
106 }
107 } else {
108 return Err(fmt::Error);
109 }
110
111 f.write_str(self.end)
112 }
113}
114
115struct MapFormatter;
116impl ValueFormatter for MapFormatter {
117 fn format(&self, value: &dyn std::any::Any, f: &mut Formatter) -> fmt::Result {
118 if let Some(map) = value.downcast_ref::<HashMap<String, Value>>() {
119 f.write_str("{")?;
120 let mut first = true;
121 for (key, value) in map {
122 if !first {
123 f.write_str(", ")?;
124 }
125 write!(f, "\"{}\": {}", key, value)?;
126 first = false;
127 }
128 f.write_str("}")
129 } else {
130 Err(fmt::Error)
131 }
132 }
133}