github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/core/facades/facade.go (about)

     1  // Copyright 2023 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package facades
     5  
     6  import (
     7  	"github.com/juju/collections/set"
     8  )
     9  
    10  // FacadeVersion is a list of version numbers for a single facade.
    11  type FacadeVersion []int
    12  
    13  // NamedFacadeVersion is a map of facade name to version numbers.
    14  type NamedFacadeVersion struct {
    15  	Name     string
    16  	Versions FacadeVersion
    17  }
    18  
    19  // FacadeVersions is a map of facade name to version numbers. The facade version
    20  // numbers contain each version of the facade that the API server is capable of
    21  // supporting. This supports having holes in the version numbers, so that we can
    22  // depreciate broken versions of the facade.
    23  type FacadeVersions map[string]FacadeVersion
    24  
    25  // Merge adds the other facade versions to the current facade versions.
    26  func (f FacadeVersions) Add(others ...NamedFacadeVersion) FacadeVersions {
    27  	for _, other := range others {
    28  		f[other.Name] = set.NewInts(f[other.Name]...).Union(set.NewInts(other.Versions...)).SortedValues()
    29  	}
    30  	return f
    31  }
    32  
    33  // BestVersion finds the newest version in the version list that we can
    34  // use.
    35  func BestVersion(desired FacadeVersion, versions FacadeVersion) int {
    36  	intersection := set.NewInts(desired...).Intersection(set.NewInts(versions...))
    37  	if intersection.Size() == 0 {
    38  		return 0
    39  	}
    40  	sorted := intersection.SortedValues()
    41  	return sorted[len(sorted)-1]
    42  }
    43  
    44  // CompleteIntersection returns true if the src and dest facades have a
    45  // complete intersection. This means that the dest facades support all of
    46  // the src facades.
    47  // src is the facades that are required, dest is the full set of facades
    48  // that are supported.
    49  func CompleteIntersection(src, dest FacadeVersions) bool {
    50  	for name, versions := range src {
    51  		if _, ok := dest[name]; !ok {
    52  			return false
    53  		}
    54  		if BestVersion(versions, dest[name]) == 0 {
    55  			return false
    56  		}
    57  	}
    58  	return true
    59  }