Compare compares two features and returns an integer representing if the first feature (f) is greater than, equal to, or less than the second feature (b). "Greater than" means the first feature has more functionality than the second feature. It is assumed the features are for the same FeatureName.
(b Feature)
| 408 | // 6. Enabled is greater than disabled |
| 409 | // 7. The actual is greater |
| 410 | func (f Feature) Compare(b Feature) int { |
| 411 | // For features with usage period constraints only, check the issued at and |
| 412 | // end dates. |
| 413 | bothHaveUsagePeriod := f.UsagePeriod != nil && b.UsagePeriod != nil |
| 414 | if bothHaveUsagePeriod { |
| 415 | issuedAtCmp := f.UsagePeriod.IssuedAt.Compare(b.UsagePeriod.IssuedAt) |
| 416 | if issuedAtCmp != 0 { |
| 417 | return issuedAtCmp |
| 418 | } |
| 419 | endCmp := f.UsagePeriod.End.Compare(b.UsagePeriod.End) |
| 420 | if endCmp != 0 { |
| 421 | return endCmp |
| 422 | } |
| 423 | } |
| 424 | |
| 425 | // Only perform capability comparisons if both features have actual values. |
| 426 | if f.Actual != nil && b.Actual != nil && (!f.Capable() || !b.Capable()) { |
| 427 | // If either is incapable, then it is possible a grace period |
| 428 | // feature can be "greater" than an entitled. |
| 429 | // If either is "NotEntitled" then we can defer to a strict entitlement |
| 430 | // check. |
| 431 | if f.Entitlement.Weight() >= 0 && b.Entitlement.Weight() >= 0 { |
| 432 | if f.Capable() && !b.Capable() { |
| 433 | return 1 |
| 434 | } |
| 435 | if b.Capable() && !f.Capable() { |
| 436 | return -1 |
| 437 | } |
| 438 | } |
| 439 | } |
| 440 | |
| 441 | // Strict entitlement check. Higher is better. We don't apply this check for |
| 442 | // usage period features as we always want the issued at date to be the main |
| 443 | // decision maker. |
| 444 | entitlementDifference := f.Entitlement.Weight() - b.Entitlement.Weight() |
| 445 | if entitlementDifference != 0 { |
| 446 | return entitlementDifference |
| 447 | } |
| 448 | |
| 449 | // If the entitlement is the same, then we can compare the limits. |
| 450 | if f.Limit == nil && b.Limit != nil { |
| 451 | return -1 |
| 452 | } |
| 453 | if f.Limit != nil && b.Limit == nil { |
| 454 | return 1 |
| 455 | } |
| 456 | if f.Limit != nil && b.Limit != nil { |
| 457 | difference := *f.Limit - *b.Limit |
| 458 | if difference != 0 { |
| 459 | return int(difference) |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | // Enabled is better than disabled. |
| 464 | if f.Enabled && !b.Enabled { |
| 465 | return 1 |
| 466 | } |
| 467 | if !f.Enabled && b.Enabled { |