Crunch
A Message Definition Language for Getting Things Right
Loading...
Searching...
No Matches
crunch_string.hpp
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <crunch/core/crunch_types.hpp>
6#include <crunch/validators/crunch_validators.hpp>
7#include <cstdint>
8#include <optional>
9#include <ranges>
10#include <span>
11#include <string_view>
12
13namespace Crunch::fields {
14
21template <std::size_t MaxSize, typename... Validators>
22 requires((Validator<Validators, std::string_view> && ...) &&
23 (sizeof...(Validators) > 0))
24class String {
25 public:
26 using ValueType = std::string_view;
27 // cppcheck-suppress unusedStructMember
28 static constexpr std::size_t max_size = MaxSize;
29
30 constexpr String() = default;
31 constexpr explicit String(std::string_view sv) {
32 static_cast<void>(set(sv));
33 }
34
35 [[nodiscard]] constexpr std::string_view get() const noexcept {
36 return std::string_view{buffer_.data(), current_len_};
37 }
38
39 constexpr std::optional<Error> set(std::string_view sv) noexcept {
40 if (sv.size() > MaxSize) {
41 // Field wrapper will attach the correct ID if available, otherwise
42 // 0.
43 return Error::capacity_exceeded(0, "string exceeds capacity");
44 }
45 if (auto err = Validate(sv); err) {
46 return err;
47 }
48
49 const std::span<char, MaxSize> buf{buffer_};
50
51 // Copy from sv and fill the rest with nulls
52 std::ranges::copy(sv, buf.begin());
53 std::ranges::fill(buf.subspan(sv.size()), '\0');
54
55 current_len_ = sv.size();
56 return std::nullopt;
57 }
58
59 constexpr void clear() noexcept {
60 current_len_ = 0;
61 std::ranges::fill(buffer_, '\0');
62 }
63
64 [[nodiscard]] constexpr bool operator==(
65 const String& other) const noexcept {
66 return get() == other.get();
67 }
68
69 [[nodiscard]] constexpr auto Validate(FieldId id = 0) const noexcept
70 -> std::optional<Error> {
71 return Validate(get(), id);
72 }
73
74 [[nodiscard]] static constexpr auto Validate(std::string_view v,
75 FieldId id = 0) noexcept
76 -> std::optional<Error> {
77 for (const auto& result : {Validators::Check(v, id)...}) {
78 if (result.has_value()) {
79 return result;
80 }
81 }
82 return std::nullopt;
83 }
84
85 std::array<char, MaxSize> buffer_{};
86 std::size_t current_len_{0};
87};
88
89template <typename T>
90struct is_string : std::false_type {};
91
92template <std::size_t MaxSize, typename... V>
93struct is_string<String<MaxSize, V...>> : std::true_type {};
94
95template <typename T>
96inline constexpr bool is_string_v = is_string<T>::value;
97
98} // namespace Crunch::fields
Fixed-size string field backed by std::array.
Definition: crunch_string.hpp:24
constexpr auto Validate(const Message &message) noexcept -> std::optional< Error >
Validates a message (field presence + message-level validation).
Definition: crunch.hpp:123
int32_t FieldId
Unique identifier for a field within a Crunch message.
Definition: crunch_types.hpp:11
static constexpr Error capacity_exceeded(FieldId id, const char(&msg)[N]) noexcept
Creates an error representing capacity exceeded. Used for strings and aggregated fields.
Definition: crunch_types.hpp:133
Definition: crunch_string.hpp:90