// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package compliance import ( "fmt" "strings" ) // LicenseConditionSet identifies sets of license conditions. type LicenseConditionSet LicenseCondition // AllLicenseConditions is the set of all recognized license conditions. const AllLicenseConditions = LicenseConditionSet(LicenseConditionMask) // NewLicenseConditionSet returns a set containing exactly the elements of // `conditions`. func NewLicenseConditionSet(conditions ...LicenseCondition) LicenseConditionSet { cs := LicenseConditionSet(0x00) for _, lc := range conditions { cs |= LicenseConditionSet(lc) } return cs } // Plus returns a new set containing all of the elements of `cs` and all of the // `conditions`. func (cs LicenseConditionSet) Plus(conditions ...LicenseCondition) LicenseConditionSet { result := cs for _, lc := range conditions { result |= LicenseConditionSet(lc) } return result } // Union returns a new set containing all of the elements of `cs` and all of the // elements of the `other` sets. func (cs LicenseConditionSet) Union(other ...LicenseConditionSet) LicenseConditionSet { result := cs for _, ls := range other { result |= ls } return result } // MatchingAny returns the subset of `cs` equal to any of the `conditions`. func (cs LicenseConditionSet) MatchingAny(conditions ...LicenseCondition) LicenseConditionSet { result := LicenseConditionSet(0x00) for _, lc := range conditions { result |= cs & LicenseConditionSet(lc) } return result } // MatchingAnySet returns the subset of `cs` that are members of any of the // `other` sets. func (cs LicenseConditionSet) MatchingAnySet(other ...LicenseConditionSet) LicenseConditionSet { result := LicenseConditionSet(0x00) for _, ls := range other { result |= cs & ls } return result } // HasAny returns true when `cs` contains at least one of the `conditions`. func (cs LicenseConditionSet) HasAny(conditions ...LicenseCondition) bool { for _, lc := range conditions { if 0x0000 != (cs & LicenseConditionSet(lc)) { return true } } return false } // MatchesAnySet returns true when `cs` has a non-empty intersection with at // least one of the `other` condition sets. func (cs LicenseConditionSet) MatchesAnySet(other ...LicenseConditionSet) bool { for _, ls := range other { if 0x0000 != (cs & ls) { return true } } return false } // HasAll returns true when `cs` contains every one of the `conditions`. func (cs LicenseConditionSet) HasAll(conditions ...LicenseCondition) bool { for _, lc := range conditions { if 0x0000 == (cs & LicenseConditionSet(lc)) { return false } } return true } // MatchesEverySet returns true when `cs` has a non-empty intersection with // each of the `other` condition sets. func (cs LicenseConditionSet) MatchesEverySet(other ...LicenseConditionSet) bool { for _, ls := range other { if 0x0000 == (cs & ls) { return false } } return true } // Intersection returns the subset of `cs` that are members of every `other` // set. func (cs LicenseConditionSet) Intersection(other ...LicenseConditionSet) LicenseConditionSet { result := cs for _, ls := range other { result &= ls } return result } // Minus returns the subset of `cs` that are not equaal to any `conditions`. func (cs LicenseConditionSet) Minus(conditions ...LicenseCondition) LicenseConditionSet { result := cs for _, lc := range conditions { result &^= LicenseConditionSet(lc) } return result } // Difference returns the subset of `cs` that are not members of any `other` // set. func (cs LicenseConditionSet) Difference(other ...LicenseConditionSet) LicenseConditionSet { result := cs for _, ls := range other { result &^= ls } return result } // Len returns the number of license conditions in the set. func (cs LicenseConditionSet) Len() int { size := 0 for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 { if 0x00 != (cs & lc) { size++ } } return size } // AsList returns an array of the license conditions in the set. func (cs LicenseConditionSet) AsList() []LicenseCondition { result := make([]LicenseCondition, 0, cs.Len()) for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 { if 0x00 != (cs & lc) { result = append(result, LicenseCondition(lc)) } } return result } // Names returns an array of the names of the license conditions in the set. func (cs LicenseConditionSet) Names() []string { result := make([]string, 0, cs.Len()) for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 { if 0x00 != (cs & lc) { result = append(result, LicenseCondition(lc).Name()) } } return result } // IsEmpty returns true when the set contains no license conditions. func (cs LicenseConditionSet) IsEmpty() bool { return 0x00 == (cs & AllLicenseConditions) } // String returns a human-readable string representation of the set. func (cs LicenseConditionSet) String() string { return fmt.Sprintf("{%s}", strings.Join(cs.Names(), "|")) }