Skip to content

Commit f1b70da

Browse files
Ensures parser output is deterministic
1 parent cddeea0 commit f1b70da

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

Sources/App/Models/Parser Models/Color.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ extension Color {
6363
wysteria,
6464
pumpkin,
6565
]
66-
return colors[index % colors.count]
66+
return colors[abs(index) % colors.count]
6767
}
6868

6969
static let defaultColor = turquoise

Sources/App/Models/Parser Models/ConstraintGroup.swift

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct ConstraintGroup {
2626
for (i, item) in layoutItems.enumerated() {
2727
// Adding a seed value ensures the color scheme can differ per input while
2828
// remaining deterministic.
29-
let color = Color.flatColor(index: i + abs(seed))
29+
let color = Color.flatColor(index: i + seed)
3030

3131
let requiresUniquing = (counts[item.prettyName] ?? 0) > 1
3232
let uniquingSuffix = requiresUniquing ? uniquingSuffixes[i] : ""
@@ -41,7 +41,7 @@ struct ConstraintGroup {
4141

4242
self.raw = raw
4343
self.constraints = constraints
44-
let layoutItems = Set(constraints.flatMap { $0.layoutItems })
44+
let layoutItems = constraints.flatMap { $0.layoutItems }.removingDuplicates()
4545
self.annotations = ConstraintGroup.annotations(for: Array(layoutItems), seed: raw.count)
4646
}
4747
}
@@ -52,7 +52,22 @@ extension ConstraintGroup {
5252
return constraints.contains(where: { $0.origin == .autoresizingMask })
5353
}
5454

55-
var footnotes: Set<Footnote> {
56-
return Set(constraints.compactMap { $0.footnote })
55+
var footnotes: [Footnote] {
56+
return constraints.compactMap { $0.footnote }.removingDuplicates()
5757
}
5858
}
59+
60+
private extension Collection where Element: Hashable {
61+
62+
func removingDuplicates() -> [Element] {
63+
var seen: Set<Element> = []
64+
var uniques: [Element] = []
65+
for element in self {
66+
guard !seen.contains(element) else { continue }
67+
seen.insert(element)
68+
uniques.append(element)
69+
}
70+
return uniques
71+
}
72+
}
73+

0 commit comments

Comments
 (0)