export builder

This commit is contained in:
NikVolf
2017-05-09 15:23:05 +03:00
parent 5d7c7b4094
commit 9345ef5f22
4 changed files with 146 additions and 2 deletions

102
src/builder/export.rs Normal file
View File

@ -0,0 +1,102 @@
use super::invoke::{Invoke, Identity};
use elements;
pub struct ExportBuilder<F=Identity> {
callback: F,
field: String,
binding: elements::Internal,
}
impl ExportBuilder {
pub fn new() -> Self {
ExportBuilder::with_callback(Identity)
}
}
impl<F> ExportBuilder<F> {
pub fn with_callback(callback: F) -> Self {
ExportBuilder {
callback: callback,
field: String::new(),
binding: elements::Internal::Function(0),
}
}
pub fn field(mut self, field: &str) -> Self {
self.field = field.to_owned();
self
}
pub fn with_internal(mut self, external: elements::Internal) -> Self {
self.binding = external;
self
}
pub fn internal(self) -> ExportInternalBuilder<Self> {
ExportInternalBuilder::with_callback(self)
}
}
impl<F> ExportBuilder<F> where F: Invoke<elements::ExportEntry> {
pub fn build(self) -> F::Result {
self.callback.invoke(elements::ExportEntry::new(self.field, self.binding))
}
}
impl<F> Invoke<elements::Internal> for ExportBuilder<F> {
type Result = Self;
fn invoke(self, val: elements::Internal) -> Self {
self.with_internal(val)
}
}
pub struct ExportInternalBuilder<F=Identity> {
callback: F,
binding: elements::Internal,
}
impl<F> ExportInternalBuilder<F> where F: Invoke<elements::Internal> {
pub fn with_callback(callback: F) -> Self {
ExportInternalBuilder{
callback: callback,
binding: elements::Internal::Function(0),
}
}
pub fn func(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Function(index);
self.callback.invoke(self.binding)
}
pub fn memory(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Memory(index);
self.callback.invoke(self.binding)
}
pub fn table(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Table(index);
self.callback.invoke(self.binding)
}
pub fn global(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Global(index);
self.callback.invoke(self.binding)
}
}
/// New builder for export entry
pub fn export() -> ExportBuilder {
ExportBuilder::new()
}
#[cfg(test)]
mod tests {
use super::export;
#[test]
fn example() {
let entry = export().field("memory").internal().memory(0).build();
assert_eq!(entry.field(), "memory");
}
}

View File

@ -5,7 +5,9 @@ mod module;
mod code;
mod misc;
mod import;
mod export;
pub use self::module::{module, from_module, ModuleBuilder};
pub use self::code::{signatures, signature, function};
pub use self::import::import;
pub use self::import::import;
pub use self::export::export;

View File

@ -1,6 +1,6 @@
use super::invoke::{Invoke, Identity};
use super::code::{self, SignaturesBuilder, FunctionBuilder};
use super::import;
use super::{import, export};
use elements;
/// Module builder
@ -248,11 +248,22 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
self
}
/// With inserted import entry
pub fn with_export(mut self, entry: elements::ExportEntry) -> Self {
self.module.export.entries_mut().push(entry);
self
}
/// Import entry builder
pub fn import(self) -> import::ImportBuilder<Self> {
import::ImportBuilder::with_callback(self)
}
/// Export entry builder
pub fn export(self) -> export::ExportBuilder<Self> {
export::ExportBuilder::with_callback(self)
}
/// Build module (final step)
pub fn build(self) -> F::Result {
self.callback.invoke(self.module.into())
@ -302,6 +313,16 @@ impl<F> Invoke<elements::ImportEntry> for ModuleBuilder<F>
}
}
impl<F> Invoke<elements::ExportEntry> for ModuleBuilder<F>
where F: Invoke<elements::Module>
{
type Result = Self;
fn invoke(self, entry: elements::ExportEntry) -> Self::Result {
self.with_export(entry)
}
}
/// Start new module builder
pub fn module() -> ModuleBuilder {
ModuleBuilder::new()
@ -337,4 +358,12 @@ mod tests {
assert_eq!(module.code_section().expect("code section to exist").bodies().len(), 1);
}
#[test]
fn export() {
let module = module()
.export().field("call").internal().func(0).build()
.build();
assert_eq!(module.export_section().expect("export section to exist").entries().len(), 1);
}
}

View File

@ -53,12 +53,23 @@ pub struct ExportEntry {
}
impl ExportEntry {
/// New export entry
pub fn new(field: String, internal: Internal) -> Self {
ExportEntry {
field_str: field,
internal: internal
}
}
/// Public name
pub fn field(&self) -> &str { &self.field_str }
/// Public name (mutable)
pub fn field_mut(&mut self) -> &mut str { &mut self.field_str }
/// Internal reference of the export entry.
pub fn internal(&self) -> &Internal { &self.internal }
/// Internal reference of the export entry (mutable).
pub fn internal_mut(&mut self) -> &mut Internal { &mut self.internal }
}