diff --git a/go.mod b/go.mod index 81c3c7a39..237b4495d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.23 require ( github.com/alicebob/miniredis/v2 v2.34.0 - github.com/aquasecurity/trivy v0.58.2 + github.com/aquasecurity/trivy v0.59.0 github.com/databus23/goslo.policy v0.0.0-20210929125152-81bf2876dbdb github.com/dlmiddlecote/sqlstats v1.0.2 github.com/docker/distribution v2.8.3+incompatible @@ -36,7 +36,7 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/distribution/reference v0.6.0 // indirect github.com/golang-migrate/migrate/v4 v4.18.2 // indirect - github.com/google/go-containerregistry v0.20.2 // indirect + github.com/google/go-containerregistry v0.20.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -50,13 +50,13 @@ require ( github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rabbitmq/amqp091-go v1.10.0 // indirect - github.com/samber/lo v1.47.0 // indirect + github.com/samber/lo v1.49.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/yuin/gopher-lua v1.1.1 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/protobuf v1.36.1 // indirect + golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect + google.golang.org/protobuf v1.36.4 // indirect ) diff --git a/go.sum b/go.sum index a26ecc622..3a8074874 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis/v2 v2.34.0 h1:mBFWMaJSNL9RwdGRyEDoAAv8OQc5UlEhLDQggTglU/0= github.com/alicebob/miniredis/v2 v2.34.0/go.mod h1:kWShP4b58T1CW0Y5dViCd5ztzrDqRWqM3nksiyXk5s8= -github.com/aquasecurity/trivy v0.58.2 h1:ZzJ9wOvXVXIJjkfYNE2CZeG3XyWz4yf9UCejgcp8WVU= -github.com/aquasecurity/trivy v0.58.2/go.mod h1:MFlUXVTUBPaiKtQMCyaAYR6KBERWSzl+T3eMdQhH92g= +github.com/aquasecurity/trivy v0.59.0 h1:ENMpySR/efn8lflYSP37KqPpYXVxklqf0HIpLsVkLfg= +github.com/aquasecurity/trivy v0.59.0/go.mod h1:dJIzxTfeSrUGtDBtbg2AiMbAnbVjo97lsLC9eyAawZI= github.com/aquasecurity/trivy-db v0.0.0-20241209111357-8c398f13db0e h1:O5j5SeCNBrXApgBTOobO06q4LMxJxIhcSGE7H6Y154E= github.com/aquasecurity/trivy-db v0.0.0-20241209111357-8c398f13db0e/go.mod h1:gS8VhlNxhraiq60BBnJw9kGtjeMspQ9E8pX24jCL4jg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -42,8 +42,8 @@ github.com/dlmiddlecote/sqlstats v1.0.2 h1:gSU11YN23D/iY50A2zVYwgXgy072khatTsIW6 github.com/dlmiddlecote/sqlstats v1.0.2/go.mod h1:0CWaIh/Th+z2aI6Q9Jpfg/o21zmGxWhbByHgQSCUQvY= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= -github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.5.0+incompatible h1:um++2NcQtGRTz5eEgO6aJimo6/JxrTXC941hd05JO6U= +github.com/docker/docker v27.5.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -80,8 +80,8 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo= -github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= +github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI= +github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gophercloud/gophercloud/v2 v2.4.0 h1:XhP5tVEH3ni66NSNK1+0iSO6kaGPH/6srtx6Cr+8eCg= github.com/gophercloud/gophercloud/v2 v2.4.0/go.mod h1:uJWNpTgJPSl2gyzJqcU/pIAhFUWvIkp8eE8M15n9rs4= @@ -174,8 +174,8 @@ github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93Ge github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= -github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/samber/lo v1.49.0 h1:AGnTnQrg1jpFuwECPUSoxZCfVH5W22b605kWSry3YxM= +github.com/samber/lo v1.49.0/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o= github.com/sapcc/go-api-declarations v1.13.2 h1:dPYYsjwKGObSAm6+K+dYCiLQWunYuWkywlZnuXfjsmk= github.com/sapcc/go-api-declarations v1.13.2/go.mod h1:83R3hTANhuRXt/pXDby37IJetw8l7DG41s33Tp9NXxI= github.com/sapcc/go-bits v0.0.0-20250130092643-87f841392737 h1:L99i3+H739jgnYUASCjCve1xDkHRFMJBifkN4LkANNg= @@ -199,14 +199,16 @@ github.com/timewasted/go-accept-headers v0.0.0-20130320203746-c78f304b1b09 h1:QV github.com/timewasted/go-accept-headers v0.0.0-20130320203746-c78f304b1b09/go.mod h1:Uy/Rnv5WKuOO+PuDhuYLEpUiiKIZtss3z519uk67aF0= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= @@ -232,10 +234,10 @@ golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/artifact.go b/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/artifact.go index 56d610dc5..a3f861d4e 100644 --- a/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/artifact.go +++ b/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/artifact.go @@ -15,6 +15,14 @@ type OS struct { Extended bool `json:"extended,omitempty"` } +func (o *OS) String() string { + s := string(o.Family) + if o.Name != "" { + s += "/" + o.Name + } + return s +} + func (o *OS) Detected() bool { return o.Family != "" } diff --git a/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/const.go b/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/const.go index 2e07709ad..d7e0a4ec0 100644 --- a/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/const.go +++ b/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/const.go @@ -66,6 +66,7 @@ const ( Pip LangType = "pip" Pipenv LangType = "pipenv" Poetry LangType = "poetry" + Uv LangType = "uv" CondaPkg LangType = "conda-pkg" CondaEnv LangType = "conda-environment" PythonPkg LangType = "python-pkg" @@ -96,13 +97,37 @@ const ( OCP LangType = "ocp" // Red Hat OpenShift Container Platform ) -var AggregatingTypes = []LangType{ - PythonPkg, - CondaPkg, - GemSpec, - NodePkg, - Jar, -} +var ( + OSTypes = []OSType{ + Alma, + Alpine, + Amazon, + Azure, + CBLMariner, + CentOS, + Chainguard, + Debian, + Fedora, + OpenSUSE, + OpenSUSELeap, + OpenSUSETumbleweed, + Oracle, + Photon, + RedHat, + Rocky, + SLEMicro, + SLES, + Ubuntu, + Wolfi, + } + AggregatingTypes = []LangType{ + PythonPkg, + CondaPkg, + GemSpec, + NodePkg, + Jar, + } +) // Config files const ( @@ -143,6 +168,7 @@ const ( PipRequirements = "requirements.txt" PipfileLock = "Pipfile.lock" PoetryLock = "poetry.lock" + UvLock = "uv.lock" GemfileLock = "Gemfile.lock" diff --git a/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/image.go b/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/image.go index 91cdfb44b..12c45de3a 100644 --- a/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/image.go +++ b/vendor/github.com/aquasecurity/trivy/pkg/fanal/types/image.go @@ -53,6 +53,7 @@ type ImageOptions struct { PodmanOptions PodmanOptions ContainerdOptions ContainerdOptions ImageSources ImageSources + MaxImageSize int64 } type DockerOptions struct { @@ -81,6 +82,9 @@ type RegistryOptions struct { // RegistryToken is a bearer token to be sent to a registry RegistryToken string + // RegistryMirrors is a map of hosts with mirrors for them + RegistryMirrors map[string][]string + // SSL/TLS Insecure bool diff --git a/vendor/github.com/samber/lo/.travis.yml b/vendor/github.com/samber/lo/.travis.yml deleted file mode 100644 index f0de7f51c..000000000 --- a/vendor/github.com/samber/lo/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -before_install: - - go mod download - - make tools -go: - - "1.18" -script: make test diff --git a/vendor/github.com/samber/lo/CHANGELOG.md b/vendor/github.com/samber/lo/CHANGELOG.md deleted file mode 100644 index 8b9e4e11f..000000000 --- a/vendor/github.com/samber/lo/CHANGELOG.md +++ /dev/null @@ -1,434 +0,0 @@ -# Changelog - -@samber: I sometimes forget to update this file. Ping me on [Twitter](https://twitter.com/samuelberthe) or open an issue in case of error. We need to keep a clear changelog for easier lib upgrade. - -## 1.39.0 (2023-12-01) - -Improvement: -- Adding IsNil - -## 1.38.1 (2023-03-20) - -Improvement: -- Async and AsyncX: now returns `<-chan T` instead of `chan T` - -## 1.38.0 (2023-03-20) - -Adding: -- lo.ValueOr -- lo.DebounceBy -- lo.EmptyableToPtr - -Improvement: -- Substring: add support for non-English chars - -Fix: -- Async: Fix goroutine leak - -## 1.37.0 (2022-12-15) - -Adding: -- lo.PartialX -- lo.Transaction - -Improvement: -- lo.Associate / lo.SliceToMap: faster memory allocation - -Chore: -- Remove *_test.go files from releases, in order to cleanup dev dependencies - -## 1.36.0 (2022-11-28) - -Adding: -- lo.AttemptWhile -- lo.AttemptWhileWithDelay - -## 1.35.0 (2022-11-15) - -Adding: -- lo.RandomString -- lo.BufferWithTimeout (alias to lo.BatchWithTimeout) -- lo.Buffer (alias to lo.Batch) - -Change: -- lo.Slice: avoid panic caused by out-of-bounds - -Deprecation: -- lo.BatchWithTimeout -- lo.Batch - -## 1.34.0 (2022-11-12) - -Improving: -- lo.Union: faster and can receive more than 2 lists - -Adding: -- lo.FanIn (alias to lo.ChannelMerge) -- lo.FanOut - -Deprecation: -- lo.ChannelMerge - -## 1.33.0 (2022-10-14) - -Adding: -- lo.ChannelMerge - -Improving: -- helpers with callbacks/predicates/iteratee now have named arguments, for easier autocompletion - -## 1.32.0 (2022-10-10) - -Adding: - -- lo.ChannelToSlice -- lo.CountValues -- lo.CountValuesBy -- lo.MapEntries -- lo.Sum -- lo.Interleave -- TupleX.Unpack() - -## 1.31.0 (2022-10-06) - -Adding: - -- lo.SliceToChannel -- lo.Generator -- lo.Batch -- lo.BatchWithTimeout - -## 1.30.1 (2022-10-06) - -Fix: - -- lo.Try1: remove generic type -- lo.Validate: format error properly - -## 1.30.0 (2022-10-04) - -Adding: - -- lo.TernaryF -- lo.Validate - -## 1.29.0 (2022-10-02) - -Adding: - -- lo.ErrorAs -- lo.TryOr -- lo.TryOrX - -## 1.28.0 (2022-09-05) - -Adding: - -- lo.ChannelDispatcher with 6 dispatching strategies: - - lo.DispatchingStrategyRoundRobin - - lo.DispatchingStrategyRandom - - lo.DispatchingStrategyWeightedRandom - - lo.DispatchingStrategyFirst - - lo.DispatchingStrategyLeast - - lo.DispatchingStrategyMost - -## 1.27.1 (2022-08-15) - -Bugfix: - -- Removed comparable constraint for lo.FindKeyBy - -## 1.27.0 (2022-07-29) - -Breaking: - -- Change of MapToSlice prototype: `MapToSlice[K comparable, V any, R any](in map[K]V, iteratee func(V, K) R) []R` -> `MapToSlice[K comparable, V any, R any](in map[K]V, iteratee func(K, V) R) []R` - -Added: - -- lo.ChunkString -- lo.SliceToMap (alias to lo.Associate) - -## 1.26.0 (2022-07-24) - -Adding: - -- lo.Associate -- lo.ReduceRight -- lo.FromPtrOr -- lo.MapToSlice -- lo.IsSorted -- lo.IsSortedByKey - -## 1.25.0 (2022-07-04) - -Adding: - -- lo.FindUniques -- lo.FindUniquesBy -- lo.FindDuplicates -- lo.FindDuplicatesBy -- lo.IsNotEmpty - -## 1.24.0 (2022-07-04) - -Adding: - -- lo.Without -- lo.WithoutEmpty - -## 1.23.0 (2022-07-04) - -Adding: - -- lo.FindKey -- lo.FindKeyBy - -## 1.22.0 (2022-07-04) - -Adding: - -- lo.Slice -- lo.FromPtr -- lo.IsEmpty -- lo.Compact -- lo.ToPairs: alias to lo.Entries -- lo.FromPairs: alias to lo.FromEntries -- lo.Partial - -Change: - -- lo.Must + lo.MustX: add context to panic message - -Fix: - -- lo.Nth: out of bound exception (#137) - -## 1.21.0 (2022-05-10) - -Adding: - -- lo.ToAnySlice -- lo.FromAnySlice - -## 1.20.0 (2022-05-02) - -Adding: - -- lo.Synchronize -- lo.SumBy - -Change: -- Removed generic type definition for lo.Try0: `lo.Try0[T]()` -> `lo.Try0()` - -## 1.19.0 (2022-04-30) - -Adding: - -- lo.RepeatBy -- lo.Subset -- lo.Replace -- lo.ReplaceAll -- lo.Substring -- lo.RuneLength - -## 1.18.0 (2022-04-28) - -Adding: - -- lo.SomeBy -- lo.EveryBy -- lo.None -- lo.NoneBy - -## 1.17.0 (2022-04-27) - -Adding: - -- lo.Unpack2 -> lo.Unpack3 -- lo.Async0 -> lo.Async6 - -## 1.16.0 (2022-04-26) - -Adding: - -- lo.AttemptWithDelay - -## 1.15.0 (2022-04-22) - -Improvement: - -- lo.Must: error or boolean value - -## 1.14.0 (2022-04-21) - -Adding: - -- lo.Coalesce - -## 1.13.0 (2022-04-14) - -Adding: - -- PickBy -- PickByKeys -- PickByValues -- OmitBy -- OmitByKeys -- OmitByValues -- Clamp -- MapKeys -- Invert -- IfF + ElseIfF + ElseF -- T0() + T1() + T2() + T3() + ... - -## 1.12.0 (2022-04-12) - -Adding: - -- Must -- Must{0-6} -- FindOrElse -- Async -- MinBy -- MaxBy -- Count -- CountBy -- FindIndexOf -- FindLastIndexOf -- FilterMap - -## 1.11.0 (2022-03-11) - -Adding: - -- Try -- Try{0-6} -- TryWitchValue -- TryCatch -- TryCatchWitchValue -- Debounce -- Reject - -## 1.10.0 (2022-03-11) - -Adding: - -- Range -- RangeFrom -- RangeWithSteps - -## 1.9.0 (2022-03-10) - -Added - -- Drop -- DropRight -- DropWhile -- DropRightWhile - -## 1.8.0 (2022-03-10) - -Adding Union. - -## 1.7.0 (2022-03-09) - -Adding ContainBy - -Adding MapValues - -Adding FlatMap - -## 1.6.0 (2022-03-07) - -Fixed PartitionBy. - -Adding Sample - -Adding Samples - -## 1.5.0 (2022-03-07) - -Adding Times - -Adding Attempt - -Adding Repeat - -## 1.4.0 (2022-03-07) - -- adding tuple types (2->9) -- adding Zip + Unzip -- adding lo.PartitionBy + lop.PartitionBy -- adding lop.GroupBy -- fixing Nth - -## 1.3.0 (2022-03-03) - -Last and Nth return errors - -## 1.2.0 (2022-03-03) - -Adding `lop.Map` and `lop.ForEach`. - -## 1.1.0 (2022-03-03) - -Adding `i int` param to `lo.Map()`, `lo.Filter()`, `lo.ForEach()` and `lo.Reduce()` predicates. - -## 1.0.0 (2022-03-02) - -*Initial release* - -Supported helpers for slices: - -- Filter -- Map -- Reduce -- ForEach -- Uniq -- UniqBy -- GroupBy -- Chunk -- Flatten -- Shuffle -- Reverse -- Fill -- ToMap - -Supported helpers for maps: - -- Keys -- Values -- Entries -- FromEntries -- Assign (maps merge) - -Supported intersection helpers: - -- Contains -- Every -- Some -- Intersect -- Difference - -Supported search helpers: - -- IndexOf -- LastIndexOf -- Find -- Min -- Max -- Last -- Nth - -Other functional programming helpers: - -- Ternary (1 line if/else statement) -- If / ElseIf / Else -- Switch / Case / Default -- ToPtr -- ToSlicePtr - -Constraints: - -- Clonable diff --git a/vendor/github.com/samber/lo/Dockerfile b/vendor/github.com/samber/lo/Dockerfile index 5eab431ac..5dbeb415b 100644 --- a/vendor/github.com/samber/lo/Dockerfile +++ b/vendor/github.com/samber/lo/Dockerfile @@ -1,5 +1,5 @@ -FROM golang:1.21.12 +FROM golang:1.23.1 WORKDIR /go/src/github.com/samber/lo diff --git a/vendor/github.com/samber/lo/LICENSE b/vendor/github.com/samber/lo/LICENSE index c3dc72d9a..2e3ebd5e8 100644 --- a/vendor/github.com/samber/lo/LICENSE +++ b/vendor/github.com/samber/lo/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Samuel Berthe +Copyright (c) 2022-2025 Samuel Berthe Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/samber/lo/README.md b/vendor/github.com/samber/lo/README.md index 3f73cc8e6..a3526a46a 100644 --- a/vendor/github.com/samber/lo/README.md +++ b/vendor/github.com/samber/lo/README.md @@ -1,3 +1,4 @@ + # lo - Iterate over slices, maps, channels... [![tag](https://img.shields.io/github/tag/samber/lo.svg)](https://github.com/samber/lo/releases) @@ -80,6 +81,7 @@ Supported helpers for slices: - [Filter](#filter) - [Map](#map) +- [UniqMap](#uniqmap) - [FilterMap](#filtermap) - [FlatMap](#flatmap) - [Reduce](#reduce) @@ -100,7 +102,9 @@ Supported helpers for slices: - [Repeat](#repeat) - [RepeatBy](#repeatby) - [KeyBy](#keyby) -- [Associate / SliceToMap](#associate-alias-slicetomap) +- [SliceToMap / Associate](#slicetomap-alias-associate) +- [FilterSliceToMap](#filterslicetomap) +- [Keyify](#keyify) - [Drop](#drop) - [DropRight](#dropright) - [DropWhile](#dropwhile) @@ -151,6 +155,8 @@ Supported math helpers: - [Clamp](#clamp) - [Sum](#sum) - [SumBy](#sumby) +- [Product](#product) +- [ProductBy](#productby) - [Mean](#mean) - [MeanBy](#meanby) @@ -166,7 +172,7 @@ Supported helpers for strings: - [SnakeCase](#snakecase) - [Words](#words) - [Capitalize](#capitalize) -- [Elipse](#elipse) +- [Ellipsis](#ellipsis) Supported helpers for tuples: @@ -176,11 +182,13 @@ Supported helpers for tuples: - [ZipBy2 -> ZipBy9](#zipby2---zipby9) - [Unzip2 -> Unzip9](#unzip2---unzip9) - [UnzipBy2 -> UnzipBy9](#unzipby2---unzipby9) +- [CrossJoin2 -> CrossJoin2](#crossjoin2---crossjoin9) +- [CrossJoinBy2 -> CrossJoinBy2](#crossjoinby2---crossjoinby9) Supported helpers for time and duration: - [Duration](#duration) -- [Duration0 -> Duration10](#duration0-duration10) +- [Duration0 -> Duration10](#duration0---duration10) Supported helpers for channels: @@ -188,6 +196,7 @@ Supported helpers for channels: - [SliceToChannel](#slicetochannel) - [Generator](#generator) - [Buffer](#buffer) +- [BufferWithContext](#bufferwithcontext) - [BufferWithTimeout](#bufferwithtimeout) - [FanIn](#fanin) - [FanOut](#fanout) @@ -206,7 +215,9 @@ Supported intersection helpers: - [Difference](#difference) - [Union](#union) - [Without](#without) +- [WithoutBy](#withoutby) - [WithoutEmpty](#withoutempty) +- [WithoutNth](#withoutnth) Supported search helpers: @@ -223,11 +234,15 @@ Supported search helpers: - [FindDuplicates](#findduplicates) - [FindDuplicatesBy](#findduplicatesby) - [Min](#min) +- [MinIndex](#minindex) - [MinBy](#minby) +- [MinIndexBy](#minindexby) - [Earliest](#earliest) - [EarliestBy](#earliestby) - [Max](#max) +- [MaxIndex](#maxindex) - [MaxBy](#maxby) +- [MaxIndexBy](#maxindexby) - [Latest](#latest) - [LatestBy](#latestby) - [First](#first) @@ -238,7 +253,9 @@ Supported search helpers: - [LastOr](#LastOr) - [Nth](#nth) - [Sample](#sample) +- [SampleBy](#sampleby) - [Samples](#samples) +- [SamplesBy](#samplesby) Conditional helpers: @@ -250,6 +267,7 @@ Conditional helpers: Type manipulation helpers: - [IsNil](#isnil) +- [IsNotNil](#isnotnil) - [ToPtr](#toptr) - [Nil](#nil) - [EmptyableToPtr](#emptyabletoptr) @@ -265,6 +283,10 @@ Type manipulation helpers: - [IsNotEmpty](#isnotempty) - [Coalesce](#coalesce) - [CoalesceOrEmpty](#coalesceorempty) +- [CoalesceSlice](#coalesceslice) +- [CoalesceSliceOrEmpty](#coalescesliceorempty) +- [CoalesceMap](#coalescemap) +- [CoalesceMapOrEmpty](#coalescemaporempty) Function helpers: @@ -279,6 +301,10 @@ Concurrency helpers: - [AttemptWhileWithDelay](#attemptwhilewithdelay) - [Debounce](#debounce) - [DebounceBy](#debounceby) +- [Throttle](#throttle) +- [ThrottleWithCount](#throttle) +- [ThrottleBy](#throttle) +- [ThrottleByWithCount](#throttle) - [Synchronize](#synchronize) - [Async](#async) - [Transaction](#transaction) @@ -341,6 +367,23 @@ lop.Map([]int64{1, 2, 3, 4}, func(x int64, _ int) string { // []string{"1", "2", "3", "4"} ``` +### UniqMap + +Manipulates a slice and transforms it to a slice of another type with unique values. + +```go +type User struct { + Name string + Age int +} +users := []User{{Name: "Alex", Age: 10}, {Name: "Alex", Age: 12}, {Name: "Bob", Age: 11}, {Name: "Alice", Age: 20}} + +names := lo.UniqMap(users, func(u User, index int) string { + return u.Name +}) +// []string{"Alex", "Bob", "Alice"} +``` + ### FilterMap Returns a slice which obtained after both filtering and mapping using the given callback function. @@ -608,25 +651,34 @@ interleaved := lo.Interleave([]int{1}, []int{2, 5, 8}, []int{3, 6}, []int{4, 7, Returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm. +⚠️ This helper is **mutable**. + ```go -randomOrder := lo.Shuffle([]int{0, 1, 2, 3, 4, 5}) +import lom "github.com/samber/lo/mutable" + +randomOrder := lom.Shuffle([]int{0, 1, 2, 3, 4, 5}) // []int{1, 4, 0, 3, 5, 2} ``` -[[play](https://go.dev/play/p/Qp73bnTDnc7)] +[[play](https://go.dev/play/p/ZTGG7OUCdnp)] ### Reverse Reverses array so that the first element becomes the last, the second element becomes the second to last, and so on. -⚠️ This helper is **mutable**. This behavior might change in `v2.0.0`. See [#160](https://github.com/samber/lo/issues/160). +⚠️ This helper is **mutable**. ```go -reverseOrder := lo.Reverse([]int{0, 1, 2, 3, 4, 5}) +import lom "github.com/samber/lo/mutable" + +list := []int{0, 1, 2, 3, 4, 5} +lom.Reverse(list) + +list // []int{5, 4, 3, 2, 1, 0} ``` -[[play](https://go.dev/play/p/fhUMLvZ7vS6)] +[[play](https://go.dev/play/p/iv2e9jslfBM)] ### Fill @@ -710,7 +762,7 @@ result := lo.KeyBy(characters, func(char Character) string { [[play](https://go.dev/play/p/mdaClUAT-zZ)] -### Associate (alias: SliceToMap) +### SliceToMap (alias: Associate) Returns a map containing key-value pairs provided by transform function applied to elements of the given slice. If any of two pairs would have the same key the last one gets added to the map. @@ -720,7 +772,7 @@ The order of keys in returned map is not specified and is not guaranteed to be t ```go in := []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}} -aMap := lo.Associate(in, func (f *foo) (string, int) { +aMap := lo.SliceToMap(in, func (f *foo) (string, int) { return f.baz, f.bar }) // map[string][int]{ "apple":1, "banana":2 } @@ -728,6 +780,35 @@ aMap := lo.Associate(in, func (f *foo) (string, int) { [[play](https://go.dev/play/p/WHa2CfMO3Lr)] +### FilterSliceToMap + +Returns a map containing key-value pairs provided by transform function applied to elements of the given slice. + +If any of two pairs would have the same key the last one gets added to the map. + +The order of keys in returned map is not specified and is not guaranteed to be the same from the original array. + +The third return value of the transform function is a boolean that indicates whether the key-value pair should be included in the map. + + +```go +list := []string{"a", "aa", "aaa"} + +result := lo.FilterSliceToMap(list, func(str string) (string, int, bool) { + return str, len(str), len(str) > 1 +}) +// map[string][int]{"aa":2 "aaa":3} +``` + +### Keyify + +Returns a map with each unique element of the slice as a key. + +```go +set := lo.Keyify([]int{1, 1, 2, 3, 4}) +// map[int]struct{}{1:{}, 2:{}, 3:{}, 4:{}} +``` + ### Drop Drops n elements from the beginning of a slice or array. @@ -787,7 +868,6 @@ l := lo.DropByIndex([]int{0, 1, 2, 3, 4, 5}, 2, 4, -1) [[play](https://go.dev/play/p/JswS7vXRJP2)] - ### Reject The opposite of Filter, this method returns the elements of collection that predicate does not return truthy for. @@ -806,6 +886,7 @@ odd := lo.Reject([]int{1, 2, 3, 4}, func(x int, _ int) bool { The opposite of FilterMap, this method returns a slice which obtained after both filtering and mapping using the given callback function. The callback function should return two values: + - the result of the mapping operation and - whether the result element should be included or not. @@ -1039,7 +1120,7 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") // []string{"a", "b", "1", "2"} ``` -[[play](https://go.dev/play/p/G5_GhkeSUBA)] +[[play](https://go.dev/play/p/wiG6XyBBu49)] ### Keys @@ -1062,13 +1143,13 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) ### UniqKeys -Creates an array of unique map keys. +Creates an array of unique map keys. ```go -keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) +keys := lo.UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) // []string{"foo", "bar", "baz"} -keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) +keys := lo.UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) // []string{"foo", "bar"} ``` @@ -1276,6 +1357,27 @@ mergedMaps := lo.Assign( [[play](https://go.dev/play/p/VhwfJOyxf5o)] +### ChunkEntries + +Splits a map into an array of elements in groups of a length equal to its size. If the map cannot be split evenly, the final chunk will contain the remaining elements. + +```go +maps := lo.ChunkEntries( + map[string]int{ + "a": 1, + "b": 2, + "c": 3, + "d": 4, + "e": 5, + }, + 3, +) +// []map[string]int{ +// {"a": 1, "b": 2, "c": 3}, +// {"d": 4, "e": 5}, +// } +``` + ### MapKeys Manipulates a map keys and transforms it to a map of another type. @@ -1411,7 +1513,35 @@ sum := lo.SumBy(strings, func(item string) int { // 6 ``` -[[play](https://go.dev/play/p/Dz_a_7jN_ca)] +### Product + +Calculates the product of the values in a collection. + +If collection is empty 0 is returned. + +```go +list := []int{1, 2, 3, 4, 5} +product := lo.Product(list) +// 120 +``` + +[[play](https://go.dev/play/p/2_kjM_smtAH)] + +### ProductBy + +Calculates the product of the values in a collection using the given return value from the iteration function. + +If collection is empty 0 is returned. + +```go +strings := []string{"foo", "bar"} +product := lo.ProductBy(strings, func(item string) int { + return len(item) +}) +// 9 +``` + +[[play](https://go.dev/play/p/wadzrWr9Aer)] ### Mean @@ -1575,18 +1705,18 @@ str := lo.Capitalize("heLLO") // Hello ``` -### Elipse +### Ellipsis -Truncates a string to a specified length and appends an ellipsis if truncated. +Trims and truncates a string to a specified length and appends an ellipsis if truncated. ```go -str := lo.Elipse("Lorem Ipsum", 5) +str := lo.Ellipsis(" Lorem Ipsum ", 5) // Lo... -str := lo.Elipse("Lorem Ipsum", 100) +str := lo.Ellipsis("Lorem Ipsum", 100) // Lorem Ipsum -str := lo.Elipse("Lorem Ipsum", 3) +str := lo.Ellipsis("Lorem Ipsum", 3) // ... ``` @@ -1674,6 +1804,36 @@ a, b := lo.UnzipBy2([]string{"hello", "john", "doe"}, func(str string) (string, // []int{5, 4, 3} ``` +### CrossJoin2 -> CrossJoin9 + +Combines every items from one list with every items from others. It is the cartesian product of lists received as arguments. It returns an empty list if a list is empty. + +```go +result := lo.CrossJoin2([]string{"hello", "john", "doe"}, []int{1, 2}) +// lo.Tuple2{"hello", 1} +// lo.Tuple2{"hello", 2} +// lo.Tuple2{"john", 1} +// lo.Tuple2{"john", 2} +// lo.Tuple2{"doe", 1} +// lo.Tuple2{"doe", 2} +``` + +### CrossJoinBy2 -> CrossJoinBy9 + +Combines every items from one list with every items from others. It is the cartesian product of lists received as arguments. The project function is used to create the output values. It returns an empty list if a list is empty. + +```go +result := lo.CrossJoinBy2([]string{"hello", "john", "doe"}, []int{1, 2}, func(a A, b B) string { + return fmt.Sprintf("%s - %d", a, b) +}) +// "hello - 1" +// "hello - 2" +// "john - 1" +// "john - 2" +// "doe - 1" +// "doe - 2" +``` + ### Duration Returns the time taken to execute a function. @@ -1864,6 +2024,32 @@ for { } ``` +### BufferWithContext + +Creates a slice of n elements from a channel, with timeout. Returns the slice, the slice length, the read time and the channel status (opened/closed). + +```go +ctx, cancel := context.WithCancel(context.TODO()) +go func() { + ch <- 0 + time.Sleep(10*time.Millisecond) + ch <- 1 + time.Sleep(10*time.Millisecond) + ch <- 2 + time.Sleep(10*time.Millisecond) + ch <- 3 + time.Sleep(10*time.Millisecond) + ch <- 4 + time.Sleep(10*time.Millisecond) + cancel() +}() + +items1, length1, duration1, ok1 := lo.BufferWithContext(ctx, ch, 3) +// []int{0, 1, 2}, 3, 20ms, true +items2, length2, duration2, ok2 := lo.BufferWithContext(ctx, ch, 3) +// []int{3, 4}, 2, 30ms, false +``` + ### BufferWithTimeout Creates a slice of n elements from a channel, with timeout. Returns the slice, the slice length, the read time and the channel status (opened/closed). @@ -1990,7 +2176,7 @@ ok := lo.Every([]int{0, 1, 2, 3, 4, 5}, []int{0, 6}) ### EveryBy -Returns true if the predicate returns true for all of the elements in the collection or if the collection is empty. +Returns true if the predicate returns true for all elements in the collection or if the collection is empty. ```go b := EveryBy([]int{1, 2, 3, 4}, func(x int) bool { @@ -2005,7 +2191,7 @@ Returns true if at least 1 element of a subset is contained into a collection. If the subset is empty Some returns false. ```go -ok := lo.Some([]int{0, 1, 2, 3, 4, 5}, []int{0, 2}) +ok := lo.Some([]int{0, 1, 2, 3, 4, 5}, []int{0, 6}) // true ok := lo.Some([]int{0, 1, 2, 3, 4, 5}, []int{-1, 6}) @@ -2097,15 +2283,57 @@ subset := lo.Without([]int{0, 2, 10}, 0, 1, 2, 3, 4, 5) // []int{10} ``` +### WithoutBy + +Filters a slice by excluding elements whose extracted keys match any in the exclude list. + +It returns a new slice containing only the elements whose keys are not in the exclude list. + + +```go +type struct User { + ID int + Name string +} + +// original users +users := []User{ + {ID: 1, Name: "Alice"}, + {ID: 2, Name: "Bob"}, + {ID: 3, Name: "Charlie"}, +} + +// extract function to get the user ID +getID := func(user User) int { + return user.ID +} + +// exclude users with IDs 2 and 3 +excludedIDs := []int{2, 3} + +// filtering users +filteredUsers := lo.WithoutBy(users, getID, excludedIDs...) +// []User[{ID: 1, Name: "Alice"}] +``` + ### WithoutEmpty -Returns slice excluding empty values. +Returns slice excluding zero values. ```go subset := lo.WithoutEmpty([]int{0, 2, 10}) // []int{2, 10} ``` +### WithoutNth + +Returns slice excluding nth value. + +```go +subset := lo.WithoutNth([]int{-2, -1, 0, 1, 2}, 3, -42, 1) +// []int{-2, 0, 2} +``` + ### IndexOf Returns the index at which the first occurrence of a value is found in an array or return -1 if the value cannot be found. @@ -2285,6 +2513,23 @@ min := lo.Min([]time.Duration{time.Second, time.Hour}) // 1s ``` +### MinIndex + +Search the minimum value of a collection and the index of the minimum value. + +Returns (zero value, -1) when the collection is empty. + +```go +min, index := lo.MinIndex([]int{1, 2, 3}) +// 1, 0 + +min, index := lo.MinIndex([]int{}) +// 0, -1 + +min, index := lo.MinIndex([]time.Duration{time.Second, time.Hour}) +// 1s, 0 +``` + ### MinBy Search the minimum value of a collection using the given comparison function. @@ -2305,6 +2550,26 @@ min := lo.MinBy([]string{}, func(item string, min string) bool { // "" ``` +### MinIndexBy + +Search the minimum value of a collection using the given comparison function and the index of the minimum value. + +If several values of the collection are equal to the smallest value, returns the first such value. + +Returns (zero value, -1) when the collection is empty. + +```go +min, index := lo.MinIndexBy([]string{"s1", "string2", "s3"}, func(item string, min string) bool { + return len(item) < len(min) +}) +// "s1", 0 + +min, index := lo.MinIndexBy([]string{}, func(item string, min string) bool { + return len(item) < len(min) +}) +// "", -1 +``` + ### Earliest Search the minimum time.Time of a collection. @@ -2350,6 +2615,23 @@ max := lo.Max([]time.Duration{time.Second, time.Hour}) // 1h ``` +### MaxIndex + +Search the maximum value of a collection and the index of the maximum value. + +Returns (zero value, -1) when the collection is empty. + +```go +max, index := lo.MaxIndex([]int{1, 2, 3}) +// 3, 2 + +max, index := lo.MaxIndex([]int{}) +// 0, -1 + +max, index := lo.MaxIndex([]time.Duration{time.Second, time.Hour}) +// 1h, 1 +``` + ### MaxBy Search the maximum value of a collection using the given comparison function. @@ -2370,6 +2652,26 @@ max := lo.MaxBy([]string{}, func(item string, max string) bool { // "" ``` +### MaxIndexBy + +Search the maximum value of a collection using the given comparison function and the index of the maximum value. + +If several values of the collection are equal to the greatest value, returns the first such value. + +Returns (zero value, -1) when the collection is empty. + +```go +max, index := lo.MaxIndexBy([]string{"string1", "s2", "string3"}, func(item string, max string) bool { + return len(item) > len(max) +}) +// "string1", 0 + +max, index := lo.MaxIndexBy([]string{}, func(item string, max string) bool { + return len(item) > len(max) +}) +// "", -1 +``` + ### Latest Search the maximum time.Time of a collection. @@ -2421,6 +2723,7 @@ first := lo.FirstOrEmpty([]int{1, 2, 3}) first := lo.FirstOrEmpty([]int{}) // 0 ``` + ### FirstOr Returns the first element of a collection or the fallback value if empty. @@ -2458,6 +2761,7 @@ last := lo.LastOrEmpty([]int{1, 2, 3}) last := lo.LastOrEmpty([]int{}) // 0 ``` + ### LastOr Returns the first element of a collection or the fallback value if empty. @@ -2494,6 +2798,21 @@ lo.Sample([]string{}) // "" ``` +### SampleBy + +Returns a random item from collection, using a given random integer generator. + +```go +import "math/rand" + +r := rand.New(rand.NewSource(42)) +lo.SampleBy([]string{"a", "b", "c"}, r.Intn) +// a random string from []string{"a", "b", "c"}, using a seeded random generator + +lo.SampleBy([]string{}, r.Intn) +// "" +``` + ### Samples Returns N random unique items from collection. @@ -2503,6 +2822,16 @@ lo.Samples([]string{"a", "b", "c"}, 3) // []string{"a", "b", "c"} in random order ``` +### SamplesBy + +Returns N random unique items from collection, using a given random integer generator. + +```go +r := rand.New(rand.NewSource(42)) +lo.SamplesBy([]string{"a", "b", "c"}, 3, r.Intn) +// []string{"a", "b", "c"} in random order, using a seeded random generator +``` + ### Ternary A 1 line if/else statement. @@ -2643,24 +2972,48 @@ Checks if a value is nil or if it's a reference type with a nil underlying value ```go var x int -IsNil(x)) +lo.IsNil(x) // false var k struct{} -IsNil(k) +lo.IsNil(k) // false var i *int -IsNil(i) +lo.IsNil(i) // true var ifaceWithNilValue any = (*string)(nil) -IsNil(ifaceWithNilValue) +lo.IsNil(ifaceWithNilValue) // true ifaceWithNilValue == nil // false ``` +### IsNotNil + +Checks if a value is not nil or if it's not a reference type with a nil underlying value. + +```go +var x int +lo.IsNotNil(x) +// true + +var k struct{} +lo.IsNotNil(k) +// true + +var i *int +lo.IsNotNil(i) +// false + +var ifaceWithNilValue any = (*string)(nil) +lo.IsNotNil(ifaceWithNilValue) +// false +ifaceWithNilValue == nil +// true +``` + ### ToPtr Returns a pointer copy of the value. @@ -2759,10 +3112,12 @@ Returns a slice with the pointer values or the fallback value. str1 := "hello" str2 := "world" -ptr := lo.FromSlicePtrOr[string]([]*string{&str1, &str2, "fallback value"}) -// []string{"hello", "world", "fallback value"} +ptr := lo.FromSlicePtrOr([]*string{&str1, nil, &str2}, "fallback value") +// []string{"hello", "fallback value", "world"} ``` +[[play](https://go.dev/play/p/CuXGVzo9G65)] + ### ToAnySlice Returns a slice with all elements mapped to `any` type. @@ -2786,7 +3141,7 @@ elements, ok := lo.FromAnySlice([]any{"foobar", "42"}) ### Empty -Returns an empty value. +Returns the [zero value](https://go.dev/ref/spec#The_zero_value). ```go lo.Empty[int]() @@ -2881,6 +3236,58 @@ result := lo.CoalesceOrEmpty(nil, nilStr, &str) // &"foobar" ``` +### CoalesceSlice + +Returns the first non-zero slice. + +```go +result, ok := lo.CoalesceSlice([]int{1, 2, 3}, []int{4, 5, 6}) +// [1, 2, 3] +// true + +result, ok := lo.CoalesceSlice(nil, []int{}) +// [] +// true +``` + +### CoalesceSliceOrEmpty + +Returns the first non-zero slice. + +```go +result := lo.CoalesceSliceOrEmpty([]int{1, 2, 3}, []int{4, 5, 6}) +// [1, 2, 3] + +result := lo.CoalesceSliceOrEmpty(nil, []int{}) +// [] +``` + +### CoalesceMap + +Returns the first non-zero map. + +```go +result, ok := lo.CoalesceMap(map[string]int{"1": 1, "2": 2, "3": 3}, map[string]int{"4": 4, "5": 5, "6": 6}) +// [1, 2, 3] +// true + +result, ok := lo.CoalesceMap(nil, map[string]int{}) +// [] +// true +``` + +### CoalesceMapOrEmpty + +Returns the first non-zero map. + +```go +result := lo.CoalesceMapOrEmpty(map[string]int{"1": 1, "2": 2, "3": 3}, map[string]int{"4": 4, "5": 5, "6": 6}) +// {"1": 1, "2": 2, "3": 3} + +result := lo.CoalesceMapOrEmpty(nil, map[string]int{}) +// {} +``` + ### Partial Returns new function that, when called, has its first argument set to the provided value. @@ -2913,7 +3320,9 @@ f(42, -4) ### Attempt -Invokes a function N times until it returns valid output. Returning either the caught error or nil. When first argument is less than `1`, the function runs until a successful response is returned. +Invokes a function N times until it returns valid output. Returns either the caught error or nil. + +When the first argument is less than `1`, the function runs until a successful response is returned. ```go iter, err := lo.Attempt(42, func(i int) error { @@ -2953,9 +3362,9 @@ For more advanced retry strategies (delay, exponential backoff...), please take ### AttemptWithDelay -Invokes a function N times until it returns valid output, with a pause between each call. Returning either the caught error or nil. +Invokes a function N times until it returns valid output, with a pause between each call. Returns either the caught error or nil. -When first argument is less than `1`, the function runs until a successful response is returned. +When the first argument is less than `1`, the function runs until a successful response is returned. ```go iter, duration, err := lo.AttemptWithDelay(5, 2*time.Second, func(i int, duration time.Duration) error { @@ -2976,9 +3385,9 @@ For more advanced retry strategies (delay, exponential backoff...), please take ### AttemptWhile -Invokes a function N times until it returns valid output. Returning either the caught error or nil, and along with a bool value to identifying whether it needs invoke function continuously. It will terminate the invoke immediately if second bool value is returned with falsy value. +Invokes a function N times until it returns valid output. Returns either the caught error or nil, along with a bool value to determine whether the function should be invoked again. It will terminate the invoke immediately if the second return value is false. -When first argument is less than `1`, the function runs until a successful response is returned. +When the first argument is less than `1`, the function runs until a successful response is returned. ```go count1, err1 := lo.AttemptWhile(5, func(i int) (error, bool) { @@ -3001,9 +3410,9 @@ For more advanced retry strategies (delay, exponential backoff...), please take ### AttemptWhileWithDelay -Invokes a function N times until it returns valid output, with a pause between each call. Returning either the caught error or nil, and along with a bool value to identifying whether it needs to invoke function continuously. It will terminate the invoke immediately if second bool value is returned with falsy value. +Invokes a function N times until it returns valid output, with a pause between each call. Returns either the caught error or nil, along with a bool value to determine whether the function should be invoked again. It will terminate the invoke immediately if the second return value is false. -When first argument is less than `1`, the function runs until a successful response is returned. +When the first argument is less than `1`, the function runs until a successful response is returned. ```go count1, time1, err1 := lo.AttemptWhileWithDelay(5, time.Millisecond, func(i int, d time.Duration) (error, bool) { @@ -3066,6 +3475,64 @@ cancel("second key") [[play](https://go.dev/play/p/d3Vpt6pxhY8)] +### Throttle + +Creates a throttled instance that invokes given functions only once in every interval. + +This returns 2 functions, First one is throttled function and Second one is a function to reset interval. + +```go +f := func() { + println("Called once in every 100ms") +} + +throttle, reset := lo.NewThrottle(100 * time.Millisecond, f) + +for j := 0; j < 10; j++ { + throttle() + time.Sleep(30 * time.Millisecond) +} + +reset() +throttle() +``` + +`NewThrottleWithCount` is NewThrottle with count limit, throttled function will be invoked count times in every interval. + +```go +f := func() { + println("Called three times in every 100ms") +} + +throttle, reset := lo.NewThrottleWithCount(100 * time.Millisecond, f) + +for j := 0; j < 10; j++ { + throttle() + time.Sleep(30 * time.Millisecond) +} + +reset() +throttle() +``` + +`NewThrottleBy` and `NewThrottleByWithCount` are NewThrottle with sharding key, throttled function will be invoked count times in every interval. + +```go +f := func(key string) { + println(key, "Called three times in every 100ms") +} + +throttle, reset := lo.NewThrottleByWithCount(100 * time.Millisecond, f) + +for j := 0; j < 10; j++ { + throttle("foo") + time.Sleep(30 * time.Millisecond) +} + +reset() +throttle() +``` + ### Synchronize Wraps the underlying callback in a mutex. It receives an optional mutex. @@ -3209,7 +3676,6 @@ iterations, duration, ok := lo.WaitFor(laterTrue, 10*time.Millisecond, 5*time.Mi // false ``` - ### WaitForWithContext Runs periodically until a condition is validated or context is invalid. @@ -3492,7 +3958,7 @@ if rateLimitErr, ok := lo.ErrorsAs[*RateLimitError](err); ok { We executed a simple benchmark with a dead-simple `lo.Map` loop: -See the full implementation [here](./benchmark_test.go). +See the full implementation [here](./map_benchmark_test.go). ```go _ = lo.Map[int64](arr, func(x int64, i int) string { diff --git a/vendor/github.com/samber/lo/channel.go b/vendor/github.com/samber/lo/channel.go index 228705ae3..a1e2cddcf 100644 --- a/vendor/github.com/samber/lo/channel.go +++ b/vendor/github.com/samber/lo/channel.go @@ -1,6 +1,7 @@ package lo import ( + "context" "sync" "time" @@ -220,17 +221,13 @@ func Batch[T any](ch <-chan T, size int) (collection []T, length int, readTime t return Buffer(ch, size) } -// BufferWithTimeout creates a slice of n elements from a channel, with timeout. Returns the slice and the slice length. +// BufferWithContext creates a slice of n elements from a channel, with context. Returns the slice and the slice length. // @TODO: we should probably provide an helper that reuse the same buffer. -func BufferWithTimeout[T any](ch <-chan T, size int, timeout time.Duration) (collection []T, length int, readTime time.Duration, ok bool) { - expire := time.NewTimer(timeout) - defer expire.Stop() - +func BufferWithContext[T any](ctx context.Context, ch <-chan T, size int) (collection []T, length int, readTime time.Duration, ok bool) { buffer := make([]T, 0, size) - index := 0 now := time.Now() - for ; index < size; index++ { + for index := 0; index < size; index++ { select { case item, ok := <-ch: if !ok { @@ -239,12 +236,19 @@ func BufferWithTimeout[T any](ch <-chan T, size int, timeout time.Duration) (col buffer = append(buffer, item) - case <-expire.C: + case <-ctx.Done(): return buffer, index, time.Since(now), true } } - return buffer, index, time.Since(now), true + return buffer, size, time.Since(now), true +} + +// BufferWithTimeout creates a slice of n elements from a channel, with timeout. Returns the slice and the slice length. +func BufferWithTimeout[T any](ch <-chan T, size int, timeout time.Duration) (collection []T, length int, readTime time.Duration, ok bool) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + return BufferWithContext(ctx, ch, size) } // BatchWithTimeout creates a slice of n elements from a channel, with timeout. Returns the slice and the slice length. diff --git a/vendor/github.com/samber/lo/errors.go b/vendor/github.com/samber/lo/errors.go index e63bf5d82..493580b12 100644 --- a/vendor/github.com/samber/lo/errors.go +++ b/vendor/github.com/samber/lo/errors.go @@ -10,7 +10,7 @@ import ( // Play: https://go.dev/play/p/vPyh51XpCBt func Validate(ok bool, format string, args ...any) error { if !ok { - return fmt.Errorf(fmt.Sprintf(format, args...)) + return fmt.Errorf(format, args...) } return nil } diff --git a/vendor/github.com/samber/lo/find.go b/vendor/github.com/samber/lo/find.go index ea577ae2a..5d1b986cb 100644 --- a/vendor/github.com/samber/lo/find.go +++ b/vendor/github.com/samber/lo/find.go @@ -241,6 +241,32 @@ func Min[T constraints.Ordered](collection []T) T { return min } +// MinIndex search the minimum value of a collection and the index of the minimum value. +// Returns (zero value, -1) when the collection is empty. +func MinIndex[T constraints.Ordered](collection []T) (T, int) { + var ( + min T + index int + ) + + if len(collection) == 0 { + return min, -1 + } + + min = collection[0] + + for i := 1; i < len(collection); i++ { + item := collection[i] + + if item < min { + min = item + index = i + } + } + + return min, index +} + // MinBy search the minimum value of a collection using the given comparison function. // If several values of the collection are equal to the smallest value, returns the first such value. // Returns zero value when the collection is empty. @@ -264,6 +290,33 @@ func MinBy[T any](collection []T, comparison func(a T, b T) bool) T { return min } +// MinIndexBy search the minimum value of a collection using the given comparison function and the index of the minimum value. +// If several values of the collection are equal to the smallest value, returns the first such value. +// Returns (zero value, -1) when the collection is empty. +func MinIndexBy[T any](collection []T, comparison func(a T, b T) bool) (T, int) { + var ( + min T + index int + ) + + if len(collection) == 0 { + return min, -1 + } + + min = collection[0] + + for i := 1; i < len(collection); i++ { + item := collection[i] + + if comparison(item, min) { + min = item + index = i + } + } + + return min, index +} + // Earliest search the minimum time.Time of a collection. // Returns zero value when the collection is empty. func Earliest(times ...time.Time) time.Time { @@ -332,6 +385,32 @@ func Max[T constraints.Ordered](collection []T) T { return max } +// MaxIndex searches the maximum value of a collection and the index of the maximum value. +// Returns (zero value, -1) when the collection is empty. +func MaxIndex[T constraints.Ordered](collection []T) (T, int) { + var ( + max T + index int + ) + + if len(collection) == 0 { + return max, -1 + } + + max = collection[0] + + for i := 1; i < len(collection); i++ { + item := collection[i] + + if item > max { + max = item + index = i + } + } + + return max, index +} + // MaxBy search the maximum value of a collection using the given comparison function. // If several values of the collection are equal to the greatest value, returns the first such value. // Returns zero value when the collection is empty. @@ -355,6 +434,33 @@ func MaxBy[T any](collection []T, comparison func(a T, b T) bool) T { return max } +// MaxIndexBy search the maximum value of a collection using the given comparison function and the index of the maximum value. +// If several values of the collection are equal to the greatest value, returns the first such value. +// Returns (zero value, -1) when the collection is empty. +func MaxIndexBy[T any](collection []T, comparison func(a T, b T) bool) (T, int) { + var ( + max T + index int + ) + + if len(collection) == 0 { + return max, -1 + } + + max = collection[0] + + for i := 1; i < len(collection); i++ { + item := collection[i] + + if comparison(item, max) { + max = item + index = i + } + } + + return max, index +} + // Latest search the maximum time.Time of a collection. // Returns zero value when the collection is empty. func Latest(times ...time.Time) time.Time { @@ -441,7 +547,7 @@ func Last[T any](collection []T) (T, bool) { return collection[length-1], true } -// Returns the last element of a collection or zero value if empty. +// LastOrEmpty returns the last element of a collection or zero value if empty. func LastOrEmpty[T any](collection []T) T { i, _ := Last(collection) return i @@ -473,18 +579,33 @@ func Nth[T any, N constraints.Integer](collection []T, nth N) (T, error) { return collection[l+n], nil } +// randomIntGenerator is a function that should return a random integer in the range [0, n) +// where n is the parameter passed to the randomIntGenerator. +type randomIntGenerator func(n int) int + // Sample returns a random item from collection. func Sample[T any](collection []T) T { + result := SampleBy(collection, rand.IntN) + return result +} + +// SampleBy returns a random item from collection, using randomIntGenerator as the random index generator. +func SampleBy[T any](collection []T, randomIntGenerator randomIntGenerator) T { size := len(collection) if size == 0 { return Empty[T]() } - - return collection[rand.IntN(size)] + return collection[randomIntGenerator(size)] } // Samples returns N random unique items from collection. func Samples[T any, Slice ~[]T](collection Slice, count int) Slice { + results := SamplesBy(collection, count, rand.IntN) + return results +} + +// SamplesBy returns N random unique items from collection, using randomIntGenerator as the random index generator. +func SamplesBy[T any, Slice ~[]T](collection Slice, count int, randomIntGenerator randomIntGenerator) Slice { size := len(collection) copy := append(Slice{}, collection...) @@ -494,7 +615,7 @@ func Samples[T any, Slice ~[]T](collection Slice, count int) Slice { for i := 0; i < size && i < count; i++ { copyLength := size - i - index := rand.IntN(size - i) + index := randomIntGenerator(size - i) results = append(results, copy[index]) // Removes element. diff --git a/vendor/github.com/samber/lo/internal/rand/ordered_go118.go b/vendor/github.com/samber/lo/internal/rand/ordered_go118.go index a31bb9f2a..9fbc5385a 100644 --- a/vendor/github.com/samber/lo/internal/rand/ordered_go118.go +++ b/vendor/github.com/samber/lo/internal/rand/ordered_go118.go @@ -12,3 +12,15 @@ func IntN(n int) int { // bearer:disable go_gosec_crypto_weak_random return rand.Intn(n) } + +func Int64() int64 { + // bearer:disable go_gosec_crypto_weak_random + n := rand.Int63() + + // bearer:disable go_gosec_crypto_weak_random + if rand.Intn(2) == 0 { + return -n + } + + return n +} diff --git a/vendor/github.com/samber/lo/internal/rand/ordered_go122.go b/vendor/github.com/samber/lo/internal/rand/ordered_go122.go index 532ed3393..65abf51a7 100644 --- a/vendor/github.com/samber/lo/internal/rand/ordered_go122.go +++ b/vendor/github.com/samber/lo/internal/rand/ordered_go122.go @@ -11,3 +11,7 @@ func Shuffle(n int, swap func(i, j int)) { func IntN(n int) int { return rand.IntN(n) } + +func Int64() int64 { + return rand.Int64() +} diff --git a/vendor/github.com/samber/lo/intersect.go b/vendor/github.com/samber/lo/intersect.go index 2df0e7415..720624500 100644 --- a/vendor/github.com/samber/lo/intersect.go +++ b/vendor/github.com/samber/lo/intersect.go @@ -33,7 +33,7 @@ func Every[T comparable](collection []T, subset []T) bool { return true } -// EveryBy returns true if the predicate returns true for all of the elements in the collection or if the collection is empty. +// EveryBy returns true if the predicate returns true for all elements in the collection or if the collection is empty. func EveryBy[T any](collection []T, predicate func(item T) bool) bool { for i := range collection { if !predicate(collection[i]) { @@ -167,18 +167,61 @@ func Union[T comparable, Slice ~[]T](lists ...Slice) Slice { // Without returns slice excluding all given values. func Without[T comparable, Slice ~[]T](collection Slice, exclude ...T) Slice { + excludeMap := make(map[T]struct{}, len(exclude)) + for i := range exclude { + excludeMap[exclude[i]] = struct{}{} + } + result := make(Slice, 0, len(collection)) for i := range collection { - if !Contains(exclude, collection[i]) { + if _, ok := excludeMap[collection[i]]; !ok { result = append(result, collection[i]) } } return result } -// WithoutEmpty returns slice excluding empty values. +// WithoutBy filters a slice by excluding elements whose extracted keys match any in the exclude list. +// It returns a new slice containing only the elements whose keys are not in the exclude list. +func WithoutBy[T any, K comparable](collection []T, iteratee func(item T) K, exclude ...K) []T { + excludeMap := make(map[K]struct{}, len(exclude)) + for _, e := range exclude { + excludeMap[e] = struct{}{} + } + + result := make([]T, 0, len(collection)) + for _, item := range collection { + if _, ok := excludeMap[iteratee(item)]; !ok { + result = append(result, item) + } + } + return result +} + +// WithoutEmpty returns slice excluding zero values. // // Deprecated: Use lo.Compact instead. func WithoutEmpty[T comparable, Slice ~[]T](collection Slice) Slice { return Compact(collection) } + +// WithoutNth returns slice excluding nth value. +func WithoutNth[T comparable, Slice ~[]T](collection Slice, nths ...int) Slice { + length := len(collection) + + toRemove := make(map[int]struct{}, len(nths)) + for i := range nths { + if nths[i] >= 0 && nths[i] <= length-1 { + toRemove[nths[i]] = struct{}{} + } + } + + result := make(Slice, 0, len(collection)) + for i := range collection { + if _, ok := toRemove[i]; !ok { + result = append(result, collection[i]) + } + } + + return result +} diff --git a/vendor/github.com/samber/lo/map.go b/vendor/github.com/samber/lo/map.go index d8feb434e..b1959e2cb 100644 --- a/vendor/github.com/samber/lo/map.go +++ b/vendor/github.com/samber/lo/map.go @@ -247,6 +247,36 @@ func Assign[K comparable, V any, Map ~map[K]V](maps ...Map) Map { return out } +// ChunkEntries splits a map into an array of elements in groups of a length equal to its size. If the map cannot be split evenly, +// the final chunk will contain the remaining elements. +func ChunkEntries[K comparable, V any](m map[K]V, size int) []map[K]V { + if size <= 0 { + panic("The chunk size must be greater than 0") + } + + count := len(m) + if count == 0 { + return []map[K]V{} + } + + chunksNum := count / size + if count%size != 0 { + chunksNum += 1 + } + + result := make([]map[K]V, 0, chunksNum) + + for k, v := range m { + if len(result) == 0 || len(result[len(result)-1]) == size { + result = append(result, make(map[K]V, size)) + } + + result[len(result)-1][k] = v + } + + return result +} + // MapKeys manipulates a map keys and transforms it to a map of another type. // Play: https://go.dev/play/p/9_4WPIqOetJ func MapKeys[K comparable, V any, R comparable](in map[K]V, iteratee func(value V, key K) R) map[R]V { diff --git a/vendor/github.com/samber/lo/math.go b/vendor/github.com/samber/lo/math.go index e866f88e0..5d2825ff9 100644 --- a/vendor/github.com/samber/lo/math.go +++ b/vendor/github.com/samber/lo/math.go @@ -85,22 +85,58 @@ func SumBy[T any, R constraints.Float | constraints.Integer | constraints.Comple return sum } +// Product gets the product of the values in a collection. If collection is empty 0 is returned. +// Play: https://go.dev/play/p/2_kjM_smtAH +func Product[T constraints.Float | constraints.Integer | constraints.Complex](collection []T) T { + if collection == nil { + return 0 + } + + if len(collection) == 0 { + return 0 + } + + var product T = 1 + for i := range collection { + product *= collection[i] + } + return product +} + +// ProductBy summarizes the values in a collection using the given return value from the iteration function. If collection is empty 0 is returned. +// Play: https://go.dev/play/p/wadzrWr9Aer +func ProductBy[T any, R constraints.Float | constraints.Integer | constraints.Complex](collection []T, iteratee func(item T) R) R { + if collection == nil { + return 0 + } + + if len(collection) == 0 { + return 0 + } + + var product R = 1 + for i := range collection { + product = product * iteratee(collection[i]) + } + return product +} + // Mean calculates the mean of a collection of numbers. func Mean[T constraints.Float | constraints.Integer](collection []T) T { - var length T = T(len(collection)) + var length = T(len(collection)) if length == 0 { return 0 } - var sum T = Sum(collection) + var sum = Sum(collection) return sum / length } // MeanBy calculates the mean of a collection of numbers using the given return value from the iteration function. func MeanBy[T any, R constraints.Float | constraints.Integer](collection []T, iteratee func(item T) R) R { - var length R = R(len(collection)) + var length = R(len(collection)) if length == 0 { return 0 } - var sum R = SumBy(collection, iteratee) + var sum = SumBy(collection, iteratee) return sum / length } diff --git a/vendor/github.com/samber/lo/mutable/slice.go b/vendor/github.com/samber/lo/mutable/slice.go new file mode 100644 index 000000000..6d61fa772 --- /dev/null +++ b/vendor/github.com/samber/lo/mutable/slice.go @@ -0,0 +1,23 @@ +package mutable + +import "github.com/samber/lo/internal/rand" + +// Shuffle returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm. +// Play: https://go.dev/play/p/ZTGG7OUCdnp +func Shuffle[T any, Slice ~[]T](collection Slice) { + rand.Shuffle(len(collection), func(i, j int) { + collection[i], collection[j] = collection[j], collection[i] + }) +} + +// Reverse reverses array so that the first element becomes the last, the second element becomes the second to last, and so on. +// Play: https://go.dev/play/p/iv2e9jslfBM +func Reverse[T any, Slice ~[]T](collection Slice) { + length := len(collection) + half := length / 2 + + for i := 0; i < half; i = i + 1 { + j := length - 1 - i + collection[i], collection[j] = collection[j], collection[i] + } +} diff --git a/vendor/github.com/samber/lo/retry.go b/vendor/github.com/samber/lo/retry.go index f026aa331..5b9cef3dd 100644 --- a/vendor/github.com/samber/lo/retry.go +++ b/vendor/github.com/samber/lo/retry.go @@ -104,7 +104,6 @@ func (d *debounceBy[T]) reset(key T) { for i := range d.callbacks { d.callbacks[i](key, count) } - }) } @@ -141,7 +140,8 @@ func NewDebounceBy[T comparable](duration time.Duration, f ...func(key T, count }, d.cancel } -// Attempt invokes a function N times until it returns valid output. Returning either the caught error or nil. When first argument is less than `1`, the function runs until a successful response is returned. +// Attempt invokes a function N times until it returns valid output. Returns either the caught error or nil. +// When the first argument is less than `1`, the function runs until a successful response is returned. // Play: https://go.dev/play/p/3ggJZ2ZKcMj func Attempt(maxIteration int, f func(index int) error) (int, error) { var err error @@ -158,8 +158,8 @@ func Attempt(maxIteration int, f func(index int) error) (int, error) { } // AttemptWithDelay invokes a function N times until it returns valid output, -// with a pause between each call. Returning either the caught error or nil. -// When first argument is less than `1`, the function runs until a successful +// with a pause between each call. Returns either the caught error or nil. +// When the first argument is less than `1`, the function runs until a successful // response is returned. // Play: https://go.dev/play/p/tVs6CygC7m1 func AttemptWithDelay(maxIteration int, delay time.Duration, f func(index int, duration time.Duration) error) (int, time.Duration, error) { @@ -182,9 +182,9 @@ func AttemptWithDelay(maxIteration int, delay time.Duration, f func(index int, d } // AttemptWhile invokes a function N times until it returns valid output. -// Returning either the caught error or nil, and along with a bool value to identify -// whether it needs invoke function continuously. It will terminate the invoke -// immediately if second bool value is returned with falsy value. When first +// Returns either the caught error or nil, along with a bool value to determine +// whether the function should be invoked again. It will terminate the invoke +// immediately if the second return value is false. When the first // argument is less than `1`, the function runs until a successful response is // returned. func AttemptWhile(maxIteration int, f func(int) (error, bool)) (int, error) { @@ -206,10 +206,10 @@ func AttemptWhile(maxIteration int, f func(int) (error, bool)) (int, error) { } // AttemptWhileWithDelay invokes a function N times until it returns valid output, -// with a pause between each call. Returning either the caught error or nil, and along -// with a bool value to identify whether it needs to invoke function continuously. -// It will terminate the invoke immediately if second bool value is returned with falsy -// value. When first argument is less than `1`, the function runs until a successful +// with a pause between each call. Returns either the caught error or nil, along +// with a bool value to determine whether the function should be invoked again. +// It will terminate the invoke immediately if the second return value is false. +// When the first argument is less than `1`, the function runs until a successful // response is returned. func AttemptWhileWithDelay(maxIteration int, delay time.Duration, f func(int, time.Duration) (error, bool)) (int, time.Duration, error) { var err error @@ -287,4 +287,89 @@ func (t *Transaction[T]) Process(state T) (T, error) { return state, err } -// throttle ? +// @TODO: single mutex per key ? +type throttleBy[T comparable] struct { + mu *sync.Mutex + timer *time.Timer + interval time.Duration + callbacks []func(key T) + countLimit int + count map[T]int +} + +func (th *throttleBy[T]) throttledFunc(key T) { + th.mu.Lock() + defer th.mu.Unlock() + + if _, ok := th.count[key]; !ok { + th.count[key] = 0 + } + + if th.count[key] < th.countLimit { + th.count[key]++ + + for _, f := range th.callbacks { + f(key) + } + + } + if th.timer == nil { + th.timer = time.AfterFunc(th.interval, func() { + th.reset() + }) + } +} + +func (th *throttleBy[T]) reset() { + th.mu.Lock() + defer th.mu.Unlock() + + if th.timer != nil { + th.timer.Stop() + } + + th.count = map[T]int{} + th.timer = nil +} + +// NewThrottle creates a throttled instance that invokes given functions only once in every interval. +// This returns 2 functions, First one is throttled function and Second one is a function to reset interval +func NewThrottle(interval time.Duration, f ...func()) (throttle func(), reset func()) { + return NewThrottleWithCount(interval, 1, f...) +} + +// NewThrottleWithCount is NewThrottle with count limit, throttled function will be invoked count times in every interval. +func NewThrottleWithCount(interval time.Duration, count int, f ...func()) (throttle func(), reset func()) { + callbacks := Map(f, func(item func(), _ int) func(struct{}) { + return func(struct{}) { + item() + } + }) + + throttleFn, reset := NewThrottleByWithCount[struct{}](interval, count, callbacks...) + return func() { + throttleFn(struct{}{}) + }, reset +} + +// NewThrottleBy creates a throttled instance that invokes given functions only once in every interval. +// This returns 2 functions, First one is throttled function and Second one is a function to reset interval +func NewThrottleBy[T comparable](interval time.Duration, f ...func(key T)) (throttle func(key T), reset func()) { + return NewThrottleByWithCount[T](interval, 1, f...) +} + +// NewThrottleByWithCount is NewThrottleBy with count limit, throttled function will be invoked count times in every interval. +func NewThrottleByWithCount[T comparable](interval time.Duration, count int, f ...func(key T)) (throttle func(key T), reset func()) { + if count <= 0 { + count = 1 + } + + th := &throttleBy[T]{ + mu: new(sync.Mutex), + interval: interval, + callbacks: f, + countLimit: count, + count: map[T]int{}, + } + return th.throttledFunc, th.reset +} diff --git a/vendor/github.com/samber/lo/slice.go b/vendor/github.com/samber/lo/slice.go index d2d3fd84a..e03cba042 100644 --- a/vendor/github.com/samber/lo/slice.go +++ b/vendor/github.com/samber/lo/slice.go @@ -4,7 +4,7 @@ import ( "sort" "github.com/samber/lo/internal/constraints" - "github.com/samber/lo/internal/rand" + "github.com/samber/lo/mutable" ) // Filter iterates over elements of collection, returning an array of all elements predicate returns truthy for. @@ -33,6 +33,21 @@ func Map[T any, R any](collection []T, iteratee func(item T, index int) R) []R { return result } +// UniqMap manipulates a slice and transforms it to a slice of another type with unique values. +func UniqMap[T any, R comparable](collection []T, iteratee func(item T, index int) R) []R { + result := make([]R, 0, len(collection)) + seen := make(map[R]struct{}, len(collection)) + + for i, item := range collection { + r := iteratee(item, i) + if _, ok := seen[r]; !ok { + result = append(result, r) + seen[r] = struct{}{} + } + } + return result +} + // FilterMap returns a slice which obtained after both filtering and mapping using the given callback function. // The callback function should return two values: // - the result of the mapping operation and @@ -282,33 +297,27 @@ func Interleave[T any, Slice ~[]T](collections ...Slice) Slice { } // Shuffle returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm. -// Play: https://go.dev/play/p/Qp73bnTDnc7 +// Play: https://go.dev/play/p/ZTGG7OUCdnp +// +// Deprecated: use mutable.Shuffle() instead. func Shuffle[T any, Slice ~[]T](collection Slice) Slice { - rand.Shuffle(len(collection), func(i, j int) { - collection[i], collection[j] = collection[j], collection[i] - }) - + mutable.Shuffle(collection) return collection } // Reverse reverses array so that the first element becomes the last, the second element becomes the second to last, and so on. -// Play: https://go.dev/play/p/fhUMLvZ7vS6 +// Play: https://go.dev/play/p/iv2e9jslfBM +// +// Deprecated: use mutable.Reverse() instead. func Reverse[T any, Slice ~[]T](collection Slice) Slice { - length := len(collection) - half := length / 2 - - for i := 0; i < half; i = i + 1 { - j := length - 1 - i - collection[i], collection[j] = collection[j], collection[i] - } - + mutable.Reverse(collection) return collection } // Fill fills elements of array with `initial` value. // Play: https://go.dev/play/p/VwR34GzqEub -func Fill[T Clonable[T]](collection []T, initial T) []T { - result := make([]T, 0, len(collection)) +func Fill[T Clonable[T], Slice ~[]T](collection Slice, initial T) Slice { + result := make(Slice, 0, len(collection)) for range collection { result = append(result, initial.Clone()) @@ -378,6 +387,34 @@ func SliceToMap[T any, K comparable, V any](collection []T, transform func(item return Associate(collection, transform) } +// FilterSliceToMap returns a map containing key-value pairs provided by transform function applied to elements of the given slice. +// If any of two pairs would have the same key the last one gets added to the map. +// The order of keys in returned map is not specified and is not guaranteed to be the same from the original array. +// The third return value of the transform function is a boolean that indicates whether the key-value pair should be included in the map. +func FilterSliceToMap[T any, K comparable, V any](collection []T, transform func(item T) (K, V, bool)) map[K]V { + result := make(map[K]V, len(collection)) + + for i := range collection { + k, v, ok := transform(collection[i]) + if ok { + result[k] = v + } + } + + return result +} + +// Keyify returns a map with each unique element of the slice as a key. +func Keyify[T comparable, Slice ~[]T](collection Slice) map[T]struct{} { + result := make(map[T]struct{}, len(collection)) + + for _, item := range collection { + result[item] = struct{}{} + } + + return result +} + // Drop drops n elements from the beginning of a slice or array. // Play: https://go.dev/play/p/JswS7vXRJP2 func Drop[T any, Slice ~[]T](collection Slice, n int) Slice { diff --git a/vendor/github.com/samber/lo/string.go b/vendor/github.com/samber/lo/string.go index 1d808788c..51b09899c 100644 --- a/vendor/github.com/samber/lo/string.go +++ b/vendor/github.com/samber/lo/string.go @@ -1,13 +1,13 @@ package lo import ( + "github.com/samber/lo/internal/rand" + "math" "regexp" "strings" "unicode" "unicode/utf8" - "github.com/samber/lo/internal/rand" - "golang.org/x/text/cases" "golang.org/x/text/language" ) @@ -25,6 +25,7 @@ var ( splitWordReg = regexp.MustCompile(`([a-z])([A-Z0-9])|([a-zA-Z])([0-9])|([0-9])([a-zA-Z])|([A-Z])([A-Z])([a-z])`) // bearer:disable go_lang_permissive_regex_validation splitNumberLetterReg = regexp.MustCompile(`([0-9])([a-zA-Z])`) + maximumCapacity = math.MaxInt>>1 + 1 ) // RandomString return a random string. @@ -37,12 +38,53 @@ func RandomString(size int, charset []rune) string { panic("lo.RandomString: Charset parameter must not be empty") } - b := make([]rune, size) - possibleCharactersCount := len(charset) - for i := range b { - b[i] = charset[rand.IntN(possibleCharactersCount)] + // see https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go + sb := strings.Builder{} + sb.Grow(size) + // Calculate the number of bits required to represent the charset, + // e.g., for 62 characters, it would need 6 bits (since 62 -> 64 = 2^6) + letterIdBits := int(math.Log2(float64(nearestPowerOfTwo(len(charset))))) + // Determine the corresponding bitmask, + // e.g., for 62 characters, the bitmask would be 111111. + var letterIdMask int64 = 1<= 0; { + // Regenerate the random number if all available bits have been used + if remain == 0 { + cache, remain = rand.Int64(), letterIdMax + } + // Select a character from the charset + if idx := int(cache & letterIdMask); idx < len(charset) { + sb.WriteRune(charset[idx]) + i-- + } + // Shift the bits to the right to prepare for the next character selection, + // e.g., for 62 characters, shift by 6 bits. + cache >>= letterIdBits + // Decrease the remaining number of uses for the current random number. + remain-- } - return string(b) + return sb.String() +} + +// nearestPowerOfTwo returns the nearest power of two. +func nearestPowerOfTwo(cap int) int { + n := cap - 1 + n |= n >> 1 + n |= n >> 2 + n |= n >> 4 + n |= n >> 8 + n |= n >> 16 + if n < 0 { + return 1 + } + if n >= maximumCapacity { + return maximumCapacity + } + return n + 1 } // Substring return part of a string. @@ -85,7 +127,7 @@ func ChunkString[T ~string](str T, size int) []T { return []T{str} } - var chunks []T = make([]T, 0, ((len(str)-1)/size)+1) + var chunks = make([]T, 0, ((len(str)-1)/size)+1) currentLen := 0 currentStart := 0 for i := range str { @@ -167,14 +209,23 @@ func Capitalize(str string) string { return cases.Title(language.English).String(str) } -// Elipse truncates a string to a specified length and appends an ellipsis if truncated. -func Elipse(str string, length int) string { +// Ellipsis trims and truncates a string to a specified length and appends an ellipsis if truncated. +func Ellipsis(str string, length int) string { + str = strings.TrimSpace(str) + if len(str) > length { if len(str) < 3 || length < 3 { return "..." } - return str[0:length-3] + "..." + return strings.TrimSpace(str[0:length-3]) + "..." } return str } + +// Elipse trims and truncates a string to a specified length and appends an ellipsis if truncated. +// +// Deprecated: Use Ellipsis instead. +func Elipse(str string, length int) string { + return Ellipsis(str, length) +} diff --git a/vendor/github.com/samber/lo/tuples.go b/vendor/github.com/samber/lo/tuples.go index 18a03009d..e355d0ca8 100644 --- a/vendor/github.com/samber/lo/tuples.go +++ b/vendor/github.com/samber/lo/tuples.go @@ -867,3 +867,283 @@ func UnzipBy9[In any, A any, B any, C any, D any, E any, F any, G any, H any, I return r1, r2, r3, r4, r5, r6, r7, r8, r9 } + +// CrossJoin2 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. +// It returns an empty list if a list is empty. +func CrossJoin2[A, B any](listA []A, listB []B) []Tuple2[A, B] { + return CrossJoinBy2(listA, listB, T2[A, B]) +} + +// CrossJoin3 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. +// It returns an empty list if a list is empty. +func CrossJoin3[A, B, C any](listA []A, listB []B, listC []C) []Tuple3[A, B, C] { + return CrossJoinBy3(listA, listB, listC, T3[A, B, C]) +} + +// CrossJoin4 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. +// It returns an empty list if a list is empty. +func CrossJoin4[A, B, C, D any](listA []A, listB []B, listC []C, listD []D) []Tuple4[A, B, C, D] { + return CrossJoinBy4(listA, listB, listC, listD, T4[A, B, C, D]) +} + +// CrossJoin5 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. +// It returns an empty list if a list is empty. +func CrossJoin5[A, B, C, D, E any](listA []A, listB []B, listC []C, listD []D, listE []E) []Tuple5[A, B, C, D, E] { + return CrossJoinBy5(listA, listB, listC, listD, listE, T5[A, B, C, D, E]) +} + +// CrossJoin6 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. +// It returns an empty list if a list is empty. +func CrossJoin6[A, B, C, D, E, F any](listA []A, listB []B, listC []C, listD []D, listE []E, listF []F) []Tuple6[A, B, C, D, E, F] { + return CrossJoinBy6(listA, listB, listC, listD, listE, listF, T6[A, B, C, D, E, F]) +} + +// CrossJoin7 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. +// It returns an empty list if a list is empty. +func CrossJoin7[A, B, C, D, E, F, G any](listA []A, listB []B, listC []C, listD []D, listE []E, listF []F, listG []G) []Tuple7[A, B, C, D, E, F, G] { + return CrossJoinBy7(listA, listB, listC, listD, listE, listF, listG, T7[A, B, C, D, E, F, G]) +} + +// CrossJoin8 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. +// It returns an empty list if a list is empty. +func CrossJoin8[A, B, C, D, E, F, G, H any](listA []A, listB []B, listC []C, listD []D, listE []E, listF []F, listG []G, listH []H) []Tuple8[A, B, C, D, E, F, G, H] { + return CrossJoinBy8(listA, listB, listC, listD, listE, listF, listG, listH, T8[A, B, C, D, E, F, G, H]) +} + +// CrossJoin9 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. +// It returns an empty list if a list is empty. +func CrossJoin9[A, B, C, D, E, F, G, H, I any](listA []A, listB []B, listC []C, listD []D, listE []E, listF []F, listG []G, listH []H, listI []I) []Tuple9[A, B, C, D, E, F, G, H, I] { + return CrossJoinBy9(listA, listB, listC, listD, listE, listF, listG, listH, listI, T9[A, B, C, D, E, F, G, H, I]) +} + +// CrossJoinBy2 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. The project function +// is used to create the output values. +// It returns an empty list if a list is empty. +func CrossJoinBy2[A, B, Out any](listA []A, listB []B, project func(a A, b B) Out) []Out { + size := len(listA) * len(listB) + if size == 0 { + return []Out{} + } + + result := make([]Out, 0, size) + + for _, a := range listA { + for _, b := range listB { + result = append(result, project(a, b)) + } + } + + return result +} + +// CrossJoinBy3 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. The project function +// is used to create the output values. +// It returns an empty list if a list is empty. +func CrossJoinBy3[A, B, C, Out any](listA []A, listB []B, listC []C, project func(a A, b B, c C) Out) []Out { + size := len(listA) * len(listB) * len(listC) + if size == 0 { + return []Out{} + } + + result := make([]Out, 0, size) + + for _, a := range listA { + for _, b := range listB { + for _, c := range listC { + result = append(result, project(a, b, c)) + } + } + } + + return result +} + +// CrossJoinBy4 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. The project function +// is used to create the output values. +// It returns an empty list if a list is empty. +func CrossJoinBy4[A, B, C, D, Out any](listA []A, listB []B, listC []C, listD []D, project func(a A, b B, c C, d D) Out) []Out { + size := len(listA) * len(listB) * len(listC) * len(listD) + if size == 0 { + return []Out{} + } + + result := make([]Out, 0, size) + + for _, a := range listA { + for _, b := range listB { + for _, c := range listC { + for _, d := range listD { + result = append(result, project(a, b, c, d)) + } + } + } + } + + return result +} + +// CrossJoinBy5 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. The project function +// is used to create the output values. +// It returns an empty list if a list is empty. +func CrossJoinBy5[A, B, C, D, E, Out any](listA []A, listB []B, listC []C, listD []D, listE []E, project func(a A, b B, c C, d D, e E) Out) []Out { + size := len(listA) * len(listB) * len(listC) * len(listD) * len(listE) + if size == 0 { + return []Out{} + } + + result := make([]Out, 0, size) + + for _, a := range listA { + for _, b := range listB { + for _, c := range listC { + for _, d := range listD { + for _, e := range listE { + result = append(result, project(a, b, c, d, e)) + } + } + } + } + } + + return result +} + +// CrossJoinBy6 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. The project function +// is used to create the output values. +// It returns an empty list if a list is empty. +func CrossJoinBy6[A, B, C, D, E, F, Out any](listA []A, listB []B, listC []C, listD []D, listE []E, listF []F, project func(a A, b B, c C, d D, e E, f F) Out) []Out { + size := len(listA) * len(listB) * len(listC) * len(listD) * len(listE) * len(listF) + if size == 0 { + return []Out{} + } + + result := make([]Out, 0, size) + + for _, a := range listA { + for _, b := range listB { + for _, c := range listC { + for _, d := range listD { + for _, e := range listE { + for _, f := range listF { + result = append(result, project(a, b, c, d, e, f)) + } + } + } + } + } + } + + return result +} + +// CrossJoinBy7 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. The project function +// is used to create the output values. +// It returns an empty list if a list is empty. +func CrossJoinBy7[A, B, C, D, E, F, G, Out any](listA []A, listB []B, listC []C, listD []D, listE []E, listF []F, listG []G, project func(a A, b B, c C, d D, e E, f F, g G) Out) []Out { + size := len(listA) * len(listB) * len(listC) * len(listD) * len(listE) * len(listF) * len(listG) + if size == 0 { + return []Out{} + } + + result := make([]Out, 0, size) + + for _, a := range listA { + for _, b := range listB { + for _, c := range listC { + for _, d := range listD { + for _, e := range listE { + for _, f := range listF { + for _, g := range listG { + result = append(result, project(a, b, c, d, e, f, g)) + } + } + } + } + } + } + } + + return result +} + +// CrossJoinBy8 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. The project function +// is used to create the output values. +// It returns an empty list if a list is empty. +func CrossJoinBy8[A, B, C, D, E, F, G, H, Out any](listA []A, listB []B, listC []C, listD []D, listE []E, listF []F, listG []G, listH []H, project func(a A, b B, c C, d D, e E, f F, g G, h H) Out) []Out { + size := len(listA) * len(listB) * len(listC) * len(listD) * len(listE) * len(listF) * len(listG) * len(listH) + if size == 0 { + return []Out{} + } + + result := make([]Out, 0, size) + + for _, a := range listA { + for _, b := range listB { + for _, c := range listC { + for _, d := range listD { + for _, e := range listE { + for _, f := range listF { + for _, g := range listG { + for _, h := range listH { + result = append(result, project(a, b, c, d, e, f, g, h)) + } + } + } + } + } + } + } + } + + return result +} + +// CrossJoinBy9 combines every items from one list with every items from others. +// It is the cartesian product of lists received as arguments. The project function +// is used to create the output values. +// It returns an empty list if a list is empty. +func CrossJoinBy9[A, B, C, D, E, F, G, H, I, Out any](listA []A, listB []B, listC []C, listD []D, listE []E, listF []F, listG []G, listH []H, listI []I, project func(a A, b B, c C, d D, e E, f F, g G, h H, i I) Out) []Out { + size := len(listA) * len(listB) * len(listC) * len(listD) * len(listE) * len(listF) * len(listG) * len(listH) * len(listI) + if size == 0 { + return []Out{} + } + + result := make([]Out, 0, size) + + for _, a := range listA { + for _, b := range listB { + for _, c := range listC { + for _, d := range listD { + for _, e := range listE { + for _, f := range listF { + for _, g := range listG { + for _, h := range listH { + for _, i := range listI { + result = append(result, project(a, b, c, d, e, f, g, h, i)) + } + } + } + } + } + } + } + } + } + + return result +} diff --git a/vendor/github.com/samber/lo/type_manipulation.go b/vendor/github.com/samber/lo/type_manipulation.go index ef070281a..bcf990cd6 100644 --- a/vendor/github.com/samber/lo/type_manipulation.go +++ b/vendor/github.com/samber/lo/type_manipulation.go @@ -8,6 +8,11 @@ func IsNil(x any) bool { return x == nil || reflect.ValueOf(x).IsNil() } +// IsNotNil checks if a value is not nil or if it's not a reference type with a nil underlying value. +func IsNotNil(x any) bool { + return !IsNil(x) +} + // ToPtr returns a pointer copy of value. func ToPtr[T any](x T) *T { return &x @@ -69,7 +74,8 @@ func FromSlicePtr[T any](collection []*T) []T { }) } -// FromSlicePtr returns a slice with the pointer values or the fallback value. +// FromSlicePtrOr returns a slice with the pointer values or the fallback value. +// Play: https://go.dev/play/p/lbunFvzlUDX func FromSlicePtrOr[T any](collection []*T, fallback T) []T { return Map(collection, func(x *T, _ int) T { if x == nil { @@ -105,7 +111,7 @@ func FromAnySlice[T any](in []any) (out []T, ok bool) { return result, true } -// Empty returns an empty value. +// Empty returns the zero value (https://go.dev/ref/spec#The_zero_value). func Empty[T any]() T { var zero T return zero @@ -141,3 +147,43 @@ func CoalesceOrEmpty[T comparable](v ...T) T { result, _ := Coalesce(v...) return result } + +// CoalesceSlice returns the first non-zero slice. +func CoalesceSlice[T any](v ...[]T) ([]T, bool) { + for i := range v { + if v[i] != nil && len(v[i]) > 0 { + return v[i], true + } + } + return []T{}, false +} + +// CoalesceSliceOrEmpty returns the first non-zero slice. +func CoalesceSliceOrEmpty[T any](v ...[]T) []T { + for i := range v { + if v[i] != nil && len(v[i]) > 0 { + return v[i] + } + } + return []T{} +} + +// CoalesceMap returns the first non-zero map. +func CoalesceMap[K comparable, V any](v ...map[K]V) (map[K]V, bool) { + for i := range v { + if v[i] != nil && len(v[i]) > 0 { + return v[i], true + } + } + return map[K]V{}, false +} + +// CoalesceMapOrEmpty returns the first non-zero map. +func CoalesceMapOrEmpty[K comparable, V any](v ...map[K]V) map[K]V { + for i := range v { + if v[i] != nil && len(v[i]) > 0 { + return v[i] + } + } + return map[K]V{} +} diff --git a/vendor/golang.org/x/xerrors/LICENSE b/vendor/golang.org/x/xerrors/LICENSE index e4a47e17f..c3c8b7d2b 100644 --- a/vendor/golang.org/x/xerrors/LICENSE +++ b/vendor/golang.org/x/xerrors/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019 The Go Authors. All rights reserved. +Copyright 2019 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go index 24bc98ac4..d972a3d98 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go @@ -185,7 +185,7 @@ func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) erro } else if xtErr != nil && xtErr != protoregistry.NotFound { return d.newError(tok.Pos(), "unable to resolve [%s]: %v", tok.RawString(), xtErr) } - if flags.ProtoLegacy { + if flags.ProtoLegacyWeak { if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() { fd = nil // reset since the weak reference is not linked in } diff --git a/vendor/google.golang.org/protobuf/internal/flags/flags.go b/vendor/google.golang.org/protobuf/internal/flags/flags.go index 58372dd34..5cb3ee70f 100644 --- a/vendor/google.golang.org/protobuf/internal/flags/flags.go +++ b/vendor/google.golang.org/protobuf/internal/flags/flags.go @@ -22,3 +22,8 @@ const ProtoLegacy = protoLegacy // extension fields at unmarshal time, but defers creating the message // structure until the extension is first accessed. const LazyUnmarshalExtensions = ProtoLegacy + +// ProtoLegacyWeak specifies whether to enable support for weak fields. +// This flag was split out of ProtoLegacy in preparation for removing +// support for weak fields (independent of the other protolegacy features). +const ProtoLegacyWeak = ProtoLegacy diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go index fb35f0bae..229c69801 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go @@ -94,7 +94,7 @@ func sizeMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalO return 0 } n := 0 - iter := mapRange(mapv) + iter := mapv.MapRange() for iter.Next() { key := mapi.conv.keyConv.PBValueOf(iter.Key()).MapKey() keySize := mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts) @@ -281,7 +281,7 @@ func appendMap(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, o if opts.Deterministic() { return appendMapDeterministic(b, mapv, mapi, f, opts) } - iter := mapRange(mapv) + iter := mapv.MapRange() for iter.Next() { var err error b = protowire.AppendVarint(b, f.wiretag) @@ -328,7 +328,7 @@ func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error { if !mi.needsInitCheck { return nil } - iter := mapRange(mapv) + iter := mapv.MapRange() for iter.Next() { val := pointerOfValue(iter.Value()) if err := mi.checkInitializedPointer(val); err != nil { @@ -336,7 +336,7 @@ func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error { } } } else { - iter := mapRange(mapv) + iter := mapv.MapRange() for iter.Next() { val := mapi.conv.valConv.PBValueOf(iter.Value()) if err := mapi.valFuncs.isInit(val); err != nil { @@ -356,7 +356,7 @@ func mergeMap(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { if dstm.IsNil() { dstm.Set(reflect.MakeMap(f.ft)) } - iter := mapRange(srcm) + iter := srcm.MapRange() for iter.Next() { dstm.SetMapIndex(iter.Key(), iter.Value()) } @@ -371,7 +371,7 @@ func mergeMapOfBytes(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { if dstm.IsNil() { dstm.Set(reflect.MakeMap(f.ft)) } - iter := mapRange(srcm) + iter := srcm.MapRange() for iter.Next() { dstm.SetMapIndex(iter.Key(), reflect.ValueOf(append(emptyBuf[:], iter.Value().Bytes()...))) } @@ -386,7 +386,7 @@ func mergeMapOfMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { if dstm.IsNil() { dstm.Set(reflect.MakeMap(f.ft)) } - iter := mapRange(srcm) + iter := srcm.MapRange() for iter.Next() { val := reflect.New(f.ft.Elem().Elem()) if f.mi != nil { diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go deleted file mode 100644 index 4b15493f2..000000000 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.12 -// +build !go1.12 - -package impl - -import "reflect" - -type mapIter struct { - v reflect.Value - keys []reflect.Value -} - -// mapRange provides a less-efficient equivalent to -// the Go 1.12 reflect.Value.MapRange method. -func mapRange(v reflect.Value) *mapIter { - return &mapIter{v: v} -} - -func (i *mapIter) Next() bool { - if i.keys == nil { - i.keys = i.v.MapKeys() - } else { - i.keys = i.keys[1:] - } - return len(i.keys) > 0 -} - -func (i *mapIter) Key() reflect.Value { - return i.keys[0] -} - -func (i *mapIter) Value() reflect.Value { - return i.v.MapIndex(i.keys[0]) -} diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go deleted file mode 100644 index 0b31b66ea..000000000 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.12 -// +build go1.12 - -package impl - -import "reflect" - -func mapRange(v reflect.Value) *reflect.MapIter { return v.MapRange() } diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_message.go b/vendor/google.golang.org/protobuf/internal/impl/codec_message.go index 2f7b363ec..111d95833 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_message.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_message.go @@ -118,12 +118,12 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { }, } case isOneof: - fieldOffset = offsetOf(fs, mi.Exporter) + fieldOffset = offsetOf(fs) case fd.IsWeak(): fieldOffset = si.weakOffset funcs = makeWeakMessageFieldCoder(fd) default: - fieldOffset = offsetOf(fs, mi.Exporter) + fieldOffset = offsetOf(fs) childMessage, funcs = fieldCoder(fd, ft) } cf := &preallocFields[i] diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go b/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go index 88c16ae5b..f81d7d0db 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go @@ -45,19 +45,19 @@ func (mi *MessageInfo) makeOpaqueCoderMethods(t reflect.Type, si opaqueStructInf var childMessage *MessageInfo switch { case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): - fieldOffset = offsetOf(fs, mi.Exporter) + fieldOffset = offsetOf(fs) case fd.IsWeak(): fieldOffset = si.weakOffset funcs = makeWeakMessageFieldCoder(fd) case fd.Message() != nil && !fd.IsMap(): - fieldOffset = offsetOf(fs, mi.Exporter) + fieldOffset = offsetOf(fs) if fd.IsList() { childMessage, funcs = makeOpaqueRepeatedMessageFieldCoder(fd, ft) } else { childMessage, funcs = makeOpaqueMessageFieldCoder(fd, ft) } default: - fieldOffset = offsetOf(fs, mi.Exporter) + fieldOffset = offsetOf(fs) childMessage, funcs = fieldCoder(fd, ft) } cf := &coderFieldInfo{ diff --git a/vendor/google.golang.org/protobuf/internal/impl/convert_map.go b/vendor/google.golang.org/protobuf/internal/impl/convert_map.go index 304244a65..e4580b3ac 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/convert_map.go +++ b/vendor/google.golang.org/protobuf/internal/impl/convert_map.go @@ -101,7 +101,7 @@ func (ms *mapReflect) Mutable(k protoreflect.MapKey) protoreflect.Value { return v } func (ms *mapReflect) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { - iter := mapRange(ms.v) + iter := ms.v.MapRange() for iter.Next() { k := ms.keyConv.PBValueOf(iter.Key()).MapKey() v := ms.valConv.PBValueOf(iter.Value()) diff --git a/vendor/google.golang.org/protobuf/internal/impl/message.go b/vendor/google.golang.org/protobuf/internal/impl/message.go index fa10a0f5c..d1f79b422 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message.go @@ -165,28 +165,28 @@ fieldLoop: switch f := t.Field(i); f.Name { case genid.SizeCache_goname, genid.SizeCacheA_goname: if f.Type == sizecacheType { - si.sizecacheOffset = offsetOf(f, mi.Exporter) + si.sizecacheOffset = offsetOf(f) si.sizecacheType = f.Type } case genid.WeakFields_goname, genid.WeakFieldsA_goname: if f.Type == weakFieldsType { - si.weakOffset = offsetOf(f, mi.Exporter) + si.weakOffset = offsetOf(f) si.weakType = f.Type } case genid.UnknownFields_goname, genid.UnknownFieldsA_goname: if f.Type == unknownFieldsAType || f.Type == unknownFieldsBType { - si.unknownOffset = offsetOf(f, mi.Exporter) + si.unknownOffset = offsetOf(f) si.unknownType = f.Type } case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname: if f.Type == extensionFieldsType { - si.extensionOffset = offsetOf(f, mi.Exporter) + si.extensionOffset = offsetOf(f) si.extensionType = f.Type } case "lazyFields", "XXX_lazyUnmarshalInfo": - si.lazyOffset = offsetOf(f, mi.Exporter) + si.lazyOffset = offsetOf(f) case "XXX_presence": - si.presenceOffset = offsetOf(f, mi.Exporter) + si.presenceOffset = offsetOf(f) default: for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") { if len(s) > 0 && strings.Trim(s, "0123456789") == "" { diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go b/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go index d407dd791..d8dcd7886 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go @@ -88,9 +88,7 @@ func opaqueInitHook(mi *MessageInfo) bool { mi.oneofs = map[protoreflect.Name]*oneofInfo{} for i := 0; i < mi.Desc.Oneofs().Len(); i++ { od := mi.Desc.Oneofs().Get(i) - if !od.IsSynthetic() { - mi.oneofs[od.Name()] = makeOneofInfo(od, si.structInfo, mi.Exporter) - } + mi.oneofs[od.Name()] = makeOneofInfoOpaque(mi, od, si.structInfo, mi.Exporter) } mi.denseFields = make([]*fieldInfo, fds.Len()*2) @@ -119,12 +117,32 @@ func opaqueInitHook(mi *MessageInfo) bool { return true } +func makeOneofInfoOpaque(mi *MessageInfo, od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo { + oi := &oneofInfo{oneofDesc: od} + if od.IsSynthetic() { + fd := od.Fields().Get(0) + index, _ := presenceIndex(mi.Desc, fd) + oi.which = func(p pointer) protoreflect.FieldNumber { + if p.IsNil() { + return 0 + } + if !mi.present(p, index) { + return 0 + } + return od.Fields().Get(0).Number() + } + return oi + } + // Dispatch to non-opaque oneof implementation for non-synthetic oneofs. + return makeOneofInfo(od, si, x) +} + func (mi *MessageInfo) fieldInfoForMapOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { ft := fs.Type if ft.Kind() != reflect.Map { panic(fmt.Sprintf("invalid type: got %v, want map kind", ft)) } - fieldOffset := offsetOf(fs, mi.Exporter) + fieldOffset := offsetOf(fs) conv := NewConverter(ft, fd) return fieldInfo{ fieldDesc: fd, @@ -178,7 +196,7 @@ func (mi *MessageInfo) fieldInfoForScalarListOpaque(si opaqueStructInfo, fd prot panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft)) } conv := NewConverter(reflect.PtrTo(ft), fd) - fieldOffset := offsetOf(fs, mi.Exporter) + fieldOffset := offsetOf(fs) index, _ := presenceIndex(mi.Desc, fd) return fieldInfo{ fieldDesc: fd, @@ -228,7 +246,7 @@ func (mi *MessageInfo) fieldInfoForMessageListOpaque(si opaqueStructInfo, fd pro panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft)) } conv := NewConverter(ft, fd) - fieldOffset := offsetOf(fs, mi.Exporter) + fieldOffset := offsetOf(fs) index, _ := presenceIndex(mi.Desc, fd) fieldNumber := fd.Number() return fieldInfo{ @@ -321,7 +339,7 @@ func (mi *MessageInfo) fieldInfoForMessageListOpaqueNoPresence(si opaqueStructIn panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft)) } conv := NewConverter(ft, fd) - fieldOffset := offsetOf(fs, mi.Exporter) + fieldOffset := offsetOf(fs) return fieldInfo{ fieldDesc: fd, has: func(p pointer) bool { @@ -393,7 +411,7 @@ func (mi *MessageInfo) fieldInfoForScalarOpaque(si opaqueStructInfo, fd protoref deref = true } conv := NewConverter(ft, fd) - fieldOffset := offsetOf(fs, mi.Exporter) + fieldOffset := offsetOf(fs) index, _ := presenceIndex(mi.Desc, fd) var getter func(p pointer) protoreflect.Value if !nullable { @@ -462,7 +480,7 @@ func (mi *MessageInfo) fieldInfoForScalarOpaque(si opaqueStructInfo, fd protoref func (mi *MessageInfo) fieldInfoForMessageOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { ft := fs.Type conv := NewConverter(ft, fd) - fieldOffset := offsetOf(fs, mi.Exporter) + fieldOffset := offsetOf(fs) index, _ := presenceIndex(mi.Desc, fd) fieldNumber := fd.Number() elemType := fs.Type.Elem() diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go index a74064620..3cd1fbc21 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go @@ -76,7 +76,7 @@ func fieldInfoForOneof(fd protoreflect.FieldDescriptor, fs reflect.StructField, isMessage := fd.Message() != nil // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) return fieldInfo{ // NOTE: The logic below intentionally assumes that oneof fields are // well-formatted. That is, the oneof interface never contains a @@ -152,7 +152,7 @@ func fieldInfoForMap(fd protoreflect.FieldDescriptor, fs reflect.StructField, x conv := NewConverter(ft, fd) // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) return fieldInfo{ fieldDesc: fd, has: func(p pointer) bool { @@ -205,7 +205,7 @@ func fieldInfoForList(fd protoreflect.FieldDescriptor, fs reflect.StructField, x conv := NewConverter(reflect.PtrTo(ft), fd) // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) return fieldInfo{ fieldDesc: fd, has: func(p pointer) bool { @@ -269,7 +269,7 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, } } conv := NewConverter(ft, fd) - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) // Generate specialized getter functions to avoid going through reflect.Value if nullable { @@ -333,7 +333,7 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, } func fieldInfoForWeakMessage(fd protoreflect.FieldDescriptor, weakOffset offset) fieldInfo { - if !flags.ProtoLegacy { + if !flags.ProtoLegacyWeak { panic("no support for proto1 weak fields") } @@ -410,7 +410,7 @@ func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField conv := NewConverter(ft, fd) // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) return fieldInfo{ fieldDesc: fd, has: func(p pointer) bool { @@ -419,7 +419,7 @@ func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField } rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() if fs.Type.Kind() != reflect.Ptr { - return !isZero(rv) + return !rv.IsZero() } return !rv.IsNil() }, @@ -466,7 +466,7 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) * oi := &oneofInfo{oneofDesc: od} if od.IsSynthetic() { fs := si.fieldsByNumber[od.Fields().Get(0).Number()] - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) oi.which = func(p pointer) protoreflect.FieldNumber { if p.IsNil() { return 0 @@ -479,7 +479,7 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) * } } else { fs := si.oneofsByName[od.Name()] - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) oi.which = func(p pointer) protoreflect.FieldNumber { if p.IsNil() { return 0 @@ -497,41 +497,3 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) * } return oi } - -// isZero is identical to reflect.Value.IsZero. -// TODO: Remove this when Go1.13 is the minimally supported Go version. -func isZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return math.Float64bits(v.Float()) == 0 - case reflect.Complex64, reflect.Complex128: - c := v.Complex() - return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0 - case reflect.Array: - for i := 0; i < v.Len(); i++ { - if !isZero(v.Index(i)) { - return false - } - } - return true - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: - return v.IsNil() - case reflect.String: - return v.Len() == 0 - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - if !isZero(v.Field(i)) { - return false - } - } - return true - default: - panic(&reflect.ValueError{Method: "reflect.Value.IsZero", Kind: v.Kind()}) - } -} diff --git a/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go b/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go index 041ebde2d..6bed45e35 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go +++ b/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go @@ -22,7 +22,7 @@ type Pointer unsafe.Pointer type offset uintptr // offsetOf returns a field offset for the struct field. -func offsetOf(f reflect.StructField, x exporter) offset { +func offsetOf(f reflect.StructField) offset { return offset(f.Offset) } diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index 3018450df..4a39af0c6 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -52,7 +52,7 @@ import ( const ( Major = 1 Minor = 36 - Patch = 1 + Patch = 4 PreRelease = "" ) diff --git a/vendor/google.golang.org/protobuf/proto/decode.go b/vendor/google.golang.org/protobuf/proto/decode.go index a3b5e142d..e28d7acb3 100644 --- a/vendor/google.golang.org/protobuf/proto/decode.go +++ b/vendor/google.golang.org/protobuf/proto/decode.go @@ -172,7 +172,7 @@ func (o UnmarshalOptions) unmarshalMessageSlow(b []byte, m protoreflect.Message) var err error if fd == nil { err = errUnknown - } else if flags.ProtoLegacy { + } else if flags.ProtoLegacyWeak { if fd.IsWeak() && fd.Message().IsPlaceholder() { err = errUnknown // weak referent is not linked in } diff --git a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go index 9550109aa..00ac835c0 100644 --- a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go @@ -78,6 +78,7 @@ import ( reflect "reflect" sync "sync" time "time" + unsafe "unsafe" ) // A Timestamp represents a point in time independent of any time zone or local @@ -297,7 +298,7 @@ func (x *Timestamp) GetNanos() int32 { var File_google_protobuf_timestamp_proto protoreflect.FileDescriptor -var file_google_protobuf_timestamp_proto_rawDesc = []byte{ +var file_google_protobuf_timestamp_proto_rawDesc = string([]byte{ 0x0a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, @@ -314,16 +315,16 @@ var file_google_protobuf_timestamp_proto_rawDesc = []byte{ 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +}) var ( file_google_protobuf_timestamp_proto_rawDescOnce sync.Once - file_google_protobuf_timestamp_proto_rawDescData = file_google_protobuf_timestamp_proto_rawDesc + file_google_protobuf_timestamp_proto_rawDescData []byte ) func file_google_protobuf_timestamp_proto_rawDescGZIP() []byte { file_google_protobuf_timestamp_proto_rawDescOnce.Do(func() { - file_google_protobuf_timestamp_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_timestamp_proto_rawDescData) + file_google_protobuf_timestamp_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_timestamp_proto_rawDesc), len(file_google_protobuf_timestamp_proto_rawDesc))) }) return file_google_protobuf_timestamp_proto_rawDescData } @@ -349,7 +350,7 @@ func file_google_protobuf_timestamp_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_google_protobuf_timestamp_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_timestamp_proto_rawDesc), len(file_google_protobuf_timestamp_proto_rawDesc)), NumEnums: 0, NumMessages: 1, NumExtensions: 0, @@ -360,7 +361,6 @@ func file_google_protobuf_timestamp_proto_init() { MessageInfos: file_google_protobuf_timestamp_proto_msgTypes, }.Build() File_google_protobuf_timestamp_proto = out.File - file_google_protobuf_timestamp_proto_rawDesc = nil file_google_protobuf_timestamp_proto_goTypes = nil file_google_protobuf_timestamp_proto_depIdxs = nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index d680a6ab0..ac7e4c805 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -11,8 +11,8 @@ github.com/alicebob/miniredis/v2/metro github.com/alicebob/miniredis/v2/proto github.com/alicebob/miniredis/v2/server github.com/alicebob/miniredis/v2/size -# github.com/aquasecurity/trivy v0.58.2 -## explicit; go 1.22.9 +# github.com/aquasecurity/trivy v0.59.0 +## explicit; go 1.23.4 github.com/aquasecurity/trivy/pkg/digest github.com/aquasecurity/trivy/pkg/fanal/types github.com/aquasecurity/trivy/pkg/module/serialize @@ -65,8 +65,8 @@ github.com/golang-migrate/migrate/v4/database/postgres github.com/golang-migrate/migrate/v4/internal/url github.com/golang-migrate/migrate/v4/source github.com/golang-migrate/migrate/v4/source/go_bindata -# github.com/google/go-containerregistry v0.20.2 -## explicit; go 1.18 +# github.com/google/go-containerregistry v0.20.3 +## explicit; go 1.23.0 github.com/google/go-containerregistry/pkg/v1 github.com/google/go-containerregistry/pkg/v1/types # github.com/gophercloud/gophercloud/v2 v2.4.0 @@ -171,11 +171,12 @@ github.com/redis/go-redis/v9/internal/util ## explicit; go 1.13 github.com/rs/cors github.com/rs/cors/internal -# github.com/samber/lo v1.47.0 +# github.com/samber/lo v1.49.0 ## explicit; go 1.18 github.com/samber/lo github.com/samber/lo/internal/constraints github.com/samber/lo/internal/rand +github.com/samber/lo/mutable # github.com/sapcc/go-api-declarations v1.13.2 ## explicit; go 1.21 github.com/sapcc/go-api-declarations/bininfo @@ -246,11 +247,11 @@ golang.org/x/text/internal/tag golang.org/x/text/language golang.org/x/text/transform golang.org/x/text/unicode/norm -# golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 +# golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 ## explicit; go 1.18 golang.org/x/xerrors golang.org/x/xerrors/internal -# google.golang.org/protobuf v1.36.1 +# google.golang.org/protobuf v1.36.4 ## explicit; go 1.21 google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/prototext