Branch data Line data Source code
1 : : /*
2 : : * Copyright 2025 Jinwoo Sung
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #pragma once
18 : : #include <cctype>
19 : : #include <chrono>
20 : : #include <cstdint>
21 : : #include <initializer_list>
22 : : #include <limits>
23 : : #include <stdexcept>
24 : : #include <string_view>
25 : : #include <type_traits>
26 : : #include <utility>
27 : :
28 : : #include "wirestead/base/constants.hpp"
29 : :
30 : : namespace wirestead::config::detail {
31 : 9212 : inline void require(bool valid, const char* message) {
32 [ + + + - ]: 9212 : if (!valid) throw std::invalid_argument(message);
33 : 9134 : }
34 : : template <class T, class L, class H>
35 : 2030 : void range(T value, L low, H high, const char* name) {
36 [ + + + + ]: 2030 : require(!std::cmp_less(value, low) && !std::cmp_greater(value, high), name);
37 : 2000 : }
38 : 2906 : inline void strategy(base::constants::BackpressureStrategy value) {
39 [ + + + + ]: 2906 : require(value == base::constants::BackpressureStrategy::Reliable ||
40 : : value == base::constants::BackpressureStrategy::BestEffort,
41 : : "invalid backpressure strategy");
42 : 2902 : }
43 : 272 : inline void duration(std::chrono::milliseconds value, uint64_t low, uint64_t high, bool zero, const char* name) {
44 [ + + + + : 272 : if (zero && value.count() == 0) return;
+ + ]
45 : 271 : range(value.count(), low, high, name);
46 : : }
47 : 34 : inline void text_option(std::string_view value, std::initializer_list<std::string_view> choices, const char* name) {
48 [ + + ]: 85 : for (auto choice : choices) {
49 [ + + ]: 79 : if (value.size() != choice.size()) continue;
50 : 44 : bool equal = true;
51 [ + + ]: 197 : for (size_t i = 0; i < value.size(); ++i)
52 [ + + ]: 169 : if (std::tolower(static_cast<unsigned char>(value[i])) != choice[i]) {
53 : 16 : equal = false;
54 : 16 : break;
55 : : }
56 [ + + ]: 44 : if (equal) return;
57 : : }
58 : 6 : require(false, name);
59 : : }
60 : : template <class Config>
61 : 2275 : void validate(const Config& config) {
62 : 2275 : require(config.is_valid(), "invalid transport configuration");
63 : 2257 : strategy(config.backpressure_strategy);
64 : : if constexpr (requires { config.idle_timeout_action; })
65 [ + + ]: 937 : require(config.idle_timeout_action == IdleTimeoutAction::Close ||
66 [ + - ]: 467 : config.idle_timeout_action == IdleTimeoutAction::Reconnect,
67 : : "invalid idle timeout action");
68 : : if constexpr (requires { config.max_connections; })
69 : 485 : range(config.max_connections, 0, base::constants::MAX_MAX_CONNECTIONS, "invalid connection limit");
70 : : if constexpr (requires { config.max_port_retries; }) {
71 : 298 : range(config.max_port_retries, 0, base::constants::MAX_RETRIES_LIMIT, "invalid port retry count");
72 : 298 : range(config.port_retry_interval_ms, base::constants::MIN_RETRY_INTERVAL_MS, base::constants::MAX_RETRY_INTERVAL_MS,
73 : : "invalid port retry interval");
74 : 298 : require(config.tls_certificate_file.empty() == config.tls_private_key_file.empty(),
75 : : "TLS requires certificate and key");
76 : : }
77 : : if constexpr (requires { config.parity; }) {
78 : : using C = std::decay_t<Config>;
79 [ + + + + : 327 : require(config.parity == C::Parity::None || config.parity == C::Parity::Even || config.parity == C::Parity::Odd,
+ - ]
80 : : "invalid parity");
81 [ + + + - : 327 : require(config.flow == C::Flow::None || config.flow == C::Flow::Software || config.flow == C::Flow::Hardware,
+ - ]
82 : : "invalid flow control");
83 : : }
84 : 2255 : }
85 : : } // namespace wirestead::config::detail
|