Aria
2.0.0
C++23 MVVM framework (C++20 minimum) — reactive, coroutine-first, ABI-layered
Toggle main menu visibility
Loading...
Searching...
No Matches
converter.hpp
Go to the documentation of this file.
1
#pragma once
2
3
#include "
aria/inplace_function.hpp
"
4
5
#include <cstdio>
6
#include <functional>
7
#include <optional>
8
#include <stdexcept>
9
#include <string>
10
#include <utility>
11
12
namespace
aria::binding
{
13
19
class
ConversionError
:
public
std::runtime_error {
20
public
:
21
using
std::runtime_error::runtime_error;
22
};
23
43
template
<
typename
T,
typename
U>
44
struct
Converter
{
45
std::function<U(
const
T&)>
to_view
;
46
std::function<T(
const
U&)>
to_model
;
47
std::function<std::optional<T>(
const
U&)>
try_to_model
;
48
};
49
50
namespace
converters
{
51
52
inline
Converter<std::string, std::string>
identity_string
() {
53
return
{
54
[](
const
std::string& s) {
return
s; },
55
[](
const
std::string& s) {
return
s; },
56
[](
const
std::string& s) -> std::optional<std::string> {
return
s; }
57
};
58
}
59
60
inline
Converter<int, std::string>
int_to_string
() {
61
return
{
62
[](
const
int
& v) {
return
std::to_string(v); },
63
[](
const
std::string& s) ->
int
{
64
try
{
65
std::size_t consumed = 0;
66
int
v = std::stoi(s, &consumed);
67
// Reject trailing garbage (e.g. "12abc"): stoi returns 12
68
// but `consumed < s.size()` exposes the truncation.
69
if
(consumed != s.size()) {
70
throw
ConversionError
{
"int_to_string: trailing chars"
};
71
}
72
return
v;
73
}
catch
(
const
ConversionError
&) {
74
throw
;
75
}
catch
(...) {
76
throw
ConversionError
{
"int_to_string: not an integer"
};
77
}
78
},
79
[](
const
std::string& s) -> std::optional<int> {
80
try
{
81
std::size_t consumed = 0;
82
int
v = std::stoi(s, &consumed);
83
if
(consumed != s.size())
return
std::nullopt;
84
return
v;
85
}
catch
(...) {
86
return
std::nullopt;
87
}
88
}
89
};
90
}
91
92
inline
Converter<double, std::string>
double_to_string
(
int
precision = 2) {
93
auto
to_view = [precision](
const
double
& v) {
94
const
int
length = std::snprintf(
nullptr
, 0,
"%.*f"
, precision, v);
95
if
(length < 0)
throw
ConversionError
{
"double_to_string: formatting failed"
};
96
std::string text(
static_cast<
std::size_t
>
(length),
'\0'
);
97
std::snprintf(text.data(), text.size() + 1,
"%.*f"
, precision, v);
98
return
text;
99
};
100
auto
to_model_strict = [](
const
std::string& s) ->
double
{
101
try
{
102
std::size_t consumed = 0;
103
double
v = std::stod(s, &consumed);
104
if
(consumed != s.size()) {
105
throw
ConversionError
{
"double_to_string: trailing chars"
};
106
}
107
return
v;
108
}
catch
(
const
ConversionError
&) {
109
throw
;
110
}
catch
(...) {
111
throw
ConversionError
{
"double_to_string: not a number"
};
112
}
113
};
114
auto
try_to_model = [](
const
std::string& s) -> std::optional<double> {
115
try
{
116
std::size_t consumed = 0;
117
double
v = std::stod(s, &consumed);
118
if
(consumed != s.size())
return
std::nullopt;
119
return
v;
120
}
catch
(...) {
121
return
std::nullopt;
122
}
123
};
124
return
{ std::move(to_view), std::move(to_model_strict), std::move(try_to_model) };
125
}
126
127
inline
Converter<bool, std::string>
bool_to_yes_no
() {
128
return
{
129
[](
const
bool
& v) -> std::string {
return
v ?
"yes"
:
"no"
; },
130
[](
const
std::string& s) {
131
if
(s ==
"yes"
|| s ==
"true"
|| s ==
"1"
)
return
true
;
132
if
(s ==
"no"
|| s ==
"false"
|| s ==
"0"
)
return
false
;
133
throw
ConversionError
{
"bool_to_yes_no: not a boolean"
};
134
},
135
[](
const
std::string& s) -> std::optional<bool> {
136
if
(s ==
"yes"
|| s ==
"true"
|| s ==
"1"
)
return
true
;
137
if
(s ==
"no"
|| s ==
"false"
|| s ==
"0"
)
return
false
;
138
return
std::nullopt;
139
}
140
};
141
}
142
143
}
// namespace converters
144
}
// namespace aria::binding
aria::binding::ConversionError
Thrown by built-in Converter::to_model when the user-provided string cannot be parsed into the target...
Definition
converter.hpp:19
inplace_function.hpp
aria::binding::converters
Definition
converter.hpp:50
aria::binding::converters::bool_to_yes_no
Converter< bool, std::string > bool_to_yes_no()
Definition
converter.hpp:127
aria::binding::converters::identity_string
Converter< std::string, std::string > identity_string()
Definition
converter.hpp:52
aria::binding::converters::int_to_string
Converter< int, std::string > int_to_string()
Definition
converter.hpp:60
aria::binding::converters::double_to_string
Converter< double, std::string > double_to_string(int precision=2)
Definition
converter.hpp:92
aria::binding
Definition
binding_engine.hpp:25
aria::binding::Converter
Bidirectional converter between Model type T and View type U.
Definition
converter.hpp:44
aria::binding::Converter::try_to_model
std::function< std::optional< T >(const U &)> try_to_model
Definition
converter.hpp:47
aria::binding::Converter::to_view
std::function< U(const T &)> to_view
Definition
converter.hpp:45
aria::binding::Converter::to_model
std::function< T(const U &)> to_model
Definition
converter.hpp:46
modules
binding
include
aria
binding
converter.hpp
Generated by
1.18.0