diff --git a/src/builtin/string.rs b/src/builtin/string.rs index 179dd19..9ffc169 100644 --- a/src/builtin/string.rs +++ b/src/builtin/string.rs @@ -161,7 +161,13 @@ pub(crate) fn register(f: &mut HashMap) { }; let index = match arg!(args, 2, "index") { - Value::Dimension(n, _) => n.to_integer().to_usize().unwrap(), + Value::Dimension(n, Unit::None) if n.is_decimal() => { + return Err(format!("$index: {} is not an int.", n).into()) + } + Value::Dimension(n, Unit::None) => n, + v @ Value::Dimension(..) => { + return Err(format!("$index: Expected {} to have no units.", v).into()) + } v => return Err(format!("$index: {} is not a number.", v).into()), }; @@ -170,7 +176,21 @@ pub(crate) fn register(f: &mut HashMap) { QuoteKind::None => QuoteKind::None, }; - string.insert_str(index - 1, &substr); + let len = string.len(); + + if index > Number::from(0) { + string.insert_str( + index.to_integer().to_usize().unwrap().min(len + 1) - 1, + &substr, + ); + } else if index == Number::from(0) { + string.insert_str(0, &substr); + } else { + string.insert_str( + len - index.abs().to_integer().to_usize().unwrap().min(len), + &substr, + ); + } Ok(Value::Ident(string, quotes)) }), diff --git a/tests/strings.rs b/tests/strings.rs index f4e7567..8ac1181 100644 --- a/tests/strings.rs +++ b/tests/strings.rs @@ -144,3 +144,32 @@ test!( "a {\n color: str-insert(abcd, \"\", 4);\n}\n", "a {\n color: abcd;\n}\n" ); +test!( + str_insert_idx_0, + "a {\n color: str-insert(abcd, \"X\", 0);\n}\n", + "a {\n color: Xabcd;\n}\n" +); +test!( + str_insert_negative_idx, + "a {\n color: str-insert(abcd, \"X\", -2);\n}\n", + "a {\n color: abXcd;\n}\n" +); +error!( + float_idx, + "a {\n color: str-insert(abcd, \"X\", .5);\n}\n", "Error: $index: 0.5 is not an int." +); +error!( + idx_with_units, + "a {\n color: str-insert(abcd, \"X\", 5px);\n}\n", + "Error: $index: Expected 5px to have no units." +); +test!( + idx_larger_than_string, + "a {\n color: str-insert(abcd, \"X\", 20);\n}\n", + "a {\n color: abcdX;\n}\n" +); +test!( + idx_larger_than_string_negative, + "a {\n color: str-insert(abcd, \"X\", -20);\n}\n", + "a {\n color: Xabcd;\n}\n" +);