Mirror of espurna firmware for wireless switches and more
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

199 lines
4.5 KiB

/*
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