Files
libopenapi/what-changed/model/security_requirement.go

151 lines
4.7 KiB
Go

// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package model
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/base"
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)
// SecurityRequirementChanges represents changes found between two SecurityRequirement Objects.
type SecurityRequirementChanges struct {
*PropertyChanges
}
// GetAllChanges returns a slice of all changes made between SecurityRequirement objects
func (s *SecurityRequirementChanges) GetAllChanges() []*Change {
return s.Changes
}
// TotalChanges returns the total number of changes between two SecurityRequirement Objects.
func (s *SecurityRequirementChanges) TotalChanges() int {
return s.PropertyChanges.TotalChanges()
}
// TotalBreakingChanges returns the total number of breaking changes between two SecurityRequirement Objects.
func (s *SecurityRequirementChanges) TotalBreakingChanges() int {
return s.PropertyChanges.TotalBreakingChanges()
}
// CompareSecurityRequirement compares left and right SecurityRequirement objects for changes. If anything
// is found, then a pointer to SecurityRequirementChanges is returned, otherwise nil.
func CompareSecurityRequirement(l, r *base.SecurityRequirement) *SecurityRequirementChanges {
var changes []*Change
sc := new(SecurityRequirementChanges)
if low.AreEqual(l, r) {
return nil
}
checkSecurityRequirement(l.Requirements.Value, r.Requirements.Value, &changes)
sc.PropertyChanges = NewPropertyChanges(changes)
return sc
}
func removedSecurityRequirement(vn *yaml.Node, name string, changes *[]*Change) {
CreateChange(changes, ObjectRemoved, v3.SecurityLabel,
vn, nil, true, name, nil)
}
func addedSecurityRequirement(vn *yaml.Node, name string, changes *[]*Change) {
CreateChange(changes, ObjectAdded, v3.SecurityLabel,
nil, vn, false, nil, name)
}
// tricky to do this correctly, this is my solution.
func checkSecurityRequirement(lSec, rSec *orderedmap.Map[low.KeyReference[string], low.ValueReference[[]low.ValueReference[string]]],
changes *[]*Change,
) {
lKeys := make([]string, orderedmap.Len(lSec))
rKeys := make([]string, orderedmap.Len(rSec))
lValues := make(map[string]low.ValueReference[[]low.ValueReference[string]])
rValues := make(map[string]low.ValueReference[[]low.ValueReference[string]])
var n, z int
for pair := orderedmap.First(lSec); pair != nil; pair = pair.Next() {
lKeys[n] = pair.Key().Value
lValues[pair.Key().Value] = pair.Value()
n++
}
for pair := orderedmap.First(rSec); pair != nil; pair = pair.Next() {
rKeys[z] = pair.Key().Value
rValues[pair.Key().Value] = pair.Value()
z++
}
for z = range lKeys {
if z < len(rKeys) {
if _, ok := rValues[lKeys[z]]; !ok {
removedSecurityRequirement(lValues[lKeys[z]].ValueNode, lKeys[z], changes)
continue
}
lValue := lValues[lKeys[z]].Value
rValue := rValues[lKeys[z]].Value
// check if actual values match up
lRoleKeys := make([]string, len(lValue))
rRoleKeys := make([]string, len(rValue))
lRoleValues := make(map[string]low.ValueReference[string])
rRoleValues := make(map[string]low.ValueReference[string])
var t, k int
for i := range lValue {
lRoleKeys[t] = lValue[i].Value
lRoleValues[lValue[i].Value] = lValue[i]
t++
}
for i := range rValue {
rRoleKeys[k] = rValue[i].Value
rRoleValues[rValue[i].Value] = rValue[i]
k++
}
for t = range lRoleKeys {
if t < len(rRoleKeys) {
if _, ok := rRoleValues[lRoleKeys[t]]; !ok {
removedSecurityRequirement(lRoleValues[lRoleKeys[t]].ValueNode, lRoleKeys[t], changes)
continue
}
}
if t >= len(rRoleKeys) {
if _, ok := rRoleValues[lRoleKeys[t]]; !ok {
removedSecurityRequirement(lRoleValues[lRoleKeys[t]].ValueNode, lRoleKeys[t], changes)
}
}
}
for t = range rRoleKeys {
if t < len(lRoleKeys) {
if _, ok := lRoleValues[rRoleKeys[t]]; !ok {
addedSecurityRequirement(rRoleValues[rRoleKeys[t]].ValueNode, rRoleKeys[t], changes)
continue
}
}
if t >= len(lRoleKeys) {
addedSecurityRequirement(rRoleValues[rRoleKeys[t]].ValueNode, rRoleKeys[t], changes)
}
}
}
if z >= len(rKeys) {
if _, ok := rValues[lKeys[z]]; !ok {
removedSecurityRequirement(lValues[lKeys[z]].ValueNode, lKeys[z], changes)
}
}
}
for z = range rKeys {
if z < len(lKeys) {
if _, ok := lValues[rKeys[z]]; !ok {
addedSecurityRequirement(rValues[rKeys[z]].ValueNode, rKeys[z], changes)
continue
}
}
if z >= len(lKeys) {
if _, ok := lValues[rKeys[z]]; !ok {
addedSecurityRequirement(rValues[rKeys[z]].ValueNode, rKeys[z], changes)
}
}
}
}