diff --git a/src/builtin/string.rs b/src/builtin/string.rs index 034f6c7..a7dac57 100644 --- a/src/builtin/string.rs +++ b/src/builtin/string.rs @@ -50,12 +50,14 @@ pub(crate) fn register(f: &mut BTreeMap) { let start = match arg!(args, 1, "start-at").eval() { Value::Dimension(n, Unit::None) if n.to_integer().is_positive() => n.to_integer().to_usize().unwrap(), Value::Dimension(n, Unit::None) if n == Number::from(0) => 1_usize, + Value::Dimension(n, Unit::None) if n < -Number::from(str_len) => 1_usize, Value::Dimension(n, Unit::None) => (BigInt::from(str_len + 1) + n.to_integer()).to_usize().unwrap(), Value::Dimension(..) => todo!("$start: Expected ___ to have no units."), _ => todo!("$start-at: ____ is not a number") }; let mut end = match arg!(args, 2, "end-at"=Value::Null).eval() { Value::Dimension(n, Unit::None) if n.to_integer().is_positive() => n.to_integer().to_usize().unwrap(), + Value::Dimension(n, Unit::None) if n < -Number::from(str_len) => 0_usize, Value::Dimension(n, Unit::None) => (BigInt::from(str_len + 1) + n.to_integer()).to_usize().unwrap(), Value::Dimension(..) => todo!("$end: Expected ___ to have no units."), Value::Null => str_len, @@ -78,6 +80,5 @@ pub(crate) fn register(f: &mut BTreeMap) { QuoteKind::None => Some(Value::Ident(s, QuoteKind::None)), } } - }); } diff --git a/src/value/number.rs b/src/value/number.rs index d31a26f..c9cdf25 100644 --- a/src/value/number.rs +++ b/src/value/number.rs @@ -1,6 +1,6 @@ use std::convert::From; use std::fmt::{self, Display, Write}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign}; +use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign, Neg}; use num_bigint::BigInt; use num_rational::BigRational; @@ -196,3 +196,13 @@ impl RemAssign for Number { self.val %= other.val } } + +impl Neg for Number { + type Output = Self; + + fn neg(self) -> Self { + Number { + val: -self.val, + } + } +} \ No newline at end of file diff --git a/tests/strings.rs b/tests/strings.rs index e27b01b..8f955d9 100644 --- a/tests/strings.rs +++ b/tests/strings.rs @@ -68,3 +68,13 @@ test!( "a {\n color: str-slice(cde, 0);\n}\n", "a {\n color: cde;\n}\n" ); +test!( + str_slice_start_below_negative_str_len, + "a {\n color: str-slice(cde, -100);\n}\n", + "a {\n color: cde;\n}\n" +); +test!( + str_slice_end_below_negative_str_len, + "a {\n color: str-slice(\"cde\", 0, -100);\n}\n", + "a {\n color: \"\";\n}\n" +);