|
|
- /*
-
- Part of SETTINGS MODULE
-
- Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
- Copyright (C) 2019-2023 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
-
- */
-
- #pragma once
-
- #include <Arduino.h>
-
- #include "settings_helpers.h"
-
- namespace espurna {
- namespace settings {
- namespace internal {
- namespace duration_convert {
-
- // A more loosely typed duration, so we could have a single type
- struct Pair {
- duration::Seconds seconds{};
- duration::Microseconds microseconds{};
- };
-
- struct Result {
- Pair value;
- bool ok { false };
- };
-
- template <typename T, typename Rep = typename T::rep, typename Period = typename T::period>
- std::chrono::duration<Rep, Period> to_chrono_duration(Pair result) {
- using Type = std::chrono::duration<Rep, Period>;
- return std::chrono::duration_cast<Type>(result.seconds)
- + std::chrono::duration_cast<Type>(result.microseconds);
- }
-
- // Attempt to parse the given string with the specific ratio
- // Same as chrono, std::ratio<1> is a second
- Result parse(StringView, int num, int den);
-
- template <intmax_t Num, intmax_t Den>
- Result parse(StringView view, std::ratio<Num, Den>) {
- return parse(view, Num, Den);
- }
-
- template <typename T>
- T unchecked_parse(StringView view) {
- const auto result = parse(view, typename T::period{});
- if (result.ok) {
- return to_chrono_duration<T>(result.value);
- }
-
- return T{}.min();
- }
-
- } // namespace duration_convert
-
- template <typename T>
- T convert(const String& value);
-
- template <>
- float convert(const String& value);
-
- template <>
- double convert(const String& value);
-
- template <>
- signed char convert(const String& value);
-
- template <>
- short convert(const String& value);
-
- template <>
- int convert(const String& value);
-
- template <>
- long convert(const String& value);
-
- template <>
- bool convert(const String& value);
-
- template <>
- unsigned long convert(const String& value);
-
- template <>
- unsigned int convert(const String& value);
-
- template <>
- unsigned short convert(const String& value);
-
- template <>
- unsigned char convert(const String& value);
-
- template <>
- duration::Microseconds convert(const String&);
-
- template <>
- duration::Milliseconds convert(const String&);
-
- template <>
- duration::Seconds convert(const String&);
-
- template <>
- duration::Minutes convert(const String&);
-
- template <>
- duration::Hours convert(const String&);
-
- inline String serialize(uint8_t value, int base = 10) {
- return String(value, base);
- }
-
- inline String serialize(uint16_t value, int base = 10) {
- return String(value, base);
- }
-
- String serialize(uint32_t value, int base = 10);
-
- inline String serialize(unsigned long value, int base = 10) {
- return serialize(static_cast<uint32_t>(value), base);
- }
-
- inline String serialize(int16_t value, int base = 10) {
- return String(value, base);
- }
-
- inline String serialize(int32_t value, int base = 10) {
- return String(value, base);
- }
-
- inline String serialize(int8_t value, int base = 10) {
- return serialize(static_cast<int32_t>(value), base);
- }
-
- inline String serialize(long value, int base = 10) {
- return String(value, base);
- }
-
- inline String serialize(bool value) {
- return value ? PSTR("true") : PSTR("false");
- }
-
- inline String serialize(float value) {
- return String(value, 3);
- }
-
- inline String serialize(double value) {
- return String(value, 3);
- }
-
- String serialize(duration::Microseconds);
-
- String serialize(duration::Milliseconds);
-
- String serialize(duration::Seconds);
-
- String serialize(duration::Minutes);
-
- String serialize(duration::Hours);
-
- template <typename Container, typename T>
- T convert(const Container& options, const String& value, T defaultValue) {
- if (value.length()) {
- using espurna::settings::options::Enumeration;
- using UnderlyingType = typename Enumeration<T>::UnderlyingType;
- typename Enumeration<T>::Numeric numeric;
- numeric.check(value, convert<UnderlyingType>);
-
- for (auto it = std::begin(options); it != std::end(options); ++it) {
- if (numeric && ((*it).numeric() == numeric.value())) {
- return static_cast<T>(numeric.value());
- } else if (!numeric && ((*it) == value)) {
- return (*it).value();
- }
- }
- }
-
- return defaultValue;
- }
-
- template <typename Container, typename T>
- String serialize(const Container& options, T value) {
- String out;
-
- for (auto it = std::begin(options); it != std::end(options); ++it) {
- if ((*it).value() == value) {
- out = (*it).string().toString();
- break;
- }
- }
-
- return out;
- }
-
- } // namespace internal
- } // namespace settings
- } // namespace espurna
|