1package versions
2
3// Set is a set of versions, usually created by parsing a constraint string.
4type Set struct {
5	setI
6}
7
8// setI is the private interface implemented by our various constraint
9// operators.
10type setI interface {
11	Has(v Version) bool
12	AllRequested() Set
13	GoString() string
14}
15
16// Has returns true if the given version is a member of the receiving set.
17func (s Set) Has(v Version) bool {
18	// The special Unspecified version is excluded as soon as any sort of
19	// constraint is applied, and so the only set it is a member of is
20	// the special All set.
21	if v == Unspecified {
22		return s == All
23	}
24
25	return s.setI.Has(v)
26}
27
28// Requests returns true if the given version is specifically requested by
29// the receiving set.
30//
31// Requesting is a stronger form of set membership that represents an explicit
32// request for a particular version, as opposed to the version just happening
33// to match some criteria.
34//
35// The functions Only and Selection mark their arguments as requested in
36// their returned sets. Exact version constraints given in constraint strings
37// also mark their versions as requested.
38//
39// The concept of requesting is intended to help deal with pre-release versions
40// in a safe and convenient way. When given generic version constraints like
41// ">= 1.0.0" the user generally does not intend to match a pre-release version
42// like "2.0.0-beta1", but it is important to stil be able to use that
43// version if explicitly requested using the constraint string "2.0.0-beta1".
44func (s Set) Requests(v Version) bool {
45	return s.AllRequested().Has(v)
46}
47
48// AllRequested returns a subset of the receiver containing only the requested
49// versions, as defined in the documentation for the method Requests.
50//
51// This can be used in conjunction with the predefined set "Released" to
52// include pre-release versions only by explicit request, which is supported
53// via the helper method WithoutUnrequestedPrereleases.
54//
55// The result of AllRequested is always a finite set.
56func (s Set) AllRequested() Set {
57	return s.setI.AllRequested()
58}
59
60// WithoutUnrequestedPrereleases returns a new set that includes all released
61// versions from the receiving set, plus any explicitly-requested pre-releases,
62// but does not include any unrequested pre-releases.
63//
64// "Requested" here is as defined in the documentation for the "Requests" method.
65//
66// This method is equivalent to the following set operations:
67//
68//     versions.Union(s.AllRequested(), s.Intersection(versions.Released))
69func (s Set) WithoutUnrequestedPrereleases() Set {
70	return Union(s.AllRequested(), Released.Intersection(s))
71}
72
73// UnmarshalText is an implementation of encoding.TextUnmarshaler, allowing
74// sets to be automatically unmarshalled from strings in text-based
75// serialization formats, including encoding/json.
76//
77// The format expected is what is accepted by MeetingConstraintsString. Any
78// parser errors are passed on verbatim to the caller.
79func (s *Set) UnmarshalText(text []byte) error {
80	str := string(text)
81	new, err := MeetingConstraintsString(str)
82	if err != nil {
83		return err
84	}
85	*s = new
86	return nil
87}
88
89var InitialDevelopment Set = OlderThan(MustParseVersion("1.0.0"))
90