14 function_ref<
bool(
const DomItem &,
const PathEls::PathComponent &,
const DomItem &)> filter,
17 DomKind k1 = i1.domKind();
18 DomKind k2 = i2.domKind();
20 if (!change(basePath, i1, i2))
26 case DomKind::Object: {
27 QStringList f1 = i1.fields();
28 QStringList f2 = i2.fields();
33 while (it1 != f1.size() || it2 != f2.size()) {
36 bool hasK1 = it1 != f1.size();
43 bool hasK2 = it2 != f2.size();
48 filt2 = i2.isCanonicalChild(el2) && filter(i2, PathEls::Field(k2), el2);
51 if (hasK1 && !filt1) {
56 }
else if (hasK2 && !filt2) {
60 if (filt1 && filt2 && k1 == k2) {
61 if (!domCompare(el1, el2, change, filter, basePath.withField(k1)))
65 }
else if (!hasK1 || (hasK2 && k1 > k2)) {
77 QStringList f1 = i1.sortedKeys();
78 QStringList f2 = i2.sortedKeys();
81 while (it1 != f1.size() || it2 != f2.size()) {
84 bool hasK1 = it1 != f1.size();
91 bool hasK2 = it2 != f2.size();
96 filt2 = i2.isCanonicalChild(el2) && filter(i2, PathEls::Key(k2), el2);
99 if (hasK1 && !filt1) {
104 }
else if (hasK2 && !filt2) {
108 if (filt1 && filt2 && k1 == k2) {
109 if (!domCompare(el1, el2, change, filter, basePath.withKey(k1)))
113 }
else if (!hasK1 || (hasK2 && k1 > k2)) {
124 case DomKind::List: {
127 index_type len1 = i1.indexes();
128 index_type len2 = i2.indexes();
130 return change(basePath, i1, i2);
131 for (index_type i = 0; i < len1; ++i) {
134 if (filter(i1,
PathEls::Index(i), v1) && filter(i2,
PathEls::Index(i), v2)) {
137 if (i1.isCanonicalChild(el1) && i2.isCanonicalChild(el2)
138 && !domCompare(el1, el2, change, filter, basePath.withIndex(i)))
143 case DomKind::Value: {
144 QCborValue v1 = i1.value();
145 QCborValue v2 = i2.value();
147 return change(basePath, i1, i2);
149 case DomKind::ScriptElement: {
161 function_ref<
bool(
const DomItem &,
const PathEls::PathComponent &,
const DomItem &)
const> filter,
165 bool hasDiff =
false;
168 [&res, &hasDiff, stopAtFirstDiff](
const Path &p,
const DomItem &j1,
const DomItem &j2) {
171 res.append(QStringLiteral(
"- %1\n").arg(p.toString()));
173 res.append(QStringLiteral(
"+ %1\n").arg(p.toString()));
175 DomKind k1 = j1.domKind();
176 DomKind k2 = j2.domKind();
179 QStringLiteral(
"- %1 %2\n").arg(p.toString(), domKindToString(k1)));
181 QStringLiteral(
"+ %1 %2\n").arg(p.toString(), domKindToString(k2)));
185 case DomKind::Object:
189 case DomKind::List: {
190 index_type len1 = j1.indexes();
191 index_type len2 = j2.indexes();
192 res.append(QStringLiteral(
"- %1 #%2\n").arg(p.toString()).arg(len1));
193 res.append(QStringLiteral(
"+ %1 #%2\n").arg(p.toString()).arg(len2));
195 case DomKind::Value: {
196 QCborValue v1 = j1.value();
197 QCborValue v2 = j2.value();
201 res.append(QStringLiteral(
"- %1 type(%2)\n")
204 res.append(QStringLiteral(
"+ %1 type(%2)\n")
208 res.append(QStringLiteral(
"- %1 value(%2)\n")
210 .arg(j1.toString()));
211 res.append(QStringLiteral(
"+ %1 value(%2)\n")
213 .arg(j2.toString()));
216 case DomKind::ScriptElement: {
226 if (hasDiff && res.isEmpty())
227 res.append(QStringLiteral(u"Had changes!"));
bool domCompare(const DomItem &i1, const DomItem &i2, function_ref< bool(Path, const DomItem &, const DomItem &)> change, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter, Path basePath)