Skip to content

Commit 73d0028

Browse files
committed
Add ValuePrinter
The printer from Decimal64 is stolen from cla-sysrepo (as is the Decimal64 implementation itself. Change-Id: I21176b15c0070a59695583f52e2fd5b837f081d4
1 parent 6b48b6d commit 73d0028

3 files changed

Lines changed: 101 additions & 0 deletions

File tree

include/libyang-cpp/Utils.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,19 @@ struct refs_type<Meta> {
9090
struct PointerCompare {
9191
bool operator()(const DataNode& a, const DataNode& b) const;
9292
};
93+
94+
/**
95+
* @brief A string conversion visitor for libyang::Value.
96+
*/
97+
struct ValuePrinter {
98+
std::string operator()(const libyang::Empty) const;
99+
std::string operator()(const std::vector<libyang::Bit>& val) const;
100+
std::string operator()(const libyang::Decimal64& val) const;
101+
std::string operator()(const libyang::Binary& val) const;
102+
std::string operator()(const libyang::Enum& val) const;
103+
std::string operator()(const libyang::IdentityRef& val) const;
104+
std::string operator()(const std::optional<libyang::DataNode>& val) const;
105+
template <typename ValueType>
106+
std::string operator()(const ValueType& val) const;
107+
};
93108
}

src/Utils.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
* SPDX-License-Identifier: BSD-3-Clause
77
*/
88

9+
#include <experimental/iterator>
10+
#include <iomanip>
911
#include <libyang-cpp/Utils.hpp>
12+
#include <sstream>
1013
#include "utils/enum.hpp"
1114

1215
namespace libyang {
@@ -27,4 +30,65 @@ bool PointerCompare::operator()(const DataNode& a, const DataNode& b) const
2730
{
2831
return getRawNode(a) < getRawNode(b);
2932
}
33+
34+
std::string ValuePrinter::operator()(const libyang::Empty) const
35+
{
36+
return "empty";
37+
}
38+
39+
std::string ValuePrinter::operator()(const std::vector<libyang::Bit>& val) const
40+
{
41+
std::ostringstream oss;
42+
std::transform(val.begin(), val.end(), std::experimental::make_ostream_joiner(oss, " "), [] (const auto& bit) {
43+
return bit.name;
44+
});
45+
return oss.str();
46+
}
47+
48+
std::string ValuePrinter::operator()(const libyang::Decimal64& val) const
49+
{
50+
std::ostringstream oss;
51+
const auto mul = impl::pow10int(val.digits);
52+
oss << (val.number / mul) << '.' << std::setfill('0') << std::setw(val.digits) << impl::abs(val.number % mul);
53+
return oss.str();
54+
}
55+
56+
std::string ValuePrinter::operator()(const libyang::Binary& val) const
57+
{
58+
return val.base64;
59+
}
60+
61+
std::string ValuePrinter::operator()(const libyang::Enum& val) const
62+
{
63+
return val.name;
64+
}
65+
66+
std::string ValuePrinter::operator()(const libyang::IdentityRef& val) const
67+
{
68+
return val.module + ":" + val.name;
69+
}
70+
71+
std::string ValuePrinter::operator()(const std::optional<libyang::DataNode>& val) const
72+
{
73+
if (!val) {
74+
return "InstanceIdentifier{no-instance}";
75+
}
76+
77+
return std::string{val->path()} + ": " + std::visit(*this, val->asTerm().value());
78+
}
79+
80+
template <typename ValueType>
81+
std::string ValuePrinter::operator()(const ValueType& val) const
82+
{
83+
std::ostringstream oss;
84+
if constexpr (std::is_same_v<ValueType, uint8_t> || std::is_same_v<ValueType, int8_t>) {
85+
oss << static_cast<int>(val);
86+
} else if constexpr (std::is_same_v<ValueType, bool>) {
87+
oss << std::boolalpha << val;
88+
} else {
89+
oss << val;
90+
}
91+
92+
return oss.str();
93+
}
3094
}

tests/data_node.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,98 +169,114 @@ TEST_CASE("Data Node manipulation")
169169
auto data = ctx.parseDataMem(dataTypes, libyang::DataFormat::JSON);
170170
std::string path;
171171
libyang::Value expected;
172+
std::string expectedPrinter;
172173

173174
DOCTEST_SUBCASE("value types")
174175
{
175176
DOCTEST_SUBCASE("int8")
176177
{
177178
path = "/example-schema:leafInt8";
178179
expected = int8_t{-43};
180+
expectedPrinter = "-43";
179181
}
180182

181183
DOCTEST_SUBCASE("int16")
182184
{
183185
path = "/example-schema:leafInt16";
184186
expected = int16_t{3000};
187+
expectedPrinter = "3000";
185188
}
186189

187190
DOCTEST_SUBCASE("int32")
188191
{
189192
path = "/example-schema:leafInt32";
190193
expected = int32_t{-391203910};
194+
expectedPrinter = "-391203910";
191195
}
192196

193197
DOCTEST_SUBCASE("int64")
194198
{
195199
path = "/example-schema:leafInt64";
196200
expected = int64_t{-234214214928};
201+
expectedPrinter = "-234214214928";
197202
}
198203

199204
DOCTEST_SUBCASE("uint8")
200205
{
201206
path = "/example-schema:leafUInt8";
202207
expected = uint8_t{43};
208+
expectedPrinter = "43";
203209
}
204210

205211
DOCTEST_SUBCASE("uint16")
206212
{
207213
path = "/example-schema:leafUInt16";
208214
expected = uint16_t{2333};
215+
expectedPrinter = "2333";
209216
}
210217

211218
DOCTEST_SUBCASE("uint32")
212219
{
213220
path = "/example-schema:leafUInt32";
214221
expected = uint32_t{23423422};
222+
expectedPrinter = "23423422";
215223
}
216224

217225
DOCTEST_SUBCASE("uint64")
218226
{
219227
path = "/example-schema:leafUInt64";
220228
expected = uint64_t{453545335344};
229+
expectedPrinter = "453545335344";
221230
}
222231

223232
DOCTEST_SUBCASE("decimal64")
224233
{
225234
path = "/example-schema:leafDecimal";
226235
using namespace libyang::literals;
227236
expected = 23212131231.43242_decimal64;
237+
expectedPrinter = "23212131231.43242";
228238
}
229239

230240
DOCTEST_SUBCASE("boolean")
231241
{
232242
path = "/example-schema:leafBool";
233243
expected = bool{false};
244+
expectedPrinter = "false";
234245
}
235246

236247
DOCTEST_SUBCASE("string")
237248
{
238249
path = "/example-schema:leafString";
239250
expected = std::string{"AHOJ"};
251+
expectedPrinter = "AHOJ";
240252
}
241253

242254
DOCTEST_SUBCASE("empty")
243255
{
244256
path = "/example-schema:leafEmpty";
245257
expected = libyang::Empty{};
258+
expectedPrinter = "empty";
246259
}
247260

248261
DOCTEST_SUBCASE("binary")
249262
{
250263
path = "/example-schema:leafBinary";
251264
expected = libyang::Binary{{0, 0, 0, 4, 16, 65, 8, 32}, "AAAABBBBCCC="};
265+
expectedPrinter = "AAAABBBBCCC=";
252266
}
253267

254268
DOCTEST_SUBCASE("intOrString")
255269
{
256270
path = "/example-schema:intOrString";
257271
expected = int32_t{14332};
272+
expectedPrinter = "14332";
258273
}
259274

260275
DOCTEST_SUBCASE("leafref")
261276
{
262277
path = "/example-schema:bossPerson";
263278
expected = std::string{"Dan"};
279+
expectedPrinter = "Dan";
264280
}
265281

266282
DOCTEST_SUBCASE("instance-identifier")
@@ -269,31 +285,36 @@ TEST_CASE("Data Node manipulation")
269285
{
270286
path = "/example-schema:targetInstance";
271287
expected = data->findPath("/example-schema:leafBool");
288+
expectedPrinter = "/example-schema:leafBool: false";
272289
}
273290

274291
DOCTEST_SUBCASE("require-instance = false")
275292
{
276293
path = "/example-schema:NOtargetInstance";
277294
expected = std::nullopt;
295+
expectedPrinter = "InstanceIdentifier{no-instance}";
278296
}
279297
}
280298

281299
DOCTEST_SUBCASE("bits")
282300
{
283301
path = "/example-schema:flagBits";
284302
expected = std::vector<libyang::Bit>{{0, "carry"}, {2, "overflow"}};
303+
expectedPrinter = "carry overflow";
285304
}
286305

287306
DOCTEST_SUBCASE("enum")
288307
{
289308
path = "/example-schema:pizzaSize";
290309
expected = libyang::Enum{"large"};
310+
expectedPrinter = "large";
291311
}
292312

293313
DOCTEST_SUBCASE("identityref")
294314
{
295315
path = "/example-schema:leafFoodTypedef";
296316
expected = libyang::IdentityRef{"example-schema", "hawaii"};
317+
expectedPrinter = "example-schema:hawaii";
297318
}
298319
}
299320

@@ -302,6 +323,7 @@ TEST_CASE("Data Node manipulation")
302323
auto term = node->asTerm();
303324
REQUIRE(term.path() == path);
304325
REQUIRE(term.value() == expected);
326+
REQUIRE(std::visit(libyang::ValuePrinter{}, term.value()) == expectedPrinter);
305327
}
306328

307329
DOCTEST_SUBCASE("DataNode::isDefaultValue")

0 commit comments

Comments
 (0)