header_utils
Loading...
Searching...
No Matches
string_interpolate.h
1
4
5#pragma once
6
7#include "eval.h"
8#include "sexps.h"
9#include "json_helpers.h"
10
11namespace ghassanpl
12{
16
18 template <char open = '[', char close = ']', typename FUNC>
19 [[nodiscard]] std::string interpolate_simple(std::string_view str, FUNC&& func)
20 {
21 static_assert(std::invocable<FUNC, std::string_view> && std::constructible_from<std::string, std::invoke_result_t<FUNC, std::string_view>>, "function must take a stringable and return a string");
22 std::string result;
23 while (!str.empty())
24 {
25 result += string_ops::consume_until_delim_ex(str, open);
26 if (str.empty()) break;
27 if (string_ops::consume(str, open))
28 result += open;
29 else
30 {
31 auto key = string_ops::consume_until_delim_ex(str, close);
32 result += func(key);
33 }
34 }
35 return result;
36 }
37
42 template <char open = '[', char close = ']', typename FUNC>
43 [[nodiscard]] std::string interpolate_recursive(std::string_view str, FUNC&& func)
44 {
45 static_assert(std::invocable<FUNC, std::string_view> && std::constructible_from<std::string, std::invoke_result_t<FUNC, std::string_view>>, "function must take a stringable and return a string");
46 std::string result;
47 while (!str.empty())
48 {
49 result += string_ops::consume_until_delim_ex(str, open);
50 if (str.empty()) break;
51 if (string_ops::consume(str, open))
52 result += open;
53 else
54 {
55 size_t opened = 0;
56 auto key = str;
57 while (!str.empty() && (str[0] != close || opened))
58 {
59 if (str[0] == close && opened)
60 opened--;
61 else if (str[0] == open)
62 opened++;
63 str.remove_prefix(1);
64 }
65 key = { key.data(), str.data() };
66 std::ignore = string_ops::consume(str, close);
67
68 result += func(interpolate_recursive<open, close>(key, func));
69 }
70 }
71 return result;
72 }
73
75 template <bool SYNTAX>
76 [[nodiscard]] std::string interpolate_eval(std::string_view str, eval::environment<SYNTAX>& env)
77 {
78 std::string result;
79 while (!str.empty())
80 {
81 result += string_ops::consume_until(str, '[');
82 if (str.empty()) break;
83 str.remove_prefix(1);
84 if (string_ops::consume(str, '['))
85 result += '[';
86 else
87 {
88 using eval::value;
90 value call_result = env.eval(call);
91 formats::json::visit(call_result, [&](auto&& val) {
92 using std::to_string;
93 using nlohmann::to_string;
94 using ghassanpl::string_ops::to_string;
95 if constexpr (requires { { to_string(val) }; })
96 result += to_string(val);
97 });
98 }
99 }
100 return result;
101 }
102
104
106}
auto visit(nlohmann::json const &j, VISIT_FUNC &&func)
Calls func with the actual value inside j; similar to std::visit.
auto consume_list(std::string_view &sexp_str, std::array< char, 2 > braces={ '[', ']' }) -> nlohmann::json
Consumes space-delimited elements until close-brace or end-of-string.
Definition sexps.h:100
std::string interpolate_recursive(std::string_view str, FUNC &&func)
Like interpolate_simple except [group]s can be recursive, that is, can contain other groups that will...
std::string interpolate_simple(std::string_view str, FUNC &&func)
The simplest string interpolation function; calls func for every [group] in str.
std::string interpolate_eval(std::string_view str, eval::environment< SYNTAX > &env)
Interpolation using the eval module functionality.
std::string_view consume_until(std::string_view &str, FUNC &&pred)
Consumes characters from the beginning of str until one matches pred(str[0]), exclusive.
Definition string_ops.h:838
std::string_view consume_until_delim_ex(std::string_view &str, char c)
Consumes characters from the beginning of str until one is equal to c, consuming c but not including ...
Definition string_ops.h:907
char consume(std::string_view &str)
Consumes and returns the first character in the str, or \0 if no more characters.
Definition string_ops.h:702
std::string to_string(T floating_point)
float overload
Primary namespace for everything in this library.
Definition align+rec2.h:10
The primary class to store the evaluation environment, declared functions, variables,...
Definition eval.h:122
Represents a single evaluated value; can store an rvalue (as json), an lvalue (json*),...
Definition eval.h:44