2025-03-07 22:15:49 +01:00

116 lines
2.2 KiB
C++

namespace seafire::protocol::rfc7232
{
inline
if_match_t::
if_match_t(anything_t)
: value_{anything}
{}
inline
if_match_t::
if_match_t(std::vector<entity_tag_t> tags)
: value_{std::move(tags)}
{}
inline
bool
if_match_t::
is_anything() const
{
return std::holds_alternative<anything_t>(value_);
}
inline
std::vector<entity_tag_t> const&
if_match_t::
tags() const
{
if (std::holds_alternative<std::vector<entity_tag_t>>(value_))
return std::get<std::vector<entity_tag_t>>(value_);
throw std::invalid_argument{"invalid if-match"};
}
inline
std::optional<if_match_t>
if_match_t::
try_parse(std::vector<std::string> const& strings,
std::error_code& ec)
{
std::vector<entity_tag_t> tags;
for (auto const& j : strings) {
auto it = j.begin();
while (it != j.end()) {
grammar::skip_space(it, j.end());
if (it != j.end() && *it == '*') {
++it; // consume '*'
grammar::skip_space(it, j.end());
if (it != j.end() || tags.size() > 0) {
ec = make_error_code(protocol_error_t::invalid_header_value);
return std::nullopt;
}
return anything;
}
auto tag = entity_tag_t::try_parse(it, j.end(), ec);
if (ec)
return std::nullopt;
if (!tag) {
ec = make_error_code(protocol_error_t::invalid_header_value);
return std::nullopt;
}
tags.emplace_back(std::move(*tag));
grammar::skip_space(it, j.end());
if (it != j.end()) {
if (*it != ',') {
ec = make_error_code(protocol_error_t::invalid_header_value);
return std::nullopt;
}
++it;
}
}
}
if (tags.empty())
return {};
return tags;
}
inline
std::string
to_string(if_match_t const& if_match)
{
if (if_match.is_anything())
return "*";
std::ostringstream str;
auto it = if_match.tags().begin();
if (it != if_match.tags().end())
str << to_string(*it++);
while (it != if_match.tags().end()) {
str << ", ";
str << to_string(*it++);
}
return str.str();
}
} // namespace seafire::protocol::rfc7232