diff --git a/src/builder/import.rs b/src/builder/import.rs index 1137aa5..4297115 100644 --- a/src/builder/import.rs +++ b/src/builder/import.rs @@ -1,11 +1,17 @@ use super::invoke::{Invoke, Identity}; use elements; -pub struct ImportBuilder { +pub struct ImportBuilder { callback: F, module: String, field: String, - binding: ExternalBinding, + binding: elements::External, +} + +impl ImportBuilder { + pub fn new() -> Self { + ImportBuilder::with_callback(Identity) + } } impl ImportBuilder { @@ -13,27 +19,97 @@ impl ImportBuilder { pub fn with_callback(callback: F) -> Self { ImportBuilder { callback: callback, - module + module: String::new(), + field: String::new(), + binding: elements::External::Function(0), } } - pub fn external(self) -> ImportExternalBuilder { + pub fn module(mut self, name: &str) -> Self { + self.module = name.to_owned(); + self + } + pub fn field(mut self, name: &str) -> Self { + self.field = name.to_owned(); + self + } + + pub fn path(self, module: &str, field: &str) -> Self { + self.module(module).field(field) + } + + pub fn with_external(mut self, external: elements::External) -> Self { + self.binding = external; + self + } + + pub fn external(self) -> ImportExternalBuilder { + ImportExternalBuilder::with_callback(self) + } +} + +impl ImportBuilder where F: Invoke { + pub fn build(self) -> F::Result { + self.callback.invoke(elements::ImportEntry::new(self.module, self.field, self.binding)) + } +} + +impl Invoke for ImportBuilder { + type Result = Self; + fn invoke(self, val: elements::External) -> Self { + self.with_external(val) } } pub struct ImportExternalBuilder { callback: F, - binding: ExternalBinding, + binding: elements::External, } -impl ImportExternalBuilder where F: Invoke { - pub fn with_callback(callback: F) { +impl ImportExternalBuilder where F: Invoke { + pub fn with_callback(callback: F) -> Self { ImportExternalBuilder{ callback: callback, - binding: ExternalBinding::ExistingFunc(0), + binding: elements::External::Function(0), } } - pub fn + pub fn func(mut self, index: u32) -> F::Result { + self.binding = elements::External::Function(index); + self.callback.invoke(self.binding) + } + + pub fn memory(mut self, min: u32, max: Option) -> F::Result { + self.binding = elements::External::Memory(elements::MemoryType::new(min, max)); + self.callback.invoke(self.binding) + } + + pub fn table(mut self, min: u32, max: Option) -> F::Result { + self.binding = elements::External::Table(elements::TableType::new(min, max)); + self.callback.invoke(self.binding) + } + + pub fn global(mut self, value_type: elements::ValueType, is_mut: bool) -> F::Result { + self.binding = elements::External::Global(elements::GlobalType::new(value_type, is_mut)); + self.callback.invoke(self.binding) + } +} + +/// New builder for import entry +pub fn import() -> ImportBuilder { + ImportBuilder::new() +} + +#[cfg(test)] +mod tests { + use super::import; + + #[test] + fn example() { + let entry = import().module("env").field("memory").external().memory(256, Some(256)).build(); + + assert_eq!(entry.module(), "env"); + assert_eq!(entry.field(), "memory"); + } } \ No newline at end of file diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 2972ffb..e5d939b 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -4,6 +4,8 @@ mod invoke; mod module; mod code; mod misc; +mod import; pub use self::module::{module, ModuleBuilder}; -pub use self::code::signatures; \ No newline at end of file +pub use self::code::signatures; +pub use self::import::import; \ No newline at end of file diff --git a/src/elements/import_entry.rs b/src/elements/import_entry.rs index fd08ae1..83328d3 100644 --- a/src/elements/import_entry.rs +++ b/src/elements/import_entry.rs @@ -11,8 +11,17 @@ pub struct GlobalType { } impl GlobalType { + /// New global type + pub fn new(content_type: ValueType, is_mutable: bool) -> Self { + GlobalType { + content_type: content_type, + is_mutable: is_mutable, + } + } + /// Type of the global entry pub fn content_type(&self) -> ValueType { self.content_type } + /// Is global entry is declared as mutable pub fn is_mutable(&self) -> bool { self.is_mutable } } @@ -47,6 +56,13 @@ pub struct TableType { } impl TableType { + /// New table definition + pub fn new(min: u32, max: Option) -> Self { + TableType { + elem_type: 0, + limits: ResizableLimits::new(min, max), + } + } /// Table memory specification pub fn limits(&self) -> &ResizableLimits { &self.limits } } @@ -81,6 +97,13 @@ pub struct ResizableLimits { } impl ResizableLimits { + /// New memory limits definition + pub fn new(min: u32, max: Option) -> Self { + ResizableLimits { + initial: min, + maximum: max, + } + } /// Initial size pub fn initial(&self) -> u32 { self.initial } /// Maximum size @@ -124,6 +147,10 @@ impl Serialize for ResizableLimits { pub struct MemoryType(ResizableLimits); impl MemoryType { + /// New memory definition + pub fn new(min: u32, max: Option) -> Self { + MemoryType(ResizableLimits::new(min, max)) + } /// Limits of the memory entry. pub fn limits(&self) -> &ResizableLimits { &self.0 diff --git a/src/elements/mod.rs b/src/elements/mod.rs index f003623..6fa0d00 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -1,4 +1,4 @@ -//! Elemets of the WebAssembly binary format. +//! Elements of the WebAssembly binary format. use std::io;