diff --git a/examples/build.rs b/examples/build.rs index d836a61..a63af44 100644 --- a/examples/build.rs +++ b/examples/build.rs @@ -14,7 +14,7 @@ fn main() { let module = builder::module() .functions() - .signature().param(elements::ValueType::I32).build() + .signature().with_param(elements::ValueType::I32).build() .bind() .build(); diff --git a/src/builder/code.rs b/src/builder/code.rs index 053869a..def72bb 100644 --- a/src/builder/code.rs +++ b/src/builder/code.rs @@ -1,5 +1,6 @@ -use super::invoke::{Invoke, Identity}; use elements; +use super::invoke::{Invoke, Identity}; +use super::misc::{ValueTypeBuilder, ValueTypesBuilder, OptionalValueTypeBuilder}; pub enum Signature { TypeReference(u32), @@ -19,22 +20,68 @@ impl SignatureBuilder where F: Invoke { } } - pub fn param(mut self, value_type: elements::ValueType) -> Self { + pub fn with_param(mut self, value_type: elements::ValueType) -> Self { self.signature.params_mut().push(value_type); - self } - pub fn return_type(mut self, value_type: elements::ValueType) -> Self { - *self.signature.return_type_mut() = Some(value_type); + pub fn with_params(mut self, value_types: Vec) -> Self { + self.signature.params_mut().extend(value_types); self } + pub fn with_return_type(mut self, return_type: Option) -> Self { + *self.signature.return_type_mut() = return_type; + self + } + + pub fn param(self) -> ValueTypeBuilder { + ValueTypeBuilder::with_callback(self) + } + + pub fn params(self) -> ValueTypesBuilder { + ValueTypesBuilder::with_callback(self) + } + + pub fn return_type(self) -> OptionalValueTypeBuilder { + OptionalValueTypeBuilder::with_callback(self) + } + pub fn build(self) -> F::Result { self.callback.invoke(self.signature) } } +impl Invoke> for SignatureBuilder + where F: Invoke +{ + type Result = Self; + + fn invoke(self, args: Vec) -> Self { + self.with_params(args) + } +} + +impl Invoke> for SignatureBuilder + where F: Invoke +{ + type Result = Self; + + fn invoke(self, arg: Option) -> Self { + self.with_return_type(arg) + } +} + +impl Invoke for SignatureBuilder + where F: Invoke +{ + type Result = Self; + + fn invoke(self, arg: elements::ValueType) -> Self { + self.with_param(arg) + } +} + pub struct TypeRefBuilder { callback: F, type_ref: u32, @@ -150,9 +197,9 @@ mod tests { let result = function() .signature() - .param(::elements::ValueType::I32) - .param(::elements::ValueType::I32) - .return_type(::elements::ValueType::I64) + .param().i32() + .param().i32() + .return_type().i64() .build() .bind(); diff --git a/src/builder/misc.rs b/src/builder/misc.rs new file mode 100644 index 0000000..9c6bc6e --- /dev/null +++ b/src/builder/misc.rs @@ -0,0 +1,93 @@ +use super::invoke::{Invoke, Identity}; +use elements; + +pub struct ValueTypeBuilder { + callback: F, +} + +impl ValueTypeBuilder where F: Invoke { + pub fn with_callback(callback: F) -> Self { + ValueTypeBuilder { callback: callback } + } + + pub fn i32(self) -> F::Result { + self.callback.invoke(elements::ValueType::I32) + } + + pub fn i64(self) -> F::Result { + self.callback.invoke(elements::ValueType::I64) + } + + pub fn f32(self) -> F::Result { + self.callback.invoke(elements::ValueType::F32) + } + + pub fn f64(self) -> F::Result { + self.callback.invoke(elements::ValueType::F64) + } +} + +pub struct OptionalValueTypeBuilder { + callback: F, +} + +impl OptionalValueTypeBuilder where F: Invoke> { + pub fn with_callback(callback: F) -> Self { + OptionalValueTypeBuilder { callback: callback } + } + + pub fn i32(self) -> F::Result { + self.callback.invoke(Some(elements::ValueType::I32)) + } + + pub fn i64(self) -> F::Result { + self.callback.invoke(Some(elements::ValueType::I64)) + } + + pub fn f32(self) -> F::Result { + self.callback.invoke(Some(elements::ValueType::F32)) + } + + pub fn f64(self) -> F::Result { + self.callback.invoke(Some(elements::ValueType::F64)) + } +} + +pub struct ValueTypesBuilder { + callback: F, + value_types: Vec, +} + +impl ValueTypesBuilder where F: Invoke> { + pub fn with_callback(callback: F) -> Self { + ValueTypesBuilder { + callback: callback, + value_types: Vec::new(), + } + } + + pub fn i32(mut self) -> Self { + self.value_types.push(elements::ValueType::I32); + self + } + + pub fn i64(mut self) -> Self { + self.value_types.push(elements::ValueType::I64); + self + } + + pub fn f32(mut self) -> Self { + self.value_types.push(elements::ValueType::F32); + self + } + + pub fn f64(mut self) -> Self { + self.value_types.push(elements::ValueType::F64); + self + } + + pub fn build(self) -> F::Result { + self.callback.invoke(self.value_types) + } +} + diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 7254828..599e40b 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -3,6 +3,7 @@ mod invoke; mod module; mod code; +mod misc; pub use self::module::{module, ModuleBuilder}; pub use self::code::function; \ No newline at end of file diff --git a/src/builder/module.rs b/src/builder/module.rs index 898b4c4..062fbca 100644 --- a/src/builder/module.rs +++ b/src/builder/module.rs @@ -162,7 +162,7 @@ mod tests { fn functions() { let module = module() .functions() - .signature().param(::elements::ValueType::I32).build() + .signature().with_param(::elements::ValueType::I32).build() .bind() .build();