github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/commons/versions/version.go (about) 1 /* 2 * Copyright 2023 Wang Min Xiang 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package versions 19 20 import ( 21 "bytes" 22 "fmt" 23 "github.com/aacfactory/errors" 24 "github.com/aacfactory/fns/commons/bytex" 25 "math" 26 "strconv" 27 ) 28 29 func New(major int, minor int, patch int) (v Version) { 30 v = Version{ 31 Major: major, 32 Minor: minor, 33 Patch: patch, 34 } 35 return 36 } 37 38 func Origin() Version { 39 return Version{ 40 Major: 0, 41 Minor: 0, 42 Patch: 0, 43 } 44 } 45 46 func Latest() Version { 47 return Version{ 48 Major: math.MaxInt64, 49 Minor: math.MaxInt64, 50 Patch: math.MaxInt64, 51 } 52 } 53 54 type Version struct { 55 Major int `json:"major"` 56 Minor int `json:"minor"` 57 Patch int `json:"patch"` 58 } 59 60 func (ver Version) Between(left Version, right Version) (ok bool) { 61 if ver.Major >= left.Major && ver.Major < right.Major { 62 if ver.Minor >= left.Minor && ver.Minor < right.Minor { 63 if ver.Patch >= left.Patch && ver.Patch < right.Patch { 64 ok = true 65 } 66 } 67 } 68 return 69 } 70 71 func (ver Version) LessThan(o Version) (ok bool) { 72 if ver.Major < o.Major { 73 ok = true 74 return 75 } 76 if ver.Major == o.Major { 77 if ver.Minor < o.Minor { 78 ok = true 79 return 80 } 81 if ver.Minor == o.Minor { 82 if ver.Patch < o.Patch { 83 ok = true 84 return 85 } 86 } 87 return 88 } 89 return 90 } 91 92 func (ver Version) Equals(o Version) (ok bool) { 93 ok = ver.Format() == o.Format() 94 return 95 } 96 97 func (ver Version) IsOrigin() (ok bool) { 98 ok = ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 99 return 100 } 101 102 func (ver Version) IsLatest() (ok bool) { 103 ok = ver.Major == math.MaxInt64 && ver.Minor == math.MaxInt64 && ver.Patch == math.MaxInt64 104 return 105 } 106 107 func (ver Version) String() (v string) { 108 if ver.IsLatest() { 109 v = "latest" 110 return 111 } 112 if ver.Major < 0 { 113 v = "invalid" 114 return 115 } 116 if ver.Minor < 0 { 117 v = fmt.Sprintf("v%d", ver.Major) 118 return 119 } 120 if ver.Patch < 0 { 121 v = fmt.Sprintf("v%d.%d", ver.Major, ver.Minor) 122 return 123 } 124 v = fmt.Sprintf("v%d.%d.%d", ver.Major, ver.Minor, ver.Patch) 125 return 126 } 127 128 func (ver Version) Format() (v string) { 129 if ver.IsLatest() { 130 v = "latest" 131 return 132 } 133 if ver.Major < 0 { 134 v = "invalid" 135 return 136 } 137 if ver.Minor < 0 { 138 ver.Minor = 0 139 ver.Patch = 0 140 } 141 if ver.Patch < 0 { 142 ver.Patch = 0 143 } 144 v = fmt.Sprintf("v%d.%d.%d", ver.Major, ver.Minor, ver.Patch) 145 return 146 } 147 148 func Parse(v []byte) (ver Version, err error) { 149 v = bytes.ToLower(bytes.TrimSpace(v)) 150 if bytes.Equal(v, []byte{'l', 'a', 't', 'e', 's', 't'}) { 151 ver = Latest() 152 return 153 } 154 if v[0] != 'v' { 155 err = errors.Warning("fns: parse version failed").WithCause(fmt.Errorf("invalid pattern")).WithMeta("version", bytex.ToString(v)) 156 return 157 } 158 v = v[1:] 159 items := bytes.Split(v, []byte{'.'}) 160 size := len(items) 161 if size > 3 { 162 err = errors.Warning("fns: parse version failed").WithCause(fmt.Errorf("invalid pattern")).WithMeta("version", bytex.ToString(v)) 163 return 164 } 165 major, minor, patch := -1, -1, -1 166 if size > 0 { 167 major, err = strconv.Atoi(bytex.ToString(bytes.TrimSpace(items[0]))) 168 if err != nil { 169 err = errors.Warning("fns: parse version failed").WithCause(fmt.Errorf("invalid pattern")).WithMeta("version", bytex.ToString(v)) 170 return 171 } 172 } 173 if size > 1 { 174 minor, err = strconv.Atoi(bytex.ToString(bytes.TrimSpace(items[1]))) 175 if err != nil { 176 err = errors.Warning("fns: parse version failed").WithCause(fmt.Errorf("invalid pattern")).WithMeta("version", bytex.ToString(v)) 177 return 178 } 179 } 180 if size > 2 { 181 patch, err = strconv.Atoi(bytex.ToString(bytes.TrimSpace(items[2]))) 182 if err != nil { 183 err = errors.Warning("fns: parse version failed").WithCause(fmt.Errorf("invalid pattern")).WithMeta("version", bytex.ToString(v)) 184 return 185 } 186 } 187 ver = New(major, minor, patch) 188 return 189 }