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()).expect("RawNode holds valid JSON by construction")
59 }
60
61 pub fn type_name(&self) -> Option<String> {
63 #[derive(Deserialize)]
64 struct TypeProbe {
65 #[serde(rename = "type")]
66 type_name: Option<String>,
67 }
68 from_json_str_unbounded::<TypeProbe>(self.0.get())
69 .ok()
70 .and_then(|p| p.type_name)
71 }
72}
73
74pub fn from_json_str_unbounded<'de, T: serde::Deserialize<'de>>(
80 s: &'de str,
81) -> serde_json::Result<T> {
82 let mut deserializer = serde_json::Deserializer::from_str(s);
83 deserializer.disable_recursion_limit();
84 T::deserialize(&mut deserializer)
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct Position {
89 pub line: u32,
90 pub column: u32,
91 #[serde(default, skip_serializing_if = "Option::is_none")]
92 pub index: Option<u32>,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct SourceLocation {
97 pub start: Position,
98 pub end: Position,
99 #[serde(default, skip_serializing_if = "Option::is_none")]
100 pub filename: Option<String>,
101 #[serde(
102 default,
103 skip_serializing_if = "Option::is_none",
104 rename = "identifierName"
105 )]
106 pub identifier_name: Option<String>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
110#[serde(tag = "type")]
111pub enum Comment {
112 CommentBlock(CommentData),
113 CommentLine(CommentData),
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct CommentData {
118 pub value: String,
119 #[serde(default, skip_serializing_if = "Option::is_none")]
120 pub start: Option<u32>,
121 #[serde(default, skip_serializing_if = "Option::is_none")]
122 pub end: Option<u32>,
123 #[serde(default, skip_serializing_if = "Option::is_none")]
124 pub loc: Option<SourceLocation>,
125}
126
127#[derive(Debug, Clone, Default, Serialize, Deserialize)]
128pub struct BaseNode {
129 #[serde(rename = "type", default, skip_serializing_if = "Option::is_none")]
137 pub node_type: Option<String>,
138 #[serde(default, skip_serializing_if = "Option::is_none")]
139 pub start: Option<u32>,
140 #[serde(default, skip_serializing_if = "Option::is_none")]
141 pub end: Option<u32>,
142 #[serde(default, skip_serializing_if = "Option::is_none")]
143 pub loc: Option<SourceLocation>,
144 #[serde(default, skip_serializing_if = "Option::is_none")]
145 pub range: Option<(u32, u32)>,
146 #[serde(default, skip_serializing_if = "Option::is_none")]
147 pub extra: Option<RawNode>,
148 #[serde(
149 default,
150 skip_serializing_if = "Option::is_none",
151 rename = "leadingComments"
152 )]
153 pub leading_comments: Option<Vec<Comment>>,
154 #[serde(
155 default,
156 skip_serializing_if = "Option::is_none",
157 rename = "innerComments"
158 )]
159 pub inner_comments: Option<Vec<Comment>>,
160 #[serde(
161 default,
162 skip_serializing_if = "Option::is_none",
163 rename = "trailingComments"
164 )]
165 pub trailing_comments: Option<Vec<Comment>>,
166 #[serde(default, skip_serializing_if = "Option::is_none", rename = "_nodeId")]
167 pub node_id: Option<u32>,
168}
169
170impl BaseNode {
171 pub fn typed(type_name: &str) -> Self {
175 Self {
176 node_type: Some(type_name.to_string()),
177 ..Default::default()
178 }
179 }
180}