10uint64_t Spell::generate_id() {
11 static std::atomic<uint64_t> next_id{1};
12 return next_id.fetch_add(1);
18 : transform_([](const
RuneSequence& input) {
return input; })
20 , description_(
"Identity transformation (no change)")
22 , is_composition_(
false)
23 , composition_depth_(1) {
29 : transform_(
std::move(transform))
33 , is_composition_(false)
34 , composition_depth_(1) {
40 return transform_(input);
45 auto result = transform_(sequence);
46 return result.to_utf8();
52 auto composed_transform = [this_transform = transform_, next_transform = next.transform_]
54 auto intermediate = this_transform(input);
55 return next_transform(intermediate);
58 std::string composed_name = name_ +
"|" + next.name_;
59 std::string composed_description = description_ +
" → " + next.description_;
61 Spell result(composed_transform, composed_name, composed_description);
62 result.is_composition_ =
true;
63 result.composition_depth_ = composition_depth_ + next.composition_depth_;
71 return name_ ==
"Identity" && !is_composition_;
77 std::ostringstream oss;
80 oss <<
", name=\"" << name_ <<
"\"";
81 oss <<
", description=\"" << description_ <<
"\"";
82 oss <<
", composition=" << (is_composition_ ?
"true" :
"false");
83 oss <<
", depth=" << composition_depth_;
89 return transform_(test_input);
99 auto transform = [result = std::move(constant_result)]
104 return Spell(transform,
"Constant",
"Always returns the same result");
108 const Spell& if_true,
109 const Spell& if_false) {
110 auto transform = [condition, if_true, if_false]
112 if (condition(input)) {
113 return if_true(input);
115 return if_false(input);
119 std::string
name =
"Conditional(" + if_true.
name() +
"/" + if_false.
name() +
")";
131Spell operator""_spell(
const char* replacement_rule,
size_t len) {
132 std::string rule(replacement_rule, len);
135 auto arrow_pos = rule.find(
" -> ");
136 if (arrow_pos == std::string::npos) {
141 std::string old_text = rule.substr(0, arrow_pos);
142 std::string new_text = rule.substr(arrow_pos + 4);
145 auto utf8_input = input.to_utf8();
148 std::string result = utf8_input;
150 while ((pos = result.find(old_text, pos)) != std::string::npos) {
151 result.replace(pos, old_text.length(), new_text);
152 pos += new_text.length();
158 std::string name =
"Replace(\"" + old_text +
"\" -> \"" + new_text +
"\")";
159 std::string description =
"Replace \"" + old_text +
"\" with \"" + new_text +
"\"";
161 return Spell(transform, name, description);
static RuneString from_utf8(std::string_view utf8_text)
Create a RuneString from UTF-8 text.
Unified spell object for text transformation.
RuneSequence test(const RuneSequence &test_input) const
Test the spell with sample input.
Spell operator|(const Spell &next) const
Compose with another spell (pipeline operator)
std::function< RuneSequence(const RuneSequence &)> transform_function
bool is_identity() const noexcept
Check if this spell is the identity transformation.
std::string to_string() const
Get a detailed string representation.
static Spell constant(RuneSequence constant_result)
Create a spell that always returns the same result.
const std::string & description() const noexcept
Get the spell description.
std::function< bool(const RuneSequence &)> validation_function
RuneSequence operator()(const RuneSequence &input) const
Apply the spell transformation.
static Spell identity()
Create an identity spell (no transformation)
const std::string & name() const noexcept
Get the spell name.
Spell() noexcept
Default constructor (identity spell)
static Spell conditional(validation_function condition, const Spell &if_true, const Spell &if_false)
Create a conditional spell.
RuneString RuneSequence
Backward compatibility alias for RuneString.