parity_wasm/builder/
import.rs

1use super::invoke::{Identity, Invoke};
2use crate::elements;
3use alloc::{borrow::ToOwned, string::String};
4
5/// Import builder
6pub struct ImportBuilder<F = Identity> {
7	callback: F,
8	module: String,
9	field: String,
10	binding: elements::External,
11}
12
13impl ImportBuilder {
14	/// New import builder
15	pub fn new() -> Self {
16		ImportBuilder::with_callback(Identity)
17	}
18}
19
20impl Default for ImportBuilder {
21	fn default() -> Self {
22		Self::new()
23	}
24}
25
26impl<F> ImportBuilder<F> {
27	/// New import builder with callback (in chained context)
28	pub fn with_callback(callback: F) -> Self {
29		ImportBuilder {
30			callback,
31			module: String::new(),
32			field: String::new(),
33			binding: elements::External::Function(0),
34		}
35	}
36
37	/// Set/override module name
38	pub fn module(mut self, name: &str) -> Self {
39		self.module = name.to_owned();
40		self
41	}
42
43	/// Set/override field name
44	pub fn field(mut self, name: &str) -> Self {
45		self.field = name.to_owned();
46		self
47	}
48
49	/// Set/override both module name and field name
50	pub fn path(self, module: &str, field: &str) -> Self {
51		self.module(module).field(field)
52	}
53
54	/// Set/override external mapping for this import
55	pub fn with_external(mut self, external: elements::External) -> Self {
56		self.binding = external;
57		self
58	}
59
60	/// Start new external mapping builder
61	pub fn external(self) -> ImportExternalBuilder<Self> {
62		ImportExternalBuilder::with_callback(self)
63	}
64}
65
66impl<F> ImportBuilder<F>
67where
68	F: Invoke<elements::ImportEntry>,
69{
70	/// Finalize current builder spawning the resulting struct
71	pub fn build(self) -> F::Result {
72		self.callback
73			.invoke(elements::ImportEntry::new(self.module, self.field, self.binding))
74	}
75}
76
77impl<F> Invoke<elements::External> for ImportBuilder<F> {
78	type Result = Self;
79	fn invoke(self, val: elements::External) -> Self {
80		self.with_external(val)
81	}
82}
83
84/// Import to external mapping builder
85pub struct ImportExternalBuilder<F = Identity> {
86	callback: F,
87	binding: elements::External,
88}
89
90impl<F> ImportExternalBuilder<F>
91where
92	F: Invoke<elements::External>,
93{
94	/// New import to external mapping builder with callback (in chained context)
95	pub fn with_callback(callback: F) -> Self {
96		ImportExternalBuilder { callback, binding: elements::External::Function(0) }
97	}
98
99	/// Function mapping with type reference
100	pub fn func(mut self, index: u32) -> F::Result {
101		self.binding = elements::External::Function(index);
102		self.callback.invoke(self.binding)
103	}
104
105	/// Memory mapping with specified limits
106	pub fn memory(mut self, min: u32, max: Option<u32>) -> F::Result {
107		self.binding = elements::External::Memory(elements::MemoryType::new(min, max));
108		self.callback.invoke(self.binding)
109	}
110
111	/// Table mapping with specified limits
112	pub fn table(mut self, min: u32, max: Option<u32>) -> F::Result {
113		self.binding = elements::External::Table(elements::TableType::new(min, max));
114		self.callback.invoke(self.binding)
115	}
116
117	/// Global mapping with speciifed type and mutability
118	pub fn global(mut self, value_type: elements::ValueType, is_mut: bool) -> F::Result {
119		self.binding = elements::External::Global(elements::GlobalType::new(value_type, is_mut));
120		self.callback.invoke(self.binding)
121	}
122}
123
124/// New builder for import entry
125pub fn import() -> ImportBuilder {
126	ImportBuilder::new()
127}
128
129#[cfg(test)]
130mod tests {
131	use super::import;
132
133	#[test]
134	fn example() {
135		let entry =
136			import().module("env").field("memory").external().memory(256, Some(256)).build();
137
138		assert_eq!(entry.module(), "env");
139		assert_eq!(entry.field(), "memory");
140	}
141}