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.115";
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 struct Export<'a> {
126 class: Option<&'a str>,
127 comments: Vec<&'a str>,
128 consumed: bool,
129 function: Function<'a>,
130 js_namespace: Option<Vec<&'a str>>,
131 method_kind: MethodKind<'a>,
132 start: bool,
133 }
134
135 struct Enum<'a> {
136 name: &'a str,
137 signed: bool,
138 variants: Vec<EnumVariant<'a>>,
139 comments: Vec<&'a str>,
140 generate_typescript: bool,
141 js_namespace: Option<Vec<&'a str>>,
142 private: bool,
143 }
144
145 struct EnumVariant<'a> {
146 name: &'a str,
147 value: u32,
148 comments: Vec<&'a str>,
149 }
150
151 struct Function<'a> {
152 args: Vec<FunctionArgumentData<'a>>,
153 asyncness: bool,
154 name: &'a str,
155 generate_typescript: bool,
156 generate_jsdoc: bool,
157 variadic: bool,
158 ret_ty_override: Option<&'a str>,
159 ret_desc: Option<&'a str>,
160 }
161
162 struct FunctionArgumentData<'a> {
163 name: String,
164 ty_override: Option<&'a str>,
165 optional: bool,
166 desc: Option<&'a str>,
167 }
168
169 struct Struct<'a> {
170 name: &'a str,
171 rust_name: &'a str,
172 fields: Vec<StructField<'a>>,
173 comments: Vec<&'a str>,
174 is_inspectable: bool,
175 generate_typescript: bool,
176 js_namespace: Option<Vec<&'a str>>,
177 private: bool,
178 }
179
180 struct StructField<'a> {
181 name: &'a str,
182 readonly: bool,
183 comments: Vec<&'a str>,
184 generate_typescript: bool,
185 generate_jsdoc: bool,
186 }
187
188 struct LocalModule<'a> {
189 identifier: &'a str,
190 contents: &'a str,
191 linked_module: bool,
192 }
193 }
194 }; } pub fn qualified_name(js_namespace: Option<&[impl AsRef<str>]>, js_name: &str) -> String {
203 match js_namespace {
204 Some(ns) if !ns.is_empty() => {
205 let mut name = ns
206 .iter()
207 .map(|s| s.as_ref())
208 .collect::<alloc::vec::Vec<_>>()
209 .join("__");
210 name.push_str("__");
211 name.push_str(js_name);
212 name
213 }
214 _ => js_name.to_string(),
215 }
216}
217
218pub fn new_function(struct_name: &str) -> String {
219 let mut name = "__wbg_".to_string();
220 name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
221 name.push_str("_new");
222 name
223}
224
225pub fn free_function(struct_name: &str) -> String {
226 let mut name = "__wbg_".to_string();
227 name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
228 name.push_str("_free");
229 name
230}
231
232pub fn unwrap_function(struct_name: &str) -> String {
233 let mut name = "__wbg_".to_string();
234 name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
235 name.push_str("_unwrap");
236 name
237}
238
239pub fn free_function_export_name(function_name: &str) -> String {
240 function_name.to_string()
241}
242
243pub fn struct_function_export_name(struct_: &str, f: &str) -> String {
244 let mut name = struct_
245 .chars()
246 .flat_map(|s| s.to_lowercase())
247 .collect::<String>();
248 name.push('_');
249 name.push_str(f);
250 name
251}
252
253pub fn struct_field_get(struct_: &str, f: &str) -> String {
254 let mut name = String::from("__wbg_get_");
255 name.extend(struct_.chars().flat_map(|s| s.to_lowercase()));
256 name.push('_');
257 name.push_str(f);
258 name
259}
260
261pub fn struct_field_set(struct_: &str, f: &str) -> String {
262 let mut name = String::from("__wbg_set_");
263 name.extend(struct_.chars().flat_map(|s| s.to_lowercase()));
264 name.push('_');
265 name.push_str(f);
266 name
267}
268
269pub fn version() -> String {
270 let mut v = env!("CARGO_PKG_VERSION").to_string();
271 if let Some(s) = option_env!("WBG_VERSION") {
272 v.push_str(" (");
273 v.push_str(s);
274 v.push(')');
275 }
276 v
277}
278
279pub fn escape_string(s: &str) -> String {
280 let mut result = String::with_capacity(s.len());
281 for c in s.chars() {
282 match c {
283 '\\' => result.push_str("\\\\"),
284 '\n' => result.push_str("\\n"),
285 '\r' => result.push_str("\\r"),
286 '\'' => result.push_str("\\'"),
287 '"' => result.push_str("\\\""),
288 _ => result.push(c),
289 }
290 }
291 result
292}