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