486 lines
23 KiB
C++
486 lines
23 KiB
C++
#ifndef MATADOR_CONVERT_HPP
|
|
#define MATADOR_CONVERT_HPP
|
|
|
|
#include "matador/utils/types.hpp"
|
|
#include "matador/utils/result.hpp"
|
|
|
|
#include <array>
|
|
#include <charconv>
|
|
#include <cstring>
|
|
#include <iomanip>
|
|
#include <string>
|
|
#include <type_traits>
|
|
|
|
/*
|
|
* Conversion matrix
|
|
* from> | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | bool | float | double | string | date | time | timestamp | blob | null
|
|
* to | | | | | | | | | | | | | | | | |
|
|
* ------------+------+-------+-------+-------+-------+--------+--------+--------+------+-------+--------+--------+------+------+-----------+------+-----
|
|
* int8 | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | ok | ok | ok | try | N/A
|
|
* int16 | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | ok | ok | ok | try | N/A
|
|
* int32 | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | ok | ok | ok | try | N/A
|
|
* int64 | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | ok | ok | ok | try | N/A
|
|
* uint8 | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | ok | ok | ok | try | N/A
|
|
* uint16 | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | ok | ok | ok | try | N/A
|
|
* uint32 | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | ok | ok | ok | try | N/A
|
|
* uint64 | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | ok | ok | ok | try | N/A
|
|
* bool | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | N/A | N/A | ok | try | N/A
|
|
* float | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | N/A | N/A | ok | try | N/A
|
|
* double | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | try | N/A | N/A | ok | try | N/A
|
|
* string | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | N/A | N/A
|
|
* date | ok | ok | ok | ok | ok | ok | ok | ok | N/A | N/A | N/A | try | ok | ok | ok | N/A | N/A
|
|
* time | ok | ok | ok | ok | ok | ok | ok | ok | N/A | N/A | N/A | try | ok | ok | ok | N/A | N/A
|
|
* timestamp | ok | ok | ok | ok | ok | ok | ok | ok | N/A | N/A | N/A | try | ok | ok | ok | N/A | N/A
|
|
* blob | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | N/A
|
|
* null | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | ok | ok
|
|
*
|
|
* from integral to date/time works, value is interpreted as std::chrono::timepoint
|
|
* from integral to blob works, bytes of integral data will converted to blob
|
|
* from boolean to blob works, byte of bool data will converted to blob
|
|
* from floating point to blob works, bytes of floating point data will converted to blob
|
|
* from date to blob works, bytes of date will converted to blob
|
|
* from time to blob works, bytes of time will converted to blob
|
|
* from string to blob works, bytes of string data will converted to blob
|
|
* from floating point to integral works, fractions are truncated
|
|
* from date/time to integral works, value will be converted from std::chrono::timepoint
|
|
* from blob to integral works, value will be converted missing is filled with zero, rest is omitted
|
|
* from blob to floating point works, value will be converted missing is filled with zero, rest is omitted
|
|
* from blob to boolean works, value will be converted missing is filled with zero, rest is omitted
|
|
*/
|
|
|
|
namespace matador::utils {
|
|
|
|
enum class conversion_error {
|
|
Ok,
|
|
NotConvertable,
|
|
MissingData
|
|
};
|
|
|
|
enum class conversion_policy {
|
|
Strict,
|
|
Relax
|
|
};
|
|
|
|
|
|
// template < typename DestType, typename SourceType >
|
|
// result<DestType, conversion_error> to(const SourceType &/*from*/);
|
|
// result<DestType, conversion_error> to(const SourceType &/*from*/, conversion_policy /*policy*/ = conversion_policy::Strict);
|
|
|
|
// {
|
|
// return failure(conversion_error::NotConvertable);
|
|
// }
|
|
|
|
/*
|
|
* Integral, Floating point & bool conversion
|
|
*/
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_arithmetic_v<DestType> && std::is_arithmetic_v<SourceType>>* = nullptr)
|
|
{
|
|
return ok(static_cast<DestType>(source));
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_same_v<std::string, DestType> && std::is_same_v<std::string, SourceType>>* = nullptr)
|
|
{
|
|
return ok(source);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_integral_v<SourceType> && !std::is_same_v<bool, SourceType> && std::is_same_v<DestType, std::string>>* = nullptr)
|
|
{
|
|
std::array<char, 128> buffer{};
|
|
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), source, 10);
|
|
if (ec == std::errc{}) {
|
|
return ok(std::string(buffer.data(), ptr));
|
|
}
|
|
|
|
return failure(conversion_error::NotConvertable/*, "couldn't convert value to std::string"}*/);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_floating_point_v<SourceType> && std::is_same_v<DestType, std::string>>* = nullptr)
|
|
{
|
|
std::array<char, 128> buffer{};
|
|
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), source, std::chars_format::general);
|
|
if (ec == std::errc{}) {
|
|
return ok(std::string(buffer.data(), ptr));
|
|
}
|
|
|
|
return failure(conversion_error::NotConvertable/*, "couldn't convert value to std::string"}*/);
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_integral_v<DestType> && std::is_signed_v<DestType>>* = nullptr)
|
|
{
|
|
if (source.empty()) {
|
|
return failure(conversion_error::MissingData/*, "failed to convert empty string"}*/);
|
|
}
|
|
char *end;
|
|
errno = 0;
|
|
const auto result = strtoll(source.c_str(), &end, 10);
|
|
if (errno == ERANGE) {
|
|
return failure(conversion_error::NotConvertable/*, "failed to convert string value"}*/);
|
|
}
|
|
|
|
return ok(static_cast<DestType>(result));
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_integral_v<DestType> && std::is_unsigned_v<DestType> && !std::is_same_v<DestType, bool>>* = nullptr)
|
|
{
|
|
if (source.empty()) {
|
|
return failure(conversion_error::MissingData/*, "failed to convert empty string"}*/);
|
|
}
|
|
char *end;
|
|
errno = 0;
|
|
const auto result = strtoull(source.c_str(), &end, 10);
|
|
if (errno == ERANGE) {
|
|
return failure(conversion_error::NotConvertable/*, "failed to convert string value"}*/);
|
|
}
|
|
|
|
return ok(static_cast<DestType>(result));
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_floating_point_v<DestType>>* = nullptr)
|
|
{
|
|
if (source.empty()) {
|
|
return failure(conversion_error::MissingData/*, "failed to convert empty string"}*/);
|
|
}
|
|
char *end;
|
|
errno = 0;
|
|
const auto result = strtod(source.c_str(), &end);
|
|
if (errno == ERANGE) {
|
|
return failure(conversion_error::NotConvertable/*, "failed to convert string value"}*/);
|
|
}
|
|
|
|
return ok(static_cast<DestType>(result));
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const blob_type_t &source, std::enable_if_t<std::is_same_v<DestType, blob_type_t>>* = nullptr) {
|
|
return ok(source);
|
|
}
|
|
|
|
// template < typename DestType >
|
|
// result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, blob>>* = nullptr) {
|
|
// if (source.empty()) {
|
|
// return failure(conversion_error::MissingData/*, "failed to convert empty string"}*/);
|
|
// }
|
|
//
|
|
// }
|
|
//
|
|
static std::unordered_map<std::string, bool> string_to_bool_map = {
|
|
{"true", true},
|
|
{"t", true},
|
|
{"on", true},
|
|
{"1", true},
|
|
{"false", false},
|
|
{"f", false},
|
|
{"off", false},
|
|
{"0", false}
|
|
};
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, bool>>* = nullptr) {
|
|
if (source.empty()) {
|
|
return failure(conversion_error::MissingData);
|
|
}
|
|
const auto it = string_to_bool_map.find(source);
|
|
if (it == string_to_bool_map.end()) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
return ok(it->second);
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const char *source, std::enable_if_t<std::is_same_v<DestType, bool>>* = nullptr) {
|
|
if (strlen(source) == 0) {
|
|
return failure(conversion_error::MissingData);
|
|
}
|
|
const auto it = string_to_bool_map.find(source);
|
|
if (it == string_to_bool_map.end()) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
return ok(it->second);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_same_v<SourceType, bool> &&std::is_same_v<DestType, std::string>>* = nullptr) {
|
|
return ok(std::string(source ? "true" : "false"));
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<SourceType, blob_type_t> &&std::is_same_v<DestType, std::string>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_same_v<SourceType, const char*> &&std::is_same_v<DestType, std::string>>* = nullptr) {
|
|
if (source == nullptr) {
|
|
return ok(std::string{});
|
|
}
|
|
return ok(std::string(source));
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_arithmetic_v<DestType> && std::is_same_v<SourceType, blob_type_t>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_integral_v<SourceType> && std::is_same_v<DestType, blob_type_t>>* = nullptr) {
|
|
DestType result;
|
|
result.resize(sizeof(source));
|
|
std::memcpy(result.data(), &source, sizeof(source));
|
|
|
|
return ok(result);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<SourceType> && std::is_same_v<DestType, blob_type_t>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<SourceType, std::string> && std::is_same_v<DestType, blob_type_t>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<SourceType, const char*> && std::is_same_v<DestType, blob_type_t>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, date_type_t>>* = nullptr) {
|
|
std::tm result{};
|
|
std::istringstream iss(source);
|
|
iss >> std::get_time(&result, "%Y-%m-%d");
|
|
if (iss.fail()) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
return ok(date_type_t{result.tm_year + 1900, static_cast<uint8_t>(result.tm_mon + 1), static_cast<uint8_t>(result.tm_mday)});
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const char *source, std::enable_if_t<std::is_same_v<DestType, date_type_t>>* = nullptr) {
|
|
return to<DestType>(std::string{source});
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, time_type_t>>* = nullptr) {
|
|
std::tm result{};
|
|
std::istringstream iss(source);
|
|
iss >> std::get_time(&result, "%H:%M:%S");
|
|
if (iss.fail()) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
return ok(time_type_t{static_cast<uint8_t>(result.tm_hour), static_cast<uint8_t>(result.tm_min), static_cast<uint8_t>(result.tm_sec)});
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const char *source, std::enable_if_t<std::is_same_v<DestType, time_type_t>>* = nullptr) {
|
|
return to<DestType>(std::string{source});
|
|
}
|
|
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, timestamp>>* = nullptr) {
|
|
std::tm result{};
|
|
std::istringstream iss(source);
|
|
iss >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
|
|
if (iss.fail()) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
const std::time_t tt = std::mktime(&result);
|
|
if (tt == -1) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
return ok(std::chrono::system_clock::from_time_t(tt));
|
|
}
|
|
|
|
template < typename DestType >
|
|
result<DestType, conversion_error> to(const char *source, std::enable_if_t<std::is_same_v<DestType, timestamp>>* = nullptr) {
|
|
return to<DestType>(std::string{source});
|
|
}
|
|
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<DestType> && !std::is_same_v<bool, DestType> && std::is_same_v<date_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<DestType> && !std::is_same_v<bool, DestType> && std::is_same_v<time_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<DestType> && !std::is_same_v<bool, DestType> && std::is_same_v<timestamp, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<bool, DestType> && std::is_same_v<date_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<bool, DestType> && std::is_same_v<time_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<bool, DestType> && std::is_same_v<timestamp, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<DestType> && std::is_same_v<date_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<DestType> && std::is_same_v<time_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<DestType> && std::is_same_v<timestamp, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<blob_type_t, DestType> && std::is_same_v<date_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<blob_type_t, DestType> && std::is_same_v<time_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<blob_type_t, DestType> && std::is_same_v<timestamp, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<std::string, DestType> && std::is_same_v<date_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<std::string, DestType> && std::is_same_v<time_type_t, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_same_v<std::string, DestType> && std::is_same_v<timestamp, SourceType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<SourceType> && !std::is_same_v<bool, SourceType> && std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<SourceType> && !std::is_same_v<bool, SourceType> && std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<SourceType> && !std::is_same_v<bool, SourceType> && std::is_same_v<timestamp, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<SourceType> && std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<SourceType> && std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType, typename SourceType >
|
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<SourceType> && std::is_same_v<timestamp, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const blob_type_t &/*source*/, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const blob_type_t &/*source*/, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const blob_type_t &/*source*/, std::enable_if_t<std::is_same_v<timestamp, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const bool &/*source*/, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const bool &/*source*/, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const bool &/*source*/, std::enable_if_t<std::is_same_v<timestamp, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const time_type_t &/*source*/, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const time_type_t &source, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
|
return ok(source);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const date_type_t &/*source*/, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
|
return failure(conversion_error::NotConvertable);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const date_type_t &source, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
|
return ok(source);
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const timestamp &source, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
|
const std::time_t tt = std::chrono::system_clock::to_time_t(source);
|
|
|
|
const std::tm* result = std::localtime(&tt);
|
|
|
|
return ok(time_type_t{static_cast<uint8_t>(result->tm_hour), static_cast<uint8_t>(result->tm_min), static_cast<uint8_t>(result->tm_sec)});
|
|
}
|
|
|
|
template < typename DestType>
|
|
result<DestType, conversion_error> to(const timestamp &source, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
|
const std::time_t tt = std::chrono::system_clock::to_time_t(source);
|
|
|
|
const std::tm* result = std::localtime(&tt);
|
|
|
|
return ok(date_type_t{result->tm_year + 1900, static_cast<uint8_t>(result->tm_mon + 1), static_cast<uint8_t>(result->tm_mday)});
|
|
}
|
|
|
|
}
|
|
|
|
#endif //MATADOR_CONVERT_HPP
|