• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mbits-os / quick_dra / 22038263728

15 Feb 2026 03:31PM UTC coverage: 93.378% (+6.4%) from 87.008%
22038263728

Pull #39

github

web-flow
Merge 74a89bbd4 into 7d773e4d9
Pull Request #39: testing

58 of 67 new or added lines in 23 files covered. (86.57%)

75 existing lines in 12 files now uncovered.

4033 of 4319 relevant lines covered (93.38%)

1107.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.58
/libs/libmodels/src/models/project_reader.cpp
1
// Copyright (c) 2026 midnightBITS
2
// This code is licensed under MIT license (see LICENSE for details)
3

4
#include <cmath>
5
#include <quick_dra/base/str.hpp>
6
#include <quick_dra/models/project_reader.hpp>
7

8
namespace quick_dra {
9
        bool read_value(ref_ctx const& ref, percent& ctx) {
463✔
10
                if (!ref.ref().has_val()) {
925✔
11
                        ctx = {};
×
12
                        return false;
×
13
                }
14

924✔
15
                auto const value = ref.val();
463✔
16
                if (value.empty()) {
463✔
17
                        ctx = {};
×
18
                        return false;
×
19
                }
20

924✔
21
                if (!percent::parse(view(value), ctx)) {
463✔
22
                        return ref.error("could not parse the percent value");
×
23
                }
24

924✔
25
                return true;
463✔
26
        }
925✔
27

28
        bool read_value(ref_ctx const& ref, currency& ctx) {
454✔
29
                if (!ref.ref().has_val()) {
907✔
30
                        ctx = {};
×
31
                        return false;
×
32
                }
33

906✔
34
                auto const value = ref.val();
454✔
35
                if (value.empty()) {
454✔
36
                        ctx = {};
×
37
                        return false;
×
38
                }
39

906✔
40
                if (!currency::parse(view(value), ctx)) {
454✔
41
                        return ref.error("could not parse the currency value");
×
42
                }
43

906✔
44
                return true;
454✔
45
        }
907✔
46

47
        bool read_value(ref_ctx const& ref, ratio& ctx) {
112✔
48
                static constexpr auto expecting_NUM_DEN =
222✔
49
                    "expecting N/M, e.g. 1/1 or 4/5"sv;
222✔
50

222✔
51
                if (!ref.ref().has_val()) {
223✔
52
                        ctx = {};
×
53
                        return false;
×
54
                }
55

222✔
56
                auto const value = ref.val();
112✔
57
                if (value.empty()) {
112✔
58
                        ctx = {};
×
59
                        return false;
×
60
                }
61

222✔
62
                auto const split = split_sv(view(value), '/'_sep);
112✔
63
                if (split.size() < 2) {
112✔
64
                        ctx = {};
×
65
                        return ref.error(expecting_NUM_DEN);
×
66
                }
67

222✔
68
                unsigned num{};
112✔
69
                unsigned den{};
334✔
70

222✔
71
                if (!convert_string(ref, split[0], num) ||
223✔
72
                    !convert_string(ref, split[1], den)) {
111✔
73
                        return ref.error(expecting_NUM_DEN);
×
74
                }
75

222✔
76
                ctx = {.num = num, .den = den};
112✔
77
                return true;
334✔
78
        }
334✔
79

80
        bool read_value(ref_ctx const& ref, insurance_title& ctx) {
178✔
81
                if (!ref.ref().has_val()) {
355✔
82
                        ctx = {};
×
83
                        return false;
×
84
                }
85

354✔
86
                auto const value = ref.val();
178✔
87
                if (value.empty()) {
178✔
88
                        ctx = {};
×
89
                        return false;
×
90
                }
91

354✔
92
                if (!insurance_title::parse(view(value), ctx)) {
178✔
93
                        return ref.error("could not parse the insurance title value");
×
94
                }
95

354✔
96
                return true;
178✔
97
        }
355✔
98

99
        bool read_value(ref_ctx const& ref, costs_of_obtaining& ctx) {
43✔
100
#define X(NAME)                          \
84✔
101
        if (!read_key(ref, #NAME, ctx.NAME)) \
102
                return ref.error("while reading `" #NAME "`");
103

84✔
104
                X(local)
57✔
105
                X(remote)
57✔
106
#undef X
84✔
107
                return true;
43✔
108
        }
85✔
109

110
        bool read_value(ref_ctx const& ref, rate& ctx) {
211✔
111
#define X(NAME, KEY)                         \
420✔
112
        if (!read_key(ref, KEY, ctx.NAME, true)) \
113
                return ref.error("while reading `" KEY "`");
114

420✔
115
                X(payer, "płatnik")
281✔
116
                X(insured, "ubezpieczony")
281✔
117
#undef X
420✔
118
                return true;
211✔
119
        }
421✔
120

121
        bool read_value(ref_ctx const& ref, rates& ctx) {
43✔
122
#define X(NAME, KEY)                   \
84✔
123
        if (!read_key(ref, KEY, ctx.NAME)) \
124
                return ref.error("while reading `" KEY "`");
125
                CONTRIBUTIONS_EX(X)
113✔
126
#undef X
84✔
127
                return true;
43✔
128
        }
337✔
129

130
        void write_value(ryml::NodeRef& ref, percent const& ctx) {
131
                yaml::write_value(ref, fmt::format("{}%", ctx));
×
UNCOV
132
        }
×
133
        void write_value(ryml::NodeRef& ref, currency const& ctx) {
64✔
134
                yaml::write_value(ref, fmt::format("{} zł", ctx));
253✔
135
        }
190✔
136
        void write_value(ryml::NodeRef& ref, ratio const& ctx) {
103✔
137
                yaml::write_value(ref, fmt::format("{}/{}", ctx.num, ctx.den));
409✔
138
        }
307✔
139
        void write_value(ryml::NodeRef& ref, insurance_title const& ctx) {
175✔
140
                yaml::write_value(
523✔
141
                    ref, fmt::format("{} {} {}", ctx.title_code, ctx.pension_right,
696✔
142
                                     ctx.disability_level));
522✔
143
        }
523✔
144

145
        bool convert_string(ref_ctx const& ref,
168✔
146
                            c4::csubstr const& value,
147
                            currency& ctx) {
1✔
148
                if (!currency::parse(view(value), ctx)) {
169✔
UNCOV
149
                        return ref.error("could not parse the currency value");
×
150
                }
151

336✔
152
                return true;
169✔
153
        }
337✔
154
}  // namespace quick_dra
155

156
namespace yaml {
157
        using quick_dra::operator""_sep;
158

159
        bool convert_string(ref_ctx const& ref,
462✔
160
                            c4::csubstr const& value,
161
                            std::chrono::year_month& ctx) {
1✔
162
                static constexpr auto expecting_YYYY_MM =
924✔
163
                    "expecting YYYY/MM or YYYY-MM"sv;
924✔
164
                auto const val = view(value);
1,387✔
165
                auto split = split_sv(val, '/'_sep, 1);
1,387✔
166

924✔
167
                if (split.size() < 2) {
463✔
UNCOV
168
                        split = split_sv(val, '-'_sep, 1);
×
169
                }
170

924✔
171
                if (split.size() < 2) {
463✔
UNCOV
172
                        return ref.error(expecting_YYYY_MM);
×
173
                }
174

924✔
175
                int year{};
463✔
176
                unsigned month{};
1,387✔
177

924✔
178
                if (!convert_string(ref, split[0], year) ||
925✔
179
                    !convert_string(ref, split[1], month)) {
462✔
UNCOV
180
                        return ref.error(expecting_YYYY_MM);
×
181
                }
182

924✔
183
                ctx = std::chrono::year{year} / static_cast<int>(month);
463✔
184

924✔
185
                if (!ctx.ok()) {
463✔
UNCOV
186
                        return ref.error(expecting_YYYY_MM);
×
187
                }
188

924✔
189
                return true;
463✔
190
        }
1,387✔
191
}  // namespace yaml
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc