decred.org/dcrdex@v1.0.5/dex/semver.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package dex
     5  
     6  import (
     7  	"fmt"
     8  	"strconv"
     9  	"strings"
    10  )
    11  
    12  // Semver models a semantic version major.minor.patch
    13  type Semver struct {
    14  	Major uint32
    15  	Minor uint32
    16  	Patch uint32
    17  }
    18  
    19  // NewSemver returns a new Semver with the version major.minor.patch
    20  func NewSemver(major, minor, patch uint32) Semver {
    21  	return Semver{major, minor, patch}
    22  }
    23  
    24  // SemverCompatible decides if the actual version is compatible with the required one.
    25  func SemverCompatible(required, actual Semver) bool {
    26  	switch {
    27  	case required.Major != actual.Major:
    28  		return false
    29  	case required.Minor > actual.Minor:
    30  		return false
    31  	case required.Minor == actual.Minor && required.Patch > actual.Patch:
    32  		return false
    33  	default:
    34  		return true
    35  	}
    36  }
    37  
    38  // SemverCompatibleAny checks if the version is compatible with any versions in
    39  // a slice of versions.
    40  func SemverCompatibleAny(compatible []Semver, actual Semver) bool {
    41  	for _, v := range compatible {
    42  		if SemverCompatible(v, actual) {
    43  			return true
    44  		}
    45  	}
    46  	return false
    47  }
    48  
    49  // Semver formats the Semver as major.minor.patch (e.g. 1.2.3).
    50  func (s Semver) String() string {
    51  	return fmt.Sprintf("%d.%d.%d", s.Major, s.Minor, s.Patch)
    52  }
    53  
    54  func SemverFromString(ver string) (*Semver, error) {
    55  	fields := strings.Split(ver, ".")
    56  	if len(fields) < 2 {
    57  		return nil, fmt.Errorf("expected semver with 2 or more fields but got %d", len(fields))
    58  	}
    59  	major, err := strconv.ParseUint(fields[0], 10, 32)
    60  	if err != nil {
    61  		return nil, fmt.Errorf("cannot parse semver major: %v", err)
    62  	}
    63  	minor, err := strconv.ParseUint(fields[1], 10, 32)
    64  	if err != nil {
    65  		return nil, fmt.Errorf("cannot parse semver minor: %v", err)
    66  	}
    67  	var patch uint64
    68  	if len(fields) > 2 {
    69  		patch, err = strconv.ParseUint(fields[2], 10, 32)
    70  		if err != nil {
    71  			return nil, fmt.Errorf("cannot parse semver major: %v", err)
    72  		}
    73  	}
    74  	// Some versions will have an extra field. Ignoring.
    75  	return &Semver{uint32(major), uint32(minor), uint32(patch)}, nil
    76  }