LCOV - code coverage report
Current view: top level - wirestead/config - validation.hpp (source / functions) Coverage Total Hit
Test: Wirestead Coverage Report Lines: 100.0 % 34 34
Test Date: 2026-10-29 11:36:05 Functions: 100.0 % 20 20
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 88.6 % 44 39

             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
        

Generated by: LCOV version 2.0-1