chrome_remote_interface_model_tools/
lib.rs

1use std::convert::TryFrom;
2use std::fs::File;
3use std::io::Write;
4use std::path::Path;
5
6use anyhow::Context as _;
7pub use check_features::check_features;
8use serde::Deserialize;
9
10mod check_features;
11mod render;
12
13#[derive(Debug, Deserialize)]
14#[serde(deny_unknown_fields)]
15struct Property {
16    name: String,
17    #[serde(flatten)]
18    annotation: Annotation,
19    #[serde(flatten)]
20    r#type: Type,
21}
22
23impl Typed for Property {
24    fn r#type(&self) -> &Type {
25        &self.r#type
26    }
27}
28
29impl Annotatable for Property {
30    fn annotation(&self) -> &Annotation {
31        &self.annotation
32    }
33}
34
35#[derive(Debug, Deserialize)]
36struct RawType {
37    r#type: Option<String>,
38    #[serde(rename = "$ref")]
39    r#ref: Option<String>,
40    r#enum: Option<Vec<String>>,
41    properties: Option<Vec<Property>>,
42    items: Option<Type>,
43    optional: Option<bool>,
44}
45
46#[derive(Debug, Deserialize)]
47#[serde(try_from = "RawType")]
48enum Type {
49    String,
50
51    Integer,
52
53    Number,
54
55    Boolean,
56
57    Binary,
58
59    Any,
60
61    EnumString(Vec<String>),
62
63    Object(Vec<Property>),
64
65    Array(Box<Type>),
66
67    Ref(String),
68
69    Option(Box<Type>),
70}
71
72impl TryFrom<RawType> for Type {
73    type Error = anyhow::Error;
74
75    fn try_from(value: RawType) -> Result<Self, Self::Error> {
76        let RawType {
77            r#type,
78            r#ref,
79            r#enum,
80            properties,
81            items,
82            optional,
83        } = value;
84        let result = match (r#type.as_deref(), r#ref, r#enum, properties, items) {
85            (None, Some(r), None, None, None) => Type::Ref(r),
86            (Some("string"), None, Some(v), None, None) => Type::EnumString(v),
87            (Some("string"), None, None, None, None) => Type::String,
88            (Some("integer"), None, None, None, None) => Type::Integer,
89            (Some("number"), None, None, None, None) => Type::Number,
90            (Some("boolean"), None, None, None, None) => Type::Boolean,
91            (Some("binary"), None, None, None, None) => Type::Binary,
92            (Some("any"), None, None, None, None) => Type::Any,
93            (Some("object"), None, None, properties, None) => {
94                Type::Object(properties.unwrap_or_default())
95            }
96            (Some("array"), None, None, None, Some(items)) => Type::Array(Box::new(items)),
97            other => anyhow::bail!("{:?}", other),
98        };
99        if optional.unwrap_or_default() {
100            Ok(Self::Option(Box::new(result)))
101        } else {
102            Ok(result)
103        }
104    }
105}
106
107trait Typed {
108    fn r#type(&self) -> &Type;
109}
110
111trait Annotatable {
112    fn annotation(&self) -> &Annotation;
113
114    fn deps(&self) -> Option<Vec<String>> {
115        None
116    }
117}
118
119#[derive(Debug, Deserialize, Default)]
120struct Annotation {
121    description: Option<String>,
122    #[serde(default)]
123    experimental: bool,
124    #[serde(default)]
125    deprecated: bool,
126}
127
128#[derive(Debug, Deserialize)]
129#[serde(deny_unknown_fields)]
130struct DomainType {
131    id: String,
132    #[serde(flatten)]
133    annotation: Annotation,
134    #[serde(flatten)]
135    r#type: Type,
136}
137
138impl Typed for DomainType {
139    fn r#type(&self) -> &Type {
140        &self.r#type
141    }
142}
143
144impl Annotatable for DomainType {
145    fn annotation(&self) -> &Annotation {
146        &self.annotation
147    }
148}
149
150#[derive(Debug, Deserialize)]
151#[serde(deny_unknown_fields)]
152struct Parameter {
153    name: String,
154    #[serde(flatten)]
155    annotation: Annotation,
156    #[serde(flatten)]
157    r#type: Type,
158}
159
160impl Typed for Parameter {
161    fn r#type(&self) -> &Type {
162        &self.r#type
163    }
164}
165
166impl Annotatable for Parameter {
167    fn annotation(&self) -> &Annotation {
168        &self.annotation
169    }
170}
171
172#[derive(Debug, Deserialize)]
173#[serde(deny_unknown_fields)]
174struct Return {
175    name: String,
176    #[serde(flatten)]
177    annotation: Annotation,
178    #[serde(flatten)]
179    r#type: Type,
180}
181
182impl Typed for Return {
183    fn r#type(&self) -> &Type {
184        &self.r#type
185    }
186}
187
188impl Annotatable for Return {
189    fn annotation(&self) -> &Annotation {
190        &self.annotation
191    }
192}
193
194#[derive(Debug, Deserialize)]
195#[serde(deny_unknown_fields)]
196struct Command {
197    name: String,
198    redirect: Option<String>,
199    #[serde(flatten)]
200    annotation: Annotation,
201    #[serde(default)]
202    parameters: Vec<Parameter>,
203    #[serde(default)]
204    returns: Vec<Return>,
205}
206
207impl Annotatable for Command {
208    fn annotation(&self) -> &Annotation {
209        &self.annotation
210    }
211}
212
213#[derive(Debug, Deserialize)]
214#[serde(deny_unknown_fields)]
215struct Event {
216    name: String,
217    #[serde(flatten)]
218    annotation: Annotation,
219    #[serde(default)]
220    parameters: Vec<Parameter>,
221}
222
223impl Annotatable for Event {
224    fn annotation(&self) -> &Annotation {
225        &self.annotation
226    }
227}
228
229#[derive(Debug, Deserialize)]
230#[serde(deny_unknown_fields)]
231struct Domain {
232    domain: String,
233    #[serde(flatten)]
234    annotation: Annotation,
235    #[serde(default)]
236    dependencies: Vec<String>,
237    #[serde(default)]
238    types: Vec<DomainType>,
239    #[serde(default)]
240    commands: Vec<Command>,
241    #[serde(default)]
242    events: Vec<Event>,
243}
244
245impl Annotatable for Domain {
246    fn annotation(&self) -> &Annotation {
247        &self.annotation
248    }
249
250    fn deps(&self) -> Option<Vec<String>> {
251        Some(
252            vec![self.domain.clone()]
253                .into_iter()
254                .chain(self.dependencies.clone().into_iter())
255                .collect(),
256        )
257    }
258}
259
260#[derive(Debug, Deserialize)]
261#[serde(deny_unknown_fields)]
262struct ProtocolVersion {
263    major: String,
264    minor: String,
265}
266
267#[derive(Debug, Deserialize)]
268#[serde(deny_unknown_fields)]
269struct Protocol {
270    domains: Vec<Domain>,
271    version: ProtocolVersion,
272}
273
274pub fn run<P: AsRef<Path>, W: Write>(path: P, output: &mut W) -> anyhow::Result<()> {
275    let mut f = File::open(path)?;
276    let protocol = serde_json::from_reader(&mut f).context("failed to parse protocol json.")?;
277    let program = render::render(&protocol);
278    write!(output, "{}", program)?;
279    Ok(())
280}