diff --git a/src/api/type_names.rs b/src/api/type_names.rs index 0b36603e..6b305272 100644 --- a/src/api/type_names.rs +++ b/src/api/type_names.rs @@ -1,3 +1,4 @@ +use crate::packages::iter_basic::{BitRange, CharsStream, StepRange}; use crate::{ Engine, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, Position, RhaiError, ERR, }; @@ -65,6 +66,41 @@ fn map_std_type_name(name: &str, shorthands: bool) -> &str { "RangeInclusive" }; } + if name == type_name::() { + return if shorthands { "range" } else { "BitRange" }; + } + if name == type_name::() { + return if shorthands { "range" } else { "CharStream" }; + } + + let step_range_name = type_name::>(); + let step_range_name = &step_range_name[..step_range_name.len() - 3]; + + if name.starts_with(step_range_name) && name.ends_with('>') { + return if shorthands { + "range" + } else { + let step_range_name = step_range_name.split("::").last().unwrap(); + &step_range_name[..step_range_name.len() - 1] + }; + } + + #[cfg(not(feature = "no_float"))] + if name == type_name::() { + return if shorthands { + "range" + } else { + "StepFloatRange" + }; + } + #[cfg(not(feature = "no_float"))] + if name == type_name::() { + return if shorthands { + "range" + } else { + "StepDecimalRange" + }; + } if name.starts_with("rhai::") { map_std_type_name(&name[6..], shorthands) diff --git a/src/packages/iter_basic.rs b/src/packages/iter_basic.rs index 95ccdf7a..2f0843d2 100644 --- a/src/packages/iter_basic.rs +++ b/src/packages/iter_basic.rs @@ -17,7 +17,7 @@ use std::ops::{Add, Sub}; // Range iterator with step #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] -struct StepRange(T, T, T) +pub struct StepRange(T, T, T) where T: Variant + Copy + PartialOrd + Add + Sub; @@ -115,7 +115,7 @@ impl FusedIterator for StepRange where // Bit-field iterator with step #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] -struct BitRange(INT, INT, usize); +pub struct BitRange(INT, INT, usize); impl BitRange { pub fn new(value: INT, from: INT, len: INT) -> RhaiResultOf { @@ -166,7 +166,7 @@ impl ExactSizeIterator for BitRange { // String iterator over characters #[derive(Debug, Clone, Hash, Eq, PartialEq)] -struct CharsStream(Vec, usize); +pub struct CharsStream(Vec, usize); impl CharsStream { pub fn new(string: &str, from: INT, len: INT) -> Self { @@ -237,6 +237,134 @@ impl ExactSizeIterator for CharsStream { } } +#[cfg(not(feature = "no_float"))] +pub mod float { + use super::*; + use crate::FLOAT; + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct StepFloatRange(FLOAT, FLOAT, FLOAT); + + impl StepFloatRange { + pub fn new(from: FLOAT, to: FLOAT, step: FLOAT) -> RhaiResultOf { + #[cfg(not(feature = "unchecked"))] + if step == 0.0 { + return Err(crate::ERR::ErrorInFunctionCall( + "range".to_string(), + "".to_string(), + crate::ERR::ErrorArithmetic( + "step value cannot be zero".to_string(), + Position::NONE, + ) + .into(), + Position::NONE, + ) + .into()); + } + + Ok(Self(from, to, step)) + } + } + + impl Iterator for StepFloatRange { + type Item = FLOAT; + + fn next(&mut self) -> Option { + if self.0 == self.1 { + None + } else if self.0 < self.1 { + #[cfg(not(feature = "unchecked"))] + if self.2 < 0.0 { + return None; + } + + let v = self.0; + let n = self.0 + self.2; + + self.0 = if n >= self.1 { self.1 } else { n }; + Some(v) + } else { + #[cfg(not(feature = "unchecked"))] + if self.2 > 0.0 { + return None; + } + + let v = self.0; + let n = self.0 + self.2; + + self.0 = if n <= self.1 { self.1 } else { n }; + Some(v) + } + } + } + + impl FusedIterator for StepFloatRange {} +} + +#[cfg(feature = "decimal")] +pub mod decimal { + use super::*; + use rust_decimal::Decimal; + + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] + pub struct StepDecimalRange(Decimal, Decimal, Decimal); + + impl StepDecimalRange { + pub fn new(from: Decimal, to: Decimal, step: Decimal) -> RhaiResultOf { + #[cfg(not(feature = "unchecked"))] + if step.is_zero() { + return Err(crate::ERR::ErrorInFunctionCall( + "range".to_string(), + "".to_string(), + crate::ERR::ErrorArithmetic( + "step value cannot be zero".to_string(), + Position::NONE, + ) + .into(), + Position::NONE, + ) + .into()); + } + + Ok(Self(from, to, step)) + } + } + + impl Iterator for StepDecimalRange { + type Item = Decimal; + + fn next(&mut self) -> Option { + if self.0 == self.1 { + None + } else if self.0 < self.1 { + #[cfg(not(feature = "unchecked"))] + if self.2.is_sign_negative() { + return None; + } + + let v = self.0; + let n = self.0 + self.2; + + self.0 = if n >= self.1 { self.1 } else { n }; + Some(v) + } else { + #[cfg(not(feature = "unchecked"))] + if self.2.is_sign_positive() { + return None; + } + + let v = self.0; + let n = self.0 + self.2; + + self.0 = if n <= self.1 { self.1 } else { n }; + Some(v) + } + } + } + + impl FusedIterator for StepDecimalRange {} +} + macro_rules! reg_range { ($lib:ident | $x:expr => $( $y:ty ),*) => { $( @@ -326,62 +454,9 @@ def_package! { #[cfg(not(feature = "no_float"))] { - use crate::FLOAT; + lib.set_iterator::(); - #[derive(Debug, Clone, Copy, PartialEq)] - struct StepFloatRange(FLOAT, FLOAT, FLOAT); - - impl StepFloatRange { - pub fn new(from: FLOAT, to: FLOAT, step: FLOAT) -> RhaiResultOf { - #[cfg(not(feature = "unchecked"))] - if step == 0.0 { - return Err(crate::ERR::ErrorInFunctionCall("range".to_string(), "".to_string(), - crate::ERR::ErrorArithmetic("step value cannot be zero".to_string(), Position::NONE).into(), - Position::NONE, - ).into()); - } - - Ok(Self(from, to, step)) - } - } - - impl Iterator for StepFloatRange { - type Item = FLOAT; - - fn next(&mut self) -> Option { - if self.0 == self.1 { - None - } else if self.0 < self.1 { - #[cfg(not(feature = "unchecked"))] - if self.2 < 0.0 { - return None; - } - - let v = self.0; - let n = self.0 + self.2; - - self.0 = if n >= self.1 { self.1 } else { n }; - Some(v) - } else { - #[cfg(not(feature = "unchecked"))] - if self.2 > 0.0 { - return None; - } - - let v = self.0; - let n = self.0 + self.2; - - self.0 = if n <= self.1 { self.1 } else { n }; - Some(v) - } - } - } - - impl FusedIterator for StepFloatRange {} - - lib.set_iterator::(); - - let _hash = lib.set_native_fn("range", StepFloatRange::new); + let _hash = lib.set_native_fn("range", float::StepFloatRange::new); #[cfg(feature = "metadata")] lib.update_fn_metadata_with_comments( _hash, @@ -408,62 +483,9 @@ def_package! { #[cfg(feature = "decimal")] { - use rust_decimal::Decimal; + lib.set_iterator::(); - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] - struct StepDecimalRange(Decimal, Decimal, Decimal); - - impl StepDecimalRange { - pub fn new(from: Decimal, to: Decimal, step: Decimal) -> RhaiResultOf { - #[cfg(not(feature = "unchecked"))] - if step.is_zero() { - return Err(crate::ERR::ErrorInFunctionCall("range".to_string(), "".to_string(), - crate::ERR::ErrorArithmetic("step value cannot be zero".to_string(), Position::NONE).into(), - Position::NONE, - ).into()); - } - - Ok(Self(from, to, step)) - } - } - - impl Iterator for StepDecimalRange { - type Item = Decimal; - - fn next(&mut self) -> Option { - if self.0 == self.1 { - None - } else if self.0 < self.1 { - #[cfg(not(feature = "unchecked"))] - if self.2.is_sign_negative() { - return None; - } - - let v = self.0; - let n = self.0 + self.2; - - self.0 = if n >= self.1 { self.1 } else { n }; - Some(v) - } else { - #[cfg(not(feature = "unchecked"))] - if self.2.is_sign_positive() { - return None; - } - - let v = self.0; - let n = self.0 + self.2; - - self.0 = if n <= self.1 { self.1 } else { n }; - Some(v) - } - } - } - - impl FusedIterator for StepDecimalRange {} - - lib.set_iterator::(); - - let _hash = lib.set_native_fn("range", StepDecimalRange::new); + let _hash = lib.set_native_fn("range", decimal::StepDecimalRange::new); #[cfg(feature = "metadata")] lib.update_fn_metadata_with_comments( _hash, diff --git a/src/packages/mod.rs b/src/packages/mod.rs index 343dd651..046b9cde 100644 --- a/src/packages/mod.rs +++ b/src/packages/mod.rs @@ -8,7 +8,7 @@ mod bit_field; pub(crate) mod blob_basic; mod debugging; mod fn_basic; -mod iter_basic; +pub(crate) mod iter_basic; mod lang_core; mod logic; mod map_basic;