react_compiler_ast/
common.rs1use serde::Deserialize;
2use serde::Serialize;
3
4#[derive(Debug, Clone, Serialize)]
16#[serde(transparent)]
17pub struct RawNode(pub Box<serde_json::value::RawValue>);
18
19impl<'de> serde::Deserialize<'de> for RawNode {
20 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
21 where
22 D: serde::Deserializer<'de>,
23 {
24 let mut buf = Vec::new();
25 let mut ser = serde_json::Serializer::new(&mut buf);
26 serde_transcode::transcode(deserializer, &mut ser).map_err(serde::de::Error::custom)?;
27 let text = String::from_utf8(buf).map_err(serde::de::Error::custom)?;
28 serde_json::value::RawValue::from_string(text)
29 .map(RawNode)
30 .map_err(serde::de::Error::custom)
31 }
32}
33
34impl RawNode {
35 pub fn from_value(value: &serde_json::Value) -> Self {
36 RawNode(
37 serde_json::value::RawValue::from_string(value.to_string())
38 .expect("serde_json::Value always serializes to valid JSON"),
39 )
40 }
41
42 pub fn null() -> Self {
43 RawNode(
44 serde_json::value::RawValue::from_string("null".to_string())
45 .expect("null is valid JSON"),
46 )
47 }
48
49 pub fn get(&self) -> &str {
51 self.0.get()
52 }
53
54 pub fn parse_value(&self) -> serde_json::Value {
58 from_json_str_unbounded(self.0.get())
59 .expect("RawNode holds valid JSON by construction")
60 }
61
62 pub fn type_name(&self) -> Option<String> {
64 #[derive(Deserialize)]
65 struct TypeProbe {
66 #[serde(rename = "type")]
67 type_name: Option<String>,
68 }
69 from_json_str_unbounded::<TypeProbe>(self.0.get())
70 .ok()
71 .and_then(|p| p.type_name)
72 }
73}
74
75pub fn from_json_str_unbounded<'de, T: serde::Deserialize<'de>>(
81 s: &'de str,
82) -> serde_json::Result<T> {
83 let mut deserializer = serde_json::Deserializer::from_str(s);
84 deserializer.disable_recursion_limit();
85 T::deserialize(&mut deserializer)
86}
87
88pub fn nullable_value<'de, D>(deserializer: D) -> Result<Option<RawNode>, D::Error>
95where
96 D: serde::Deserializer<'de>,
97{
98 RawNode::deserialize(deserializer).map(Some)
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct Position {
103 pub line: u32,
104 pub column: u32,
105 #[serde(default, skip_serializing_if = "Option::is_none")]
106 pub index: Option<u32>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct SourceLocation {
111 pub start: Position,
112 pub end: Position,
113 #[serde(default, skip_serializing_if = "Option::is_none")]
114 pub filename: Option<String>,
115 #[serde(
116 default,
117 skip_serializing_if = "Option::is_none",
118 rename = "identifierName"
119 )]
120 pub identifier_name: Option<String>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124#[serde(tag = "type")]
125pub enum Comment {
126 CommentBlock(CommentData),
127 CommentLine(CommentData),
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct CommentData {
132 pub value: String,
133 #[serde(default, skip_serializing_if = "Option::is_none")]
134 pub start: Option<u32>,
135 #[serde(default, skip_serializing_if = "Option::is_none")]
136 pub end: Option<u32>,
137 #[serde(default, skip_serializing_if = "Option::is_none")]
138 pub loc: Option<SourceLocation>,
139}
140
141#[derive(Debug, Clone, Default, Serialize, Deserialize)]
142pub struct BaseNode {
143 #[serde(rename = "type", default, skip_serializing_if = "Option::is_none")]
151 pub node_type: Option<String>,
152 #[serde(default, skip_serializing_if = "Option::is_none")]
153 pub start: Option<u32>,
154 #[serde(default, skip_serializing_if = "Option::is_none")]
155 pub end: Option<u32>,
156 #[serde(default, skip_serializing_if = "Option::is_none")]
157 pub loc: Option<SourceLocation>,
158 #[serde(default, skip_serializing_if = "Option::is_none")]
159 pub range: Option<(u32, u32)>,
160 #[serde(default, skip_serializing_if = "Option::is_none")]
161 pub extra: Option<RawNode>,
162 #[serde(
163 default,
164 skip_serializing_if = "Option::is_none",
165 rename = "leadingComments"
166 )]
167 pub leading_comments: Option<Vec<Comment>>,
168 #[serde(
169 default,
170 skip_serializing_if = "Option::is_none",
171 rename = "innerComments"
172 )]
173 pub inner_comments: Option<Vec<Comment>>,
174 #[serde(
175 default,
176 skip_serializing_if = "Option::is_none",
177 rename = "trailingComments"
178 )]
179 pub trailing_comments: Option<Vec<Comment>>,
180 #[serde(default, skip_serializing_if = "Option::is_none", rename = "_nodeId")]
181 pub node_id: Option<u32>,
182}
183
184impl BaseNode {
185 pub fn typed(type_name: &str) -> Self {
189 Self {
190 node_type: Some(type_name.to_string()),
191 ..Default::default()
192 }
193 }
194}