cppfig 0.1.0
Modern C++20 compile-time type-safe configuration library
Loading...
Searching...
No Matches
diff.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <sstream>
5#include <string>
6#include <vector>
7
8#include "cppfig/value.h"
9
10namespace cppfig {
11
13enum class DiffType : std::uint8_t { Added,
14 Removed,
15 Modified };
16
18struct DiffEntry {
20 std::string path;
21 std::string old_value;
22 std::string new_value;
23
24 [[nodiscard]] auto TypeString() const -> std::string
25 {
26 switch (type) {
27 case DiffType::Added:
28 return "ADDED";
30 return "REMOVED";
32 return "MODIFIED";
33 }
34 return "UNKNOWN"; // LCOV_EXCL_LINE
35 }
36};
37
40public:
41 std::vector<DiffEntry> entries;
42
44 [[nodiscard]] auto HasDifferences() const -> bool { return !entries.empty(); }
45
47 [[nodiscard]] auto Size() const -> std::size_t { return entries.size(); }
48
50 [[nodiscard]] auto Filter(DiffType type) const -> std::vector<DiffEntry>
51 {
52 std::vector<DiffEntry> result;
53 for (const auto& entry : entries) {
54 if (entry.type == type) {
55 result.push_back(entry);
56 }
57 }
58 return result;
59 }
60
62 [[nodiscard]] auto Added() const -> std::vector<DiffEntry> { return Filter(DiffType::Added); }
63
65 [[nodiscard]] auto Removed() const -> std::vector<DiffEntry> { return Filter(DiffType::Removed); }
66
68 [[nodiscard]] auto Modified() const -> std::vector<DiffEntry> { return Filter(DiffType::Modified); }
69
71 [[nodiscard]] auto ToString() const -> std::string
72 {
73 if (!HasDifferences()) {
74 return "No differences found.\n";
75 }
76
77 std::ostringstream ss;
78 ss << "Configuration differences:\n";
79
80 for (const auto& entry : entries) {
81 ss << " [" << entry.TypeString() << "] " << entry.path;
82 switch (entry.type) {
83 case DiffType::Added:
84 ss << " = " << entry.new_value;
85 break;
87 ss << " (was: " << entry.old_value << ")";
88 break;
90 ss << ": " << entry.old_value << " -> " << entry.new_value;
91 break;
92 }
93 ss << "\n";
94 }
95
96 return ss.str();
97 }
98};
99
100namespace detail {
101
103 inline void CompareValueRecursive(const Value& base, const Value& target, const std::string& prefix,
104 ConfigDiff& diff)
105 {
106 // Check for keys in target that are not in base (added)
107 if (target.IsObject()) {
108 for (const auto& [key, value] : target.Items()) {
109 std::string path = prefix.empty() ? key : prefix + "." + key;
110
111 if (!base.IsObject() || !base.Contains(key)) {
112 diff.entries.push_back({ DiffType::Added, path, "", value.Dump() });
113 }
114 else if (base[key] != value) {
115 if (base[key].IsObject() && value.IsObject()) {
116 CompareValueRecursive(base[key], value, path, diff);
117 }
118 else {
119 diff.entries.push_back({ DiffType::Modified, path, base[key].Dump(), value.Dump() });
120 }
121 }
122 }
123 }
124
125 // Check for keys in base that are not in target (removed)
126 if (base.IsObject()) {
127 for (const auto& [key, value] : base.Items()) {
128 std::string path = prefix.empty() ? key : prefix + "." + key;
129
130 if (!target.IsObject() || !target.Contains(key)) {
131 diff.entries.push_back({ DiffType::Removed, path, value.Dump(), "" });
132 }
133 }
134 }
135 }
136
137} // namespace detail
138
144inline auto DiffValues(const Value& base, const Value& target) -> ConfigDiff
145{
146 ConfigDiff diff;
147 detail::CompareValueRecursive(base, target, "", diff);
148 return diff;
149}
150
157inline auto DiffFileFromDefaults(const Value& defaults, const Value& file_values) -> ConfigDiff
158{
159 return DiffValues(defaults, file_values);
160}
161
168inline auto DiffDefaultsFromFile(const Value& defaults, const Value& file_values) -> ConfigDiff
169{
170 return DiffValues(file_values, defaults);
171}
172
173} // namespace cppfig
Result of comparing two configurations.
Definition diff.h:39
auto Added() const -> std::vector< DiffEntry >
Returns entries that were added.
Definition diff.h:62
auto Size() const -> std::size_t
Returns the number of differences.
Definition diff.h:47
auto Removed() const -> std::vector< DiffEntry >
Returns entries that were removed.
Definition diff.h:65
auto HasDifferences() const -> bool
Checks if there are any differences.
Definition diff.h:44
auto ToString() const -> std::string
Converts the diff to a human-readable string.
Definition diff.h:71
auto Filter(DiffType type) const -> std::vector< DiffEntry >
Filters entries by type.
Definition diff.h:50
std::vector< DiffEntry > entries
Definition diff.h:41
auto Modified() const -> std::vector< DiffEntry >
Returns entries that were modified.
Definition diff.h:68
A self-contained, recursive value type for configuration data.
Definition value.h:26
auto Items() const -> const ObjectType &
Returns const reference to the object entries.
Definition value.h:245
auto Contains(std::string_view key) const -> bool
Checks whether the given key exists in an object value.
Definition value.h:210
auto IsObject() const -> bool
Returns true if this value is an object (key-value map).
Definition value.h:167
auto Dump(int indent=0) const -> std::string
Produces a JSON-like string representation.
Definition value.h:337
void CompareValueRecursive(const Value &base, const Value &target, const std::string &prefix, ConfigDiff &diff)
Recursively compares two Value objects and collects differences.
Definition diff.h:103
C++20 compile-time type-safe configuration library.
Definition conf.h:13
auto DiffDefaultsFromFile(const Value &defaults, const Value &file_values) -> ConfigDiff
Compares defaults against file configuration.
Definition diff.h:168
DiffType
Type of change detected in a diff.
Definition diff.h:13
auto DiffFileFromDefaults(const Value &defaults, const Value &file_values) -> ConfigDiff
Compares file configuration against defaults.
Definition diff.h:157
auto DiffValues(const Value &base, const Value &target) -> ConfigDiff
Compares two Value configurations and returns the differences.
Definition diff.h:144
Represents a single difference between two configurations.
Definition diff.h:18
std::string new_value
Definition diff.h:22
std::string path
Definition diff.h:20
std::string old_value
Definition diff.h:21
auto TypeString() const -> std::string
Definition diff.h:24
DiffType type
Definition diff.h:19