#pragma once #include #include #include namespace jinja { // allow differentiate between user input strings and template strings // transformations should handle this information as follows: // - one-to-one (e.g., uppercase, lowercase): preserve is_input flag // - one-to-many (e.g., strip): if input string is marked as is_input, all resulting parts should be marked as is_input // - many-to-one (e.g., concat): if ALL input parts are marked as is_input, resulting part should be marked as is_input struct string_part { bool is_input = false; // may skip parsing special tokens if true std::string val; bool is_uppercase() const; bool is_lowercase() const; }; struct string { std::vector parts; string() = default; string(const std::string & v, bool user_input = false) { parts.push_back({user_input, v}); } string(int v) { parts.push_back({false, std::to_string(v)}); } string(double v) { parts.push_back({false, std::to_string(v)}); } // mark all parts as user input void mark_input(); std::string str() const; size_t length() const; bool all_parts_are_input() const; bool is_uppercase() const; bool is_lowercase() const; // mark this string as input if other has ALL parts as input void mark_input_based_on(const string & other); string append(const string & other); // in-place transformations string uppercase(); string lowercase(); string capitalize(); string titlecase(); string strip(bool left, bool right, std::optional chars = std::nullopt); }; } // namespace jinja