1#![doc(html_root_url = "https://docs.rs/wasm-bindgen-shared/0.2")]
2#![no_std]
3
4extern crate alloc;
5
6use alloc::string::{String, ToString};
7
8pub mod identifier;
9#[cfg(test)]
10mod schema_hash_approval;
11pub mod tys;
12
13pub const SCHEMA_VERSION: &str = "0.2.114";
17
18#[macro_export]
19macro_rules! shared_api {
20 ($mac:ident) => {
21 $mac! {
22 struct Program<'a> {
23 exports: Vec<Export<'a>>,
24 enums: Vec<Enum<'a>>,
25 imports: Vec<Import<'a>>,
26 structs: Vec<Struct<'a>>,
27 typescript_custom_sections: Vec<LitOrExpr<'a>>,
32 local_modules: Vec<LocalModule<'a>>,
33 inline_js: Vec<&'a str>,
34 unique_crate_identifier: &'a str,
35 package_json: Option<&'a str>,
36 linked_modules: Vec<LinkedModule<'a>>,
37 }
38
39 struct Import<'a> {
40 module: Option<ImportModule<'a>>,
41 js_namespace: Option<Vec<String>>,
42 reexport: Option<String>,
43 kind: ImportKind<'a>,
44 }
45
46 struct LinkedModule<'a> {
47 module: ImportModule<'a>,
48 link_function_name: &'a str,
49 }
50
51 enum ImportModule<'a> {
52 Named(&'a str),
53 RawNamed(&'a str),
54 Inline(u32),
55 }
56
57 enum ImportKind<'a> {
58 Function(ImportFunction<'a>),
59 Static(ImportStatic<'a>),
60 String(ImportString<'a>),
61 Type(ImportType<'a>),
62 Enum(StringEnum<'a>),
63 }
64
65 struct ImportFunction<'a> {
66 shim: &'a str,
67 catch: bool,
68 variadic: bool,
69 assert_no_shim: bool,
70 method: Option<MethodData<'a>>,
71 structural: bool,
72 function: Function<'a>,
73 }
74
75 struct MethodData<'a> {
76 class: &'a str,
77 kind: MethodKind<'a>,
78 }
79
80 enum MethodKind<'a> {
81 Constructor,
82 Operation(Operation<'a>),
83 }
84
85 struct Operation<'a> {
86 is_static: bool,
87 kind: OperationKind<'a>,
88 }
89
90 enum OperationKind<'a> {
91 Regular,
92 RegularThis,
93 Getter(&'a str),
94 Setter(&'a str),
95 IndexingGetter,
96 IndexingSetter,
97 IndexingDeleter,
98 }
99
100 struct ImportStatic<'a> {
101 name: &'a str,
102 shim: &'a str,
103 }
104
105 struct ImportString<'a> {
106 shim: &'a str,
107 string: &'a str,
108 }
109
110 struct ImportType<'a> {
111 name: &'a str,
112 instanceof_shim: &'a str,
113 vendor_prefixes: Vec<&'a str>,
114 }
115
116 struct StringEnum<'a> {
117 name: &'a str,
118 variant_values: Vec<&'a str>,
119 comments: Vec<&'a str>,
120 generate_typescript: bool,
121 js_namespace: Option<Vec<&'a str>>,
122 }
123
124 struct Export<'a> {
125 class: Option<&'a str>,
126 comments: Vec<&'a str>,
127 consumed: bool,
128 function: Function<'a>,
129 js_namespace: Option<Vec<&'a str>>,
130 method_kind: MethodKind<'a>,
131 start: bool,
132 }
133
134 struct Enum<'a> {
135 name: &'a str,
136 signed: bool,
137 variants: Vec<EnumVariant<'a>>,
138 comments: Vec<&'a str>,
139 generate_typescript: bool,
140 js_namespace: Option<Vec<&'a str>>,
141 private: bool,
142 }
143
144 struct EnumVariant<'a> {
145 name: &'a str,
146 value: u32,
147 comments: Vec<&'a str>,
148 }
149
150 struct Function<'a> {
151 args: Vec<FunctionArgumentData<'a>>,
152 asyncness: bool,
153 name: &'a str,
154 generate_typescript: bool,
155 generate_jsdoc: bool,
156 variadic: bool,
157 ret_ty_override: Option<&'a str>,
158 ret_desc: Option<&'a str>,
159 }
160
161 struct FunctionArgumentData<'a> {
162 name: String,
163 ty_override: Option<&'a str>,
164 optional: bool,
165 desc: Option<&'a str>,
166 }
167
168 struct Struct<'a> {
169 name: &'a str,
170 rust_name: &'a str,
171 fields: Vec<StructField<'a>>,
172 comments: Vec<&'a str>,
173 is_inspectable: bool,
174 generate_typescript: bool,
175 js_namespace: Option<Vec<&'a str>>,
176 private: bool,
177 }
178
179 struct StructField<'a> {
180 name: &'a str,
181 readonly: bool,
182 comments: Vec<&'a str>,
183 generate_typescript: bool,
184 generate_jsdoc: bool,
185 }
186
187 struct LocalModule<'a> {
188 identifier: &'a str,
189 contents: &'a str,
190 linked_module: bool,
191 }
192 }
193 }; } pub fn qualified_name(js_namespace: Option<&[impl AsRef<str>]>, js_name: &str) -> String {
202 match js_namespace {
203 Some(ns) if !ns.is_empty() => {
204 let mut name = ns
205 .iter()
206 .map(|s| s.as_ref())
207 .collect::<alloc::vec::Vec<_>>()
208 .join("__");
209 name.push_str("__");
210 name.push_str(js_name);
211 name
212 }
213 _ => js_name.to_string(),
214 }
215}
216
217pub fn new_function(struct_name: &str) -> String {
218 let mut name = "__wbg_".to_string();
219 name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
220 name.push_str("_new");
221 name
222}
223
224pub fn free_function(struct_name: &str) -> String {
225 let mut name = "__wbg_".to_string();
226 name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
227 name.push_str("_free");
228 name
229}
230
231pub fn unwrap_function(struct_name: &str) -> String {
232 let mut name = "__wbg_".to_string();
233 name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
234 name.push_str("_unwrap");
235 name
236}
237
238pub fn free_function_export_name(function_name: &str) -> String {
239 function_name.to_string()
240}
241
242pub fn struct_function_export_name(struct_: &str, f: &str) -> String {
243 let mut name = struct_
244 .chars()
245 .flat_map(|s| s.to_lowercase())
246 .collect::<String>();
247 name.push('_');
248 name.push_str(f);
249 name
250}
251
252pub fn struct_field_get(struct_: &str, f: &str) -> String {
253 let mut name = String::from("__wbg_get_");
254 name.extend(struct_.chars().flat_map(|s| s.to_lowercase()));
255 name.push('_');
256 name.push_str(f);
257 name
258}
259
260pub fn struct_field_set(struct_: &str, f: &str) -> String {
261 let mut name = String::from("__wbg_set_");
262 name.extend(struct_.chars().flat_map(|s| s.to_lowercase()));
263 name.push('_');
264 name.push_str(f);
265 name
266}
267
268pub fn version() -> String {
269 let mut v = env!("CARGO_PKG_VERSION").to_string();
270 if let Some(s) = option_env!("WBG_VERSION") {
271 v.push_str(" (");
272 v.push_str(s);
273 v.push(')');
274 }
275 v
276}
277
278pub fn escape_string(s: &str) -> String {
279 let mut result = String::with_capacity(s.len());
280 for c in s.chars() {
281 match c {
282 '\\' => result.push_str("\\\\"),
283 '\n' => result.push_str("\\n"),
284 '\r' => result.push_str("\\r"),
285 '\'' => result.push_str("\\'"),
286 '"' => result.push_str("\\\""),
287 _ => result.push(c),
288 }
289 }
290 result
291}