diff --git a/src/builtin/string.rs b/src/builtin/string.rs index b77efcf..179dd19 100644 --- a/src/builtin/string.rs +++ b/src/builtin/string.rs @@ -146,4 +146,33 @@ pub(crate) fn register(f: &mut HashMap) { }) }), ); + f.insert( + "str-insert".to_owned(), + Box::new(|args, _| { + max_args!(args, 3); + let (mut string, q) = match arg!(args, 0, "string") { + Value::Ident(i, q) => (i, q), + v => return Err(format!("$string: {} is not a string.", v).into()), + }; + + let substr = match arg!(args, 1, "insert") { + Value::Ident(i, _) => i, + v => return Err(format!("$insert: {} is not a string.", v).into()), + }; + + let index = match arg!(args, 2, "index") { + Value::Dimension(n, _) => n.to_integer().to_usize().unwrap(), + v => return Err(format!("$index: {} is not a number.", v).into()), + }; + + let quotes = match q { + QuoteKind::Double | QuoteKind::Single => QuoteKind::Double, + QuoteKind::None => QuoteKind::None, + }; + + string.insert_str(index - 1, &substr); + + Ok(Value::Ident(string, quotes)) + }), + ); } diff --git a/tests/strings.rs b/tests/strings.rs index 7f81ee4..f4e7567 100644 --- a/tests/strings.rs +++ b/tests/strings.rs @@ -114,3 +114,33 @@ test!( "a {\n color: 1;\n}\n" ); test!(str_index_null, "a {\n color: str-index(abcd, X);\n}\n", ""); +test!( + str_insert_start, + "a {\n color: str-insert(\"abcd\", \"X\", 1);\n}\n", + "a {\n color: \"Xabcd\";\n}\n" +); +test!( + str_insert_middle, + "a {\n color: str-insert(\"abcd\", \"X\", 4);\n}\n", + "a {\n color: \"abcXd\";\n}\n" +); +test!( + str_insert_end, + "a {\n color: str-insert(\"abcd\", \"X\", 5);\n}\n", + "a {\n color: \"abcdX\";\n}\n" +); +test!( + str_insert_sgl_quotes, + "a {\n color: str-insert('abcd', \"X\", 4);\n}\n", + "a {\n color: \"abcXd\";\n}\n" +); +test!( + str_insert_no_quotes, + "a {\n color: str-insert(abcd, \"X\", 4);\n}\n", + "a {\n color: abcXd;\n}\n" +); +test!( + str_insert_empty_string, + "a {\n color: str-insert(abcd, \"\", 4);\n}\n", + "a {\n color: abcd;\n}\n" +);