39namespace morph::forms::detail {
49template <std::
size_t N>
50[[nodiscard]]
consteval std::size_t escapedPartWidth(const ::morph::detail::FixedString<N>& text)
noexcept {
51 std::size_t width = 0;
52 for (
char const character :
text.view()) {
53 width += (character ==
'_') ? 2U : 1U;
66template <std::
size_t N>
67[[nodiscard]]
consteval bool hasBoundaryUnderscore(const ::morph::detail::FixedString<N>& text)
noexcept {
68 std::string_view
const view =
text.view();
69 return !view.empty() && (view.front() ==
'_' || view.back() ==
'_');
99template <::morph::detail::FixedString OptionsAction, ::morph::detail::FixedString ValueField,
100 ::morph::detail::FixedString LabelField, ::morph::detail::FixedString... DependsOn>
101inline constexpr auto choiceSchemaNameStorage = [] {
102 static_assert(!hasBoundaryUnderscore(OptionsAction) && !hasBoundaryUnderscore(ValueField) &&
103 !hasBoundaryUnderscore(LabelField) && !(hasBoundaryUnderscore(DependsOn) || ...),
104 "Choice: an options action or field name may not begin or end with '_' -- the schema key that "
105 "keeps two Choice instantiations apart cannot be composed unambiguously from such a name");
107 constexpr std::string_view prefix{
"Choice_"};
108 constexpr std::size_t total = prefix.size() + escapedPartWidth(OptionsAction) + 1U + escapedPartWidth(ValueField) +
109 1U + escapedPartWidth(LabelField) +
110 ((1U + escapedPartWidth(DependsOn)) + ... + std::size_t{0});
112 std::array<char, total> out{};
113 std::size_t written = 0;
117 auto append = [&out, &written](std::string_view part) {
118 for (
char const character : part) {
120 out[written] = character;
126 auto appendPart = [&out, &written](std::string_view part) {
127 for (
char const character : part) {
129 out[written] = character;
131 if (character ==
'_') {
133 out[written] = character;
140 appendPart(OptionsAction.
view());
142 appendPart(ValueField.view());
144 appendPart(LabelField.view());
145 ((
append(
"_"), appendPart(DependsOn.view())), ...);
162template <::morph::detail::FixedString OptionsAction, ::morph::detail::FixedString ValueField,
163 ::morph::detail::FixedString LabelField, ::morph::detail::FixedString... DependsOn>
164inline constexpr std::string_view choiceSchemaName{
165 choiceSchemaNameStorage<OptionsAction, ValueField, LabelField, DependsOn...>.
data(),
166 choiceSchemaNameStorage<OptionsAction, ValueField, LabelField, DependsOn...>.size()};
180 std::array<char, 16> characters{};
182 std::size_t size = 0;
186 constexpr void append(std::string_view text)
noexcept {
187 for (
char const character : text) {
189 characters[size] = character;
196 constexpr void appendDecimal(std::size_t value)
noexcept {
197 std::array<char, 20> digits{};
198 std::size_t
count = 0;
201 digits[
count] =
static_cast<char>(
'0' +
static_cast<char>(value % 10U));
206 digits.front() =
'0';
212 characters[size] = digits[
count];
219 [[nodiscard]]
constexpr std::string_view view() const noexcept {
return {characters.data(), size}; }
234inline constexpr bool isCharacterType =
235 std::same_as<T, char> || std::same_as<T, char8_t> || std::same_as<T, char16_t> || std::same_as<T, char32_t> ||
236 std::same_as<T, wchar_t>;
254 requires std::is_arithmetic_v<T>
255[[nodiscard]]
consteval ShapeTag numericShapeTag() {
257 if constexpr (std::same_as<T, bool>) {
260 if constexpr (isCharacterType<T>) {
262 }
else if constexpr (std::floating_point<T>) {
264 }
else if constexpr (std::is_signed_v<T>) {
269 tag.appendDecimal(
sizeof(T) * 8U);
280 requires std::is_arithmetic_v<T>
281inline constexpr auto rangedSchemaNameStorage = [] {
283 key.append(
"Ranged_");
284 key.append(numericShapeTag<T>().view());
299 requires std::is_arithmetic_v<T>
300inline constexpr std::string_view rangedSchemaName = rangedSchemaNameStorage<T>.view();
Node text(TextOptions const &options)
A text node.
Handle< std::int64_t > count(AnyHandle const &list)
count: a list's length.
void append(Json &json, char const *key, Json item)
Appends item to the array at key of json, making the array on first use.
Shared compile-time, NTTP-capable fixed string.
constexpr std::string_view view() const noexcept
A view of the string (without the terminating null).
std::array< char, N > data
Character storage (null-terminated).