@@ -5,14 +5,57 @@ import (
5
5
"strings"
6
6
)
7
7
8
+ // constrainer is a reusable accumulator of constraint clause terms.
9
+ type constrainer struct {
10
+ pos []Identifier
11
+ neg []Identifier
12
+ }
13
+
14
+ func (x * constrainer ) Add (id Identifier ) {
15
+ x .pos = append (x .pos , id )
16
+ }
17
+
18
+ func (x * constrainer ) AddNot (id Identifier ) {
19
+ x .neg = append (x .neg , id )
20
+ }
21
+
22
+ // Reset clears the receiver's internal state so that it can be
23
+ // reused.
24
+ func (x * constrainer ) Reset () {
25
+ x .pos = x .pos [:0 ]
26
+ x .neg = x .neg [:0 ]
27
+ }
28
+
29
+ // Empty returns true if and only if the receiver has accumulated no
30
+ // positive or negative terms.
31
+ func (x * constrainer ) Empty () bool {
32
+ return len (x .pos ) == 0 && len (x .neg ) == 0
33
+ }
34
+
8
35
// Constraint implementations limit the circumstances under which a
9
36
// particular Installable can appear in a solution.
10
37
type Constraint interface {
11
38
String (subject Identifier ) string
12
- apply (x constrainer , subject Identifier )
39
+ apply (x * constrainer , subject Identifier )
13
40
order () []Identifier
14
41
}
15
42
43
+ // zeroConstraint is returned by ConstraintOf in error cases.
44
+ type zeroConstraint struct {}
45
+
46
+ var _ Constraint = zeroConstraint {}
47
+
48
+ func (zeroConstraint ) String (subject Identifier ) string {
49
+ return ""
50
+ }
51
+
52
+ func (zeroConstraint ) apply (x * constrainer , subject Identifier ) {
53
+ }
54
+
55
+ func (zeroConstraint ) order () []Identifier {
56
+ return nil
57
+ }
58
+
16
59
// AppliedConstraint values compose a single Constraint with the
17
60
// Installable it applies to.
18
61
type AppliedConstraint struct {
@@ -26,25 +69,13 @@ func (a AppliedConstraint) String() string {
26
69
return a .Constraint .String (a .Installable .Identifier ())
27
70
}
28
71
29
- // constrainer is the set of operations available to Constraint
30
- // implementations.
31
- type constrainer interface {
32
- // Add appends the Installable identified by the given
33
- // Identifier to the clause representing a Constraint.
34
- Add (Identifier )
35
- // Add appends the negation of the Installable identified by
36
- // the given Identifier to the clause representing a
37
- // Constraint.
38
- AddNot (Identifier )
39
- }
40
-
41
72
type mandatory struct {}
42
73
43
74
func (c mandatory ) String (subject Identifier ) string {
44
75
return fmt .Sprintf ("%s is mandatory" , subject )
45
76
}
46
77
47
- func (c mandatory ) apply (x constrainer , subject Identifier ) {
78
+ func (c mandatory ) apply (x * constrainer , subject Identifier ) {
48
79
x .Add (subject )
49
80
}
50
81
@@ -64,7 +95,7 @@ func (c prohibited) String(subject Identifier) string {
64
95
return fmt .Sprintf ("%s is prohibited" , subject )
65
96
}
66
97
67
- func (c prohibited ) apply (x constrainer , subject Identifier ) {
98
+ func (c prohibited ) apply (x * constrainer , subject Identifier ) {
68
99
x .AddNot (subject )
69
100
}
70
101
@@ -90,7 +121,7 @@ func (c dependency) String(subject Identifier) string {
90
121
return fmt .Sprintf ("%s requires at least one of %s" , subject , strings .Join (s , ", " ))
91
122
}
92
123
93
- func (c dependency ) apply (x constrainer , subject Identifier ) {
124
+ func (c dependency ) apply (x * constrainer , subject Identifier ) {
94
125
if len (c ) == 0 {
95
126
return
96
127
}
@@ -119,7 +150,7 @@ func (c conflict) String(subject Identifier) string {
119
150
return fmt .Sprintf ("%s conflicts with %s" , subject , c )
120
151
}
121
152
122
- func (c conflict ) apply (x constrainer , subject Identifier ) {
153
+ func (c conflict ) apply (x * constrainer , subject Identifier ) {
123
154
x .AddNot (subject )
124
155
x .AddNot (Identifier (c ))
125
156
}
0 commit comments