commit 051ab22004c2f32a0b64d147ac289a7b00f78be9
parent 14d4abd2b8a602420a12b2f4ab1f4e706d7299ee
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 25 Nov 2022 11:32:01 +0100
strings::template: support ${var} syntax
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/strings/template/README b/strings/template/README
@@ -4,7 +4,9 @@ with [[execute]] to print formatted text to an [[io::handle]].
The template format is a string with variable substituted using "$". Variable
names must be alphanumeric ASCII characters (i.e. for which [[ascii::isalnum]]
-returns true). A literal "$" may be printed by using it twice: "$$".
+returns true). A literal "$" may be printed by using it twice: "$$". Variables
+may also be used with braces, i.e. ${variable}, so that they can be placed
+immediately next to alphanumeric characters.
const src = "Hello, $user! Your balance is $$$balance.\n";
const template = template::compile(src)!;
diff --git a/strings/template/template.ha b/strings/template/template.ha
@@ -1,6 +1,5 @@
// License: MPL-2.0
// (c) 2022 Drew DeVault <sir@cmpwn.com>
-// TODO: Add ${whatever:x}-style formatting
use ascii;
use errors;
use fmt;
@@ -112,6 +111,18 @@ fn parse_variable(
iter: *strings::iterator,
buf: *strio::stream,
) (void | errors::invalid) = {
+ let brace = false;
+ match (strings::next(iter)) {
+ case let rn: rune =>
+ if (rn == '{') {
+ brace = true;
+ } else {
+ strings::prev(iter);
+ };
+ case =>
+ return errors::invalid;
+ };
+
for (true) {
const rn = match (strings::next(iter)) {
case let rn: rune =>
@@ -120,11 +131,19 @@ fn parse_variable(
return errors::invalid;
};
- if (ascii::isalnum(rn)) {
- strio::appendrune(buf, rn)!;
+ if (brace) {
+ if (rn != '}') {
+ strio::appendrune(buf, rn)!;
+ } else {
+ break;
+ };
} else {
- strings::prev(iter);
- break;
+ if (ascii::isalnum(rn)) {
+ strio::appendrune(buf, rn)!;
+ } else {
+ strings::prev(iter);
+ break;
+ };
};
};
@@ -133,7 +152,7 @@ fn parse_variable(
strio::reset(buf);
};
-def test_input: str = `Dear $recipient,
+def test_input: str = `Dear ${recipient},
I am the crown prince of $country. Your brother, $brother, has recently passed
away in my country. I am writing to you to facilitate the transfer of his