diff --git a/src/api/build_type.rs b/src/api/build_type.rs index 02a5b3cd..db8b3997 100644 --- a/src/api/build_type.rs +++ b/src/api/build_type.rs @@ -283,6 +283,20 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { } } +impl<'a, T> TypeBuilder<'a, T> +where + T: Variant + Clone + IntoIterator, + ::Item: Variant + Clone, +{ + /// Register an type iterator. + /// This is an advanced API. + #[inline(always)] + pub fn is_iterable(&mut self) -> &mut Self { + self.engine.register_iterator::(); + self + } +} + impl<'a, T: Variant + Clone> Drop for TypeBuilder<'a, T> { #[inline] fn drop(&mut self) { diff --git a/tests/build_type.rs b/tests/build_type.rs index 9f8924d4..b649dac4 100644 --- a/tests/build_type.rs +++ b/tests/build_type.rs @@ -45,10 +45,21 @@ fn build_type() -> Result<(), Box> { } } + impl IntoIterator for Vec3 { + type Item = INT; + + type IntoIter = std::array::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + <[INT; 3] as IntoIterator>::into_iter([self.x, self.y, self.z]) + } + } + impl CustomType for Vec3 { fn build(mut builder: TypeBuilder) { builder .with_name("Vec3") + .is_iterable() .with_fn("vec3", Self::new) .with_get_set("x", Self::get_x, Self::set_x) .with_get_set("y", Self::get_y, Self::set_y) @@ -117,6 +128,19 @@ fn build_type() -> Result<(), Box> { )?, Vec3::new(5, 6, 7), ); + assert_eq!( + engine.eval::( + " + let sum = 0; + let v = vec3(1, 2, 3); + for i in v { + sum += i; + } + sum + ", + )?, + 6, + ); Ok(()) }