facet_json/to_json.rs
1#![allow(unreachable_code)]
2
3use facet_poke::Peek;
4use facet_trait::ShapeExt as _;
5use std::io::{self, Write};
6
7/// Serializes any Facet type to JSON
8pub fn to_json<W: Write>(peek: Peek<'_>, writer: &mut W, indent: bool) -> io::Result<()> {
9 fn serialize_value<W: Write>(
10 peek: Peek<'_>,
11 writer: &mut W,
12 indent: bool,
13 level: usize,
14 ) -> io::Result<()> {
15 match peek {
16 Peek::Value(pv) => {
17 if pv.shape().is_type::<()>() {
18 write!(writer, "null")
19 } else if pv.shape().is_type::<bool>() {
20 let value = unsafe { pv.data().as_ref::<bool>() };
21 write!(writer, "{}", value)
22 } else if pv.shape().is_type::<u64>() {
23 let value = unsafe { pv.data().as_ref::<u64>() };
24 write!(writer, "{}", value)
25 } else if pv.shape().is_type::<String>() {
26 let value = unsafe { pv.data().as_ref::<String>() };
27 write!(writer, "\"{}\"", value.escape_debug())
28 } else {
29 // For other types, we'll use a placeholder
30 write!(writer, "\"<unsupported type>\"")
31 }
32 }
33 Peek::Struct(ps) => {
34 write!(writer, "{{")?;
35 if indent {
36 writeln!(writer)?;
37 }
38
39 let mut first = true;
40 for field in ps.fields() {
41 if !first {
42 write!(writer, ",")?;
43 if indent {
44 writeln!(writer)?;
45 }
46 }
47 first = false;
48
49 if indent {
50 write!(writer, "{:indent$}", "", indent = (level + 1) * 2)?;
51 }
52 write!(writer, "\"{}\":", field.0)?;
53 if indent {
54 write!(writer, " ")?;
55 }
56
57 serialize_value(Peek::Value(field.1), writer, indent, level + 1)?;
58 }
59
60 if !first && indent {
61 writeln!(writer)?;
62 write!(writer, "{:indent$}", "", indent = level * 2)?;
63 }
64 write!(writer, "}}")
65 }
66 Peek::List(_pl) => {
67 todo!("list");
68
69 write!(writer, "[")?;
70 if indent {
71 writeln!(writer)?;
72 }
73
74 let mut first = true;
75 let mut _index = 0;
76 // while let Some(item) = pl.item_at(index) {
77 // if !first {
78 // write!(writer, ",")?;
79 // if indent {
80 // writeln!(writer)?;
81 // }
82 // }
83 // first = false;
84
85 // if indent {
86 // write!(writer, "{:indent$}", "", indent = (level + 1) * 2)?;
87 // }
88
89 // serialize_value(item, writer, indent, level + 1)?;
90 // index += 1;
91 // }
92
93 if !first && indent {
94 writeln!(writer)?;
95 write!(writer, "{:indent$}", "", indent = level * 2)?;
96 }
97 write!(writer, "]")
98 }
99 Peek::Map(_pm) => {
100 todo!("map");
101
102 write!(writer, "{{")?;
103 if indent {
104 writeln!(writer)?;
105 }
106
107 let mut first = true;
108 let mut _index = 0;
109 // while let Some((key, value)) = pm.entry_at(index) {
110 // if !first {
111 // write!(writer, ",")?;
112 // if indent {
113 // writeln!(writer)?;
114 // }
115 // }
116 // first = false;
117
118 // if indent {
119 // write!(writer, "{:indent$}", "", indent = (level + 1) * 2)?;
120 // }
121
122 // // Handle key serialization
123 // serialize_value(Peek::Scalar(key), writer, false, 0)?;
124 // write!(writer, ":")?;
125
126 // if indent {
127 // write!(writer, " ")?;
128 // }
129
130 // serialize_value(value, writer, indent, level + 1)?;
131 // index += 1;
132 // }
133
134 if !first && indent {
135 writeln!(writer)?;
136 write!(writer, "{:indent$}", "", indent = level * 2)?;
137 }
138
139 write!(writer, "}}")
140 }
141 }
142 }
143
144 serialize_value(peek, writer, indent, 0)
145}
146
147/// Serializes any Facet type to JSON and returns it as a String
148pub fn to_json_string(peek: Peek<'_>, indent: bool) -> String {
149 let mut buffer = Vec::new();
150 to_json(peek, &mut buffer, indent).unwrap();
151 String::from_utf8(buffer).unwrap()
152}