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.118";
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 generate_typescript: bool,
44 kind: ImportKind<'a>,
45 }
46
47 struct LinkedModule<'a> {
48 module: ImportModule<'a>,
49 link_function_name: &'a str,
50 }
51
52 enum ImportModule<'a> {
53 Named(&'a str),
54 RawNamed(&'a str),
55 Inline(u32),
56 }
57
58 enum ImportKind<'a> {
59 Function(ImportFunction<'a>),
60 Static(ImportStatic<'a>),
61 String(ImportString<'a>),
62 Type(ImportType<'a>),
63 Enum(StringEnum<'a>),
64 }
65
66 struct ImportFunction<'a> {
67 shim: &'a str,
68 catch: bool,
69 variadic: bool,
70 assert_no_shim: bool,
71 method: Option<MethodData<'a>>,
72 structural: bool,
73 function: Function<'a>,
74 }
75
76 struct MethodData<'a> {
77 class: &'a str,
78 kind: MethodKind<'a>,
79 }
80
81 enum MethodKind<'a> {
82 Constructor,
83 Operation(Operation<'a>),
84 }
85
86 struct Operation<'a> {
87 is_static: bool,
88 kind: OperationKind<'a>,
89 }
90
91 enum OperationKind<'a> {
92 Regular,
93 RegularThis,
94 Getter(&'a str),
95 Setter(&'a str),
96 IndexingGetter,
97 IndexingSetter,
98 IndexingDeleter,
99 }
100
101 struct ImportStatic<'a> {
102 name: &'a str,
103 shim: &'a str,
104 }
105
106 struct ImportString<'a> {
107 shim: &'a str,
108 string: &'a str,
109 }
110
111 struct ImportType<'a> {
112 name: &'a str,
113 instanceof_shim: &'a str,
114 vendor_prefixes: Vec<&'a str>,
115 }
116
117 struct StringEnum<'a> {
118 name: &'a str,
119 variant_values: Vec<&'a str>,
120 comments: Vec<&'a str>,
121 generate_typescript: bool,
122 js_namespace: Option<Vec<&'a str>>,
123 }
124
125 enum StartKind {
126 None,
127 Public,
128 Private,
129 }
130
131 struct Export<'a> {
132 class: Option<&'a str>,
133 comments: Vec<&'a str>,
134 consumed: bool,
135 function: Function<'a>,
136 js_namespace: Option<Vec<&'a str>>,
137 method_kind: MethodKind<'a>,
138 start: StartKind,
139 }
140
141 struct Enum<'a> {
142 name: &'a str,
143 signed: bool,
144 variants: Vec<EnumVariant<'a>>,
145 comments: Vec<&'a str>,
146 generate_typescript: bool,
147 js_namespace: Option<Vec<&'a str>>,
148 private: bool,
149 }
150
151 struct EnumVariant<'a> {
152 name: &'a str,
153 value: u32,
154 comments: Vec<&'a str>,
155 }
156
157 struct Function<'a> {
158 args: Vec<FunctionArgumentData<'a>>,
159 asyncness: bool,
160 name: &'a str,
161 generate_typescript: bool,
162 generate_jsdoc: bool,
163 variadic: bool,
164 ret_ty_override: Option<&'a str>,
165 ret_desc: Option<&'a str>,
166 }
167
168 struct FunctionArgumentData<'a> {
169 name: String,
170 ty_override: Option<&'a str>,
171 optional: bool,
172 desc: Option<&'a str>,
173 }
174
175 struct Struct<'a> {
176 name: &'a str,
177 rust_name: &'a str,
178 fields: Vec<StructField<'a>>,
179 comments: Vec<&'a str>,
180 is_inspectable: bool,
181 generate_typescript: bool,
182 js_namespace: Option<Vec<&'a str>>,
183 private: bool,
184 }
185
186 struct StructField<'a> {
187 name: &'a str,
188 readonly: bool,
189 comments: Vec<&'a str>,
190 generate_typescript: bool,
191 generate_jsdoc: bool,
192 }
193
194 struct LocalModule<'a> {
195 identifier: &'a str,
196 contents: &'a str,
197 linked_module: bool,
198 }
199 }
200 }; } pub fn qualified_name(js_namespace: Option<&[impl AsRef<str>]>, js_name: &str) -> String {
209 match js_namespace {
210 Some(ns) if !ns.is_empty() => {
211 let mut name = ns
212 .iter()
213 .map(|s| s.as_ref())
214 .collect::<alloc::vec::Vec<_>>()
215 .join("__");
216 name.push_str("__");
217 name.push_str(js_name);
218 name
219 }
220 _ => js_name.to_string(),
221 }
222}
223
224pub fn new_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("_new");
228 name
229}
230
231pub fn free_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("_free");
235 name
236}
237
238pub fn unwrap_function(struct_name: &str) -> String {
239 let mut name = "__wbg_".to_string();
240 name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
241 name.push_str("_unwrap");
242 name
243}
244
245pub fn free_function_export_name(function_name: &str) -> String {
246 function_name.to_string()
247}
248
249pub fn struct_function_export_name(struct_: &str, f: &str) -> String {
250 let mut name = struct_
251 .chars()
252 .flat_map(|s| s.to_lowercase())
253 .collect::<String>();
254 name.push('_');
255 name.push_str(f);
256 name
257}
258
259pub fn struct_field_get(struct_: &str, f: &str) -> String {
260 let mut name = String::from("__wbg_get_");
261 name.extend(struct_.chars().flat_map(|s| s.to_lowercase()));
262 name.push('_');
263 name.push_str(f);
264 name
265}
266
267pub fn struct_field_set(struct_: &str, f: &str) -> String {
268 let mut name = String::from("__wbg_set_");
269 name.extend(struct_.chars().flat_map(|s| s.to_lowercase()));
270 name.push('_');
271 name.push_str(f);
272 name
273}
274
275pub fn version() -> String {
276 let mut v = env!("CARGO_PKG_VERSION").to_string();
277 if let Some(s) = option_env!("WBG_VERSION") {
278 v.push_str(" (");
279 v.push_str(s);
280 v.push(')');
281 }
282 v
283}
284
285pub fn escape_string(s: &str) -> String {
286 let mut result = String::with_capacity(s.len());
287 for c in s.chars() {
288 match c {
289 '\\' => result.push_str("\\\\"),
290 '\n' => result.push_str("\\n"),
291 '\r' => result.push_str("\\r"),
292 '\'' => result.push_str("\\'"),
293 '"' => result.push_str("\\\""),
294 _ => result.push(c),
295 }
296 }
297 result
298}