fix(deps): update module github.com/prometheus/alertmanager to v0.29.0 (main) (#19797)
Signed-off-by: renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com> Co-authored-by: renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
parent
abaeff7fad
commit
5ec7ddca47
@@ -85,7 +85,7 @@ require (
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
github.com/prometheus/client_model v0.6.2
|
||||
github.com/prometheus/common v0.66.1
|
||||
github.com/prometheus/common v0.67.1
|
||||
github.com/prometheus/prometheus v0.305.1-0.20250806170547-208187eaa19b
|
||||
github.com/redis/go-redis/v9 v9.10.0
|
||||
github.com/segmentio/fasthash v1.0.3
|
||||
@@ -142,7 +142,7 @@ require (
|
||||
github.com/oklog/ulid/v2 v2.1.1
|
||||
github.com/parquet-go/parquet-go v0.25.1
|
||||
github.com/pressly/goose/v3 v3.26.0
|
||||
github.com/prometheus/alertmanager v0.28.1
|
||||
github.com/prometheus/alertmanager v0.29.0
|
||||
github.com/prometheus/common/sigv4 v0.1.0
|
||||
github.com/prometheus/otlptranslator v0.0.2
|
||||
github.com/prometheus/sigv4 v0.2.1
|
||||
@@ -209,6 +209,17 @@ require (
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/swag/cmdutils v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/conv v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/fileutils v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/jsonname v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/jsonutils v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/loading v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/mangling v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/netutils v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/stringutils v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/typeutils v0.25.1 // indirect
|
||||
github.com/go-openapi/swag/yamlutils v0.25.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
@@ -268,7 +279,7 @@ require (
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zeebo/errs v1.4.0 // indirect
|
||||
github.com/zeebo/xxh3 v1.0.2 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/collector/component v1.35.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap v1.35.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.129.0 // indirect
|
||||
@@ -300,10 +311,10 @@ require (
|
||||
go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.6.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated // indirect
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
modernc.org/libc v1.66.3 // indirect
|
||||
@@ -352,7 +363,7 @@ require (
|
||||
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.6.0 // indirect
|
||||
github.com/dennwc/varint v1.0.0 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
@@ -372,15 +383,15 @@ require (
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
github.com/go-openapi/errors v0.22.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/loads v0.22.0 // indirect
|
||||
github.com/go-openapi/spec v0.21.0 // indirect
|
||||
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/go-openapi/analysis v0.24.0 // indirect
|
||||
github.com/go-openapi/errors v0.22.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.22.1 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.2 // indirect
|
||||
github.com/go-openapi/loads v0.23.1 // indirect
|
||||
github.com/go-openapi/spec v0.22.0 // indirect
|
||||
github.com/go-openapi/strfmt v0.24.0 // indirect
|
||||
github.com/go-openapi/swag v0.25.1 // indirect
|
||||
github.com/go-openapi/validate v0.25.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.26.0 // indirect
|
||||
@@ -414,14 +425,12 @@ require (
|
||||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/leodido/ragel-machinery v0.0.0-20190525184631-5f46317e436b // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/miekg/dns v1.1.68 // indirect
|
||||
@@ -437,7 +446,7 @@ require (
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/exporter-toolkit v0.14.0 // indirect
|
||||
github.com/prometheus/exporter-toolkit v0.14.1 // indirect
|
||||
github.com/prometheus/procfs v0.17.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
@@ -455,7 +464,7 @@ require (
|
||||
go.etcd.io/etcd/api/v3 v3.5.4 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.4 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.2 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.4 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.128.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0
|
||||
@@ -465,9 +474,9 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.38.0
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/mod v0.28.0 // indirect
|
||||
golang.org/x/mod v0.29.0 // indirect
|
||||
golang.org/x/term v0.36.0 // indirect
|
||||
golang.org/x/tools v0.37.0 // indirect
|
||||
golang.org/x/tools v0.38.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda
|
||||
|
||||
@@ -323,8 +323,8 @@ github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03V
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=
|
||||
github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
@@ -455,24 +455,48 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
|
||||
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
|
||||
github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
|
||||
github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||
github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=
|
||||
github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=
|
||||
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
|
||||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||
github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
|
||||
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
|
||||
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
|
||||
github.com/go-openapi/analysis v0.24.0 h1:vE/VFFkICKyYuTWYnplQ+aVr45vlG6NcZKC7BdIXhsA=
|
||||
github.com/go-openapi/analysis v0.24.0/go.mod h1:GLyoJA+bvmGGaHgpfeDh8ldpGo69fAJg7eeMDMRCIrw=
|
||||
github.com/go-openapi/errors v0.22.3 h1:k6Hxa5Jg1TUyZnOwV2Lh81j8ayNw5VVYLvKrp4zFKFs=
|
||||
github.com/go-openapi/errors v0.22.3/go.mod h1:+WvbaBBULWCOna//9B9TbLNGSFOfF8lY9dw4hGiEiKQ=
|
||||
github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk=
|
||||
github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM=
|
||||
github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU=
|
||||
github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ=
|
||||
github.com/go-openapi/loads v0.23.1 h1:H8A0dX2KDHxDzc797h0+uiCZ5kwE2+VojaQVaTlXvS0=
|
||||
github.com/go-openapi/loads v0.23.1/go.mod h1:hZSXkyACCWzWPQqizAv/Ye0yhi2zzHwMmoXQ6YQml44=
|
||||
github.com/go-openapi/spec v0.22.0 h1:xT/EsX4frL3U09QviRIZXvkh80yibxQmtoEvyqug0Tw=
|
||||
github.com/go-openapi/spec v0.22.0/go.mod h1:K0FhKxkez8YNS94XzF8YKEMULbFrRw4m15i2YUht4L0=
|
||||
github.com/go-openapi/strfmt v0.24.0 h1:dDsopqbI3wrrlIzeXRbqMihRNnjzGC+ez4NQaAAJLuc=
|
||||
github.com/go-openapi/strfmt v0.24.0/go.mod h1:Lnn1Bk9rZjXxU9VMADbEEOo7D7CDyKGLsSKekhFr7s4=
|
||||
github.com/go-openapi/swag v0.25.1 h1:6uwVsx+/OuvFVPqfQmOOPsqTcm5/GkBhNwLqIR916n8=
|
||||
github.com/go-openapi/swag v0.25.1/go.mod h1:bzONdGlT0fkStgGPd3bhZf1MnuPkf2YAys6h+jZipOo=
|
||||
github.com/go-openapi/swag/cmdutils v0.25.1 h1:nDke3nAFDArAa631aitksFGj2omusks88GF1VwdYqPY=
|
||||
github.com/go-openapi/swag/cmdutils v0.25.1/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
|
||||
github.com/go-openapi/swag/conv v0.25.1 h1:+9o8YUg6QuqqBM5X6rYL/p1dpWeZRhoIt9x7CCP+he0=
|
||||
github.com/go-openapi/swag/conv v0.25.1/go.mod h1:Z1mFEGPfyIKPu0806khI3zF+/EUXde+fdeksUl2NiDs=
|
||||
github.com/go-openapi/swag/fileutils v0.25.1 h1:rSRXapjQequt7kqalKXdcpIegIShhTPXx7yw0kek2uU=
|
||||
github.com/go-openapi/swag/fileutils v0.25.1/go.mod h1:+NXtt5xNZZqmpIpjqcujqojGFek9/w55b3ecmOdtg8M=
|
||||
github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU=
|
||||
github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.1 h1:AihLHaD0brrkJoMqEZOBNzTLnk81Kg9cWr+SPtxtgl8=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.1/go.mod h1:JpEkAjxQXpiaHmRO04N1zE4qbUEg3b7Udll7AMGTNOo=
|
||||
github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1 h1:DSQGcdB6G0N9c/KhtpYc71PzzGEIc/fZ1no35x4/XBY=
|
||||
github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1/go.mod h1:kjmweouyPwRUEYMSrbAidoLMGeJ5p6zdHi9BgZiqmsg=
|
||||
github.com/go-openapi/swag/loading v0.25.1 h1:6OruqzjWoJyanZOim58iG2vj934TysYVptyaoXS24kw=
|
||||
github.com/go-openapi/swag/loading v0.25.1/go.mod h1:xoIe2EG32NOYYbqxvXgPzne989bWvSNoWoyQVWEZicc=
|
||||
github.com/go-openapi/swag/mangling v0.25.1 h1:XzILnLzhZPZNtmxKaz/2xIGPQsBsvmCjrJOWGNz/ync=
|
||||
github.com/go-openapi/swag/mangling v0.25.1/go.mod h1:CdiMQ6pnfAgyQGSOIYnZkXvqhnnwOn997uXZMAd/7mQ=
|
||||
github.com/go-openapi/swag/netutils v0.25.1 h1:2wFLYahe40tDUHfKT1GRC4rfa5T1B4GWZ+msEFA4Fl4=
|
||||
github.com/go-openapi/swag/netutils v0.25.1/go.mod h1:CAkkvqnUJX8NV96tNhEQvKz8SQo2KF0f7LleiJwIeRE=
|
||||
github.com/go-openapi/swag/stringutils v0.25.1 h1:Xasqgjvk30eUe8VKdmyzKtjkVjeiXx1Iz0zDfMNpPbw=
|
||||
github.com/go-openapi/swag/stringutils v0.25.1/go.mod h1:JLdSAq5169HaiDUbTvArA2yQxmgn4D6h4A+4HqVvAYg=
|
||||
github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3I3ysiFZqukA=
|
||||
github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg=
|
||||
github.com/go-openapi/validate v0.25.0 h1:JD9eGX81hDTjoY3WOzh6WqxVBVl7xjsLnvDo1GL5WPU=
|
||||
github.com/go-openapi/validate v0.25.0/go.mod h1:SUY7vKrN5FiwK6LyvSwKjDfLNirSfWwHNgxd2l29Mmw=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
@@ -738,7 +762,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joncrlsn/dque v0.0.0-20211108142734-c2ef48c5192a h1:sfe532Ipn7GX0V6mHdynBk393rDmqgI0QmjLK7ct7TU=
|
||||
github.com/joncrlsn/dque v0.0.0-20211108142734-c2ef48c5192a/go.mod h1:dNKs71rs2VJGBAmttu7fouEsRQlRjxy0p1Sx+T5wbpY=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
@@ -808,8 +831,6 @@ github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i
|
||||
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI=
|
||||
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
@@ -969,8 +990,8 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/pressly/goose/v3 v3.26.0 h1:KJakav68jdH0WDvoAcj8+n61WqOIaPGgH0bJWS6jpmM=
|
||||
github.com/pressly/goose/v3 v3.26.0/go.mod h1:4hC1KrritdCxtuFsqgs1R4AU5bWtTAf+cnWvfhf2DNY=
|
||||
github.com/prometheus/alertmanager v0.28.1 h1:BK5pCoAtaKg01BYRUJhEDV1tqJMEtYBGzPw8QdvnnvA=
|
||||
github.com/prometheus/alertmanager v0.28.1/go.mod h1:0StpPUDDHi1VXeM7p2yYfeZgLVi/PPlt39vo9LQUHxM=
|
||||
github.com/prometheus/alertmanager v0.29.0 h1:/ET4NmAGx2Dv9kStrXIBqBgHyiSgIk4OetY+hoZRfgc=
|
||||
github.com/prometheus/alertmanager v0.29.0/go.mod h1:SjI2vhrfdWg10UaRUxTz27rgdJVG3HXrhI5WFjCdBgs=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
@@ -992,12 +1013,12 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||
github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI=
|
||||
github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q=
|
||||
github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
|
||||
github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI=
|
||||
github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg=
|
||||
github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA=
|
||||
github.com/prometheus/exporter-toolkit v0.14.1 h1:uKPE4ewweVRWFainwvAcHs3uw15pjw2dk3I7b+aNo9o=
|
||||
github.com/prometheus/exporter-toolkit v0.14.1/go.mod h1:di7yaAJiaMkcjcz48f/u4yRPwtyuxTU5Jr4EnM2mhtQ=
|
||||
github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DRXRd5OSnMEQ=
|
||||
github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
@@ -1170,8 +1191,8 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7H
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4=
|
||||
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
|
||||
go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM=
|
||||
go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
|
||||
go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw=
|
||||
go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
@@ -1179,8 +1200,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
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/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/collector/component v1.35.0 h1:JpvBukEcEUvJ/TInF1KYpXtWEP+C7iYkxCHKjI0o7BQ=
|
||||
go.opentelemetry.io/collector/component v1.35.0/go.mod h1:hU/ieWPxWbMAacODCSqem5ZaN6QH9W5GWiZ3MtXVuwc=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.129.0 h1:ejpBAt7hXAAZiQKcSxLvcy8sj8SjY4HOLdoXIlW6ybw=
|
||||
@@ -1300,8 +1321,10 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
|
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s=
|
||||
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@@ -1358,8 +1381,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
|
||||
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1492,8 +1515,8 @@ golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8=
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE=
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU=
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@@ -1569,8 +1592,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk=
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
+6
-4
@@ -13,7 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
// Package activation implements primitives for systemd socket activation.
|
||||
package activation
|
||||
@@ -38,9 +37,12 @@ const (
|
||||
// fd usage and to avoid leaking environment flags to child processes.
|
||||
func Files(unsetEnv bool) []*os.File {
|
||||
if unsetEnv {
|
||||
defer os.Unsetenv("LISTEN_PID")
|
||||
defer os.Unsetenv("LISTEN_FDS")
|
||||
defer os.Unsetenv("LISTEN_FDNAMES")
|
||||
defer func() {
|
||||
// Unsetenv implementation for unix never returns an error.
|
||||
_ = os.Unsetenv("LISTEN_PID")
|
||||
_ = os.Unsetenv("LISTEN_FDS")
|
||||
_ = os.Unsetenv("LISTEN_FDNAMES")
|
||||
}()
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
|
||||
|
||||
+1
-1
@@ -41,6 +41,6 @@ const (
|
||||
)
|
||||
|
||||
// Print prints a message to the local systemd journal using Send().
|
||||
func Print(priority Priority, format string, a ...interface{}) error {
|
||||
func Print(priority Priority, format string, a ...any) error {
|
||||
return Send(fmt.Sprintf(format, a...), priority, nil)
|
||||
}
|
||||
|
||||
+3
-5
@@ -13,7 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
// Package journal provides write bindings to the local systemd journal.
|
||||
// It is implemented in pure Go and connects to the journal directly over its
|
||||
@@ -31,7 +30,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -194,7 +192,7 @@ func appendVariable(w io.Writer, name, value string) {
|
||||
* - the data, followed by a newline
|
||||
*/
|
||||
fmt.Fprintln(w, name)
|
||||
binary.Write(w, binary.LittleEndian, uint64(len(value)))
|
||||
_ = binary.Write(w, binary.LittleEndian, uint64(len(value)))
|
||||
fmt.Fprintln(w, value)
|
||||
} else {
|
||||
/* just write the variable and value all on one line */
|
||||
@@ -214,7 +212,7 @@ func validVarName(name string) error {
|
||||
}
|
||||
|
||||
for _, c := range name {
|
||||
if !(('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_') {
|
||||
if ('A' > c || c > 'Z') && ('0' > c || c > '9') && c != '_' {
|
||||
return errors.New("Variable name contains invalid characters")
|
||||
}
|
||||
}
|
||||
@@ -239,7 +237,7 @@ func isSocketSpaceError(err error) bool {
|
||||
|
||||
// tempFd creates a temporary, unlinked file under `/dev/shm`.
|
||||
func tempFd() (*os.File, error) {
|
||||
file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX")
|
||||
file, err := os.CreateTemp("/dev/shm/", "journal.XXXXX")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+70
-56
@@ -1,61 +1,75 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- maligned
|
||||
- unparam
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- nlreturn
|
||||
- noinlineerr
|
||||
- nonamedreturns
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- wsl_v5
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text.
|
||||
# Set to 0 to disable.
|
||||
# Default: 3
|
||||
max-same-issues: 0
|
||||
|
||||
+583
-579
File diff suppressed because it is too large
Load Diff
+53
@@ -0,0 +1,53 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type analysisError string
|
||||
|
||||
const (
|
||||
ErrAnalysis analysisError = "analysis error"
|
||||
ErrNoSchema analysisError = "no schema to analyze"
|
||||
)
|
||||
|
||||
func (e analysisError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func ErrAtKey(key string, err error) error {
|
||||
return errors.Join(
|
||||
fmt.Errorf("key %s: %w", key, err),
|
||||
ErrAnalysis,
|
||||
)
|
||||
}
|
||||
|
||||
func ErrInvalidRef(key string) error {
|
||||
return fmt.Errorf("invalid reference: %q: %w", key, ErrAnalysis)
|
||||
}
|
||||
|
||||
func ErrInvalidParameterRef(key string) error {
|
||||
return fmt.Errorf("resolved reference is not a parameter: %q: %w", key, ErrAnalysis)
|
||||
}
|
||||
|
||||
func ErrResolveSchema(err error) error {
|
||||
return errors.Join(
|
||||
fmt.Errorf("could not resolve schema: %w", err),
|
||||
ErrAnalysis,
|
||||
)
|
||||
}
|
||||
|
||||
func ErrRewriteRef(key string, target any, err error) error {
|
||||
return errors.Join(
|
||||
fmt.Errorf("failed to rewrite ref for key %q at %v: %w", key, target, err),
|
||||
ErrAnalysis,
|
||||
)
|
||||
}
|
||||
|
||||
func ErrInlineDefinition(key string, err error) error {
|
||||
return errors.Join(
|
||||
fmt.Errorf("error while creating definition %q from inline schema: %w", key, err),
|
||||
ErrAnalysis,
|
||||
)
|
||||
}
|
||||
+1
-1
@@ -72,7 +72,7 @@ func FixEmptyDescs(rs *spec.Responses) {
|
||||
// Response object if it doesn't already have one and isn't a
|
||||
// ref. No-op on nil input.
|
||||
func FixEmptyDesc(rs *spec.Response) {
|
||||
if rs == nil || rs.Description != "" || rs.Ref.Ref.GetURL() != nil {
|
||||
if rs == nil || rs.Description != "" || rs.Ref.GetURL() != nil {
|
||||
return
|
||||
}
|
||||
rs.Description = "(empty)"
|
||||
|
||||
+12
-13
@@ -15,7 +15,6 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"path"
|
||||
"sort"
|
||||
@@ -52,9 +51,9 @@ type context struct {
|
||||
|
||||
func newContext() *context {
|
||||
return &context{
|
||||
newRefs: make(map[string]*newRef, 150),
|
||||
newRefs: make(map[string]*newRef, allocMediumMap),
|
||||
warnings: make([]string, 0),
|
||||
resolved: make(map[string]string, 50),
|
||||
resolved: make(map[string]string, allocMediumMap),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +250,7 @@ func nameInlinedSchemas(opts *FlattenOpts) error {
|
||||
|
||||
asch, err := Schema(SchemaOpts{Schema: sch.Schema, Root: opts.Swagger(), BasePath: opts.BasePath})
|
||||
if err != nil {
|
||||
return fmt.Errorf("schema analysis [%s]: %w", key, err)
|
||||
return ErrAtKey(key, err)
|
||||
}
|
||||
|
||||
if asch.isAnalyzedAsComplex() { // move complex schemas to definitions
|
||||
@@ -320,7 +319,7 @@ func importNewRef(entry sortref.RefRevIdx, refStr string, opts *FlattenOpts) err
|
||||
|
||||
sch, err := spec.ResolveRefWithBase(opts.Swagger(), &entry.Ref, opts.ExpandOpts(false))
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not resolve schema: %w", err)
|
||||
return ErrResolveSchema(err)
|
||||
}
|
||||
|
||||
// at this stage only $ref analysis matters
|
||||
@@ -335,7 +334,7 @@ func importNewRef(entry sortref.RefRevIdx, refStr string, opts *FlattenOpts) err
|
||||
// now rewrite those refs with rebase
|
||||
for key, ref := range partialAnalyzer.references.allRefs {
|
||||
if err := replace.UpdateRef(sch, key, spec.MustCreateRef(normalize.RebaseRef(entry.Ref.String(), ref.String()))); err != nil {
|
||||
return fmt.Errorf("failed to rewrite ref for key %q at %s: %w", key, entry.Ref.String(), err)
|
||||
return ErrRewriteRef(key, entry.Ref.String(), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,7 +428,7 @@ func importExternalReferences(opts *FlattenOpts) (bool, error) {
|
||||
ref := spec.MustCreateRef(r.path)
|
||||
sch, err := spec.ResolveRefWithBase(opts.Swagger(), &ref, opts.ExpandOpts(false))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("could not resolve schema: %w", err)
|
||||
return false, ErrResolveSchema(err)
|
||||
}
|
||||
|
||||
r.schema = sch
|
||||
@@ -643,7 +642,7 @@ func stripOAIGenForRef(opts *FlattenOpts, k string, r *newRef) (bool, error) {
|
||||
}
|
||||
|
||||
debugLog("re-inlined schema: parent: %s, %t", pr[0], asch.isAnalyzedAsComplex())
|
||||
replacedWithComplex = replacedWithComplex || !(path.Dir(pr[0]) == definitionsPath) && asch.isAnalyzedAsComplex()
|
||||
replacedWithComplex = replacedWithComplex || path.Dir(pr[0]) != definitionsPath && asch.isAnalyzedAsComplex()
|
||||
}
|
||||
|
||||
return replacedWithComplex, nil
|
||||
@@ -666,7 +665,7 @@ func namePointers(opts *FlattenOpts) error {
|
||||
|
||||
result, err := replace.DeepestRef(opts.Swagger(), opts.ExpandOpts(false), ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("at %s, %w", k, err)
|
||||
return ErrAtKey(k, err)
|
||||
}
|
||||
|
||||
replacingRef := result.Ref
|
||||
@@ -697,7 +696,7 @@ func namePointers(opts *FlattenOpts) error {
|
||||
// update current replacement, which may have been updated by previous changes of deeper elements
|
||||
result, erd := replace.DeepestRef(opts.Swagger(), opts.ExpandOpts(false), v.Ref)
|
||||
if erd != nil {
|
||||
return fmt.Errorf("at %s, %w", key, erd)
|
||||
return ErrAtKey(key, erd)
|
||||
}
|
||||
|
||||
if opts.flattenContext != nil {
|
||||
@@ -743,9 +742,9 @@ func flattenAnonPointer(key string, v SchemaRef, refsToReplace map[string]Schema
|
||||
// qualify the expanded schema
|
||||
asch, ers := Schema(SchemaOpts{Schema: v.Schema, Root: opts.Swagger(), BasePath: opts.BasePath})
|
||||
if ers != nil {
|
||||
return fmt.Errorf("schema analysis [%s]: %w", key, ers)
|
||||
return ErrAtKey(key, ers)
|
||||
}
|
||||
callers := make([]string, 0, 64)
|
||||
callers := make([]string, 0, allocMediumMap)
|
||||
|
||||
debugLog("looking for callers")
|
||||
|
||||
@@ -753,7 +752,7 @@ func flattenAnonPointer(key string, v SchemaRef, refsToReplace map[string]Schema
|
||||
for k, w := range an.references.allRefs {
|
||||
r, err := replace.DeepestRef(opts.Swagger(), opts.ExpandOpts(false), w)
|
||||
if err != nil {
|
||||
return fmt.Errorf("at %s, %w", key, err)
|
||||
return ErrAtKey(key, err)
|
||||
}
|
||||
|
||||
if opts.flattenContext != nil {
|
||||
|
||||
+12
-6
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/go-openapi/analysis/internal/flatten/schutils"
|
||||
"github.com/go-openapi/analysis/internal/flatten/sortref"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/mangling"
|
||||
)
|
||||
|
||||
// InlineSchemaNamer finds a new name for an inlined type
|
||||
@@ -43,7 +43,7 @@ func (isn *InlineSchemaNamer) Name(key string, schema *spec.Schema, aschema *Ana
|
||||
debugLog("rewriting schema to ref: key=%s with new name: %s", key, newName)
|
||||
if err := replace.RewriteSchemaToRef(isn.Spec, key,
|
||||
spec.MustCreateRef(path.Join(definitionsPath, newName))); err != nil {
|
||||
return fmt.Errorf("error while creating definition %q from inline schema: %w", newName, err)
|
||||
return ErrInlineDefinition(newName, err)
|
||||
}
|
||||
|
||||
// rewrite any dependent $ref pointing to this place,
|
||||
@@ -54,7 +54,7 @@ func (isn *InlineSchemaNamer) Name(key string, schema *spec.Schema, aschema *Ana
|
||||
for k, v := range an.references.allRefs {
|
||||
r, erd := replace.DeepestRef(isn.opts.Swagger(), isn.opts.ExpandOpts(false), v)
|
||||
if erd != nil {
|
||||
return fmt.Errorf("at %s, %w", k, erd)
|
||||
return ErrAtKey(k, erd)
|
||||
}
|
||||
|
||||
if isn.opts.flattenContext != nil {
|
||||
@@ -227,10 +227,15 @@ func namesForOperation(parts sortref.SplitKey, operations map[string]operations.
|
||||
return baseNames, startIndex
|
||||
}
|
||||
|
||||
const (
|
||||
minStartIndex = 2
|
||||
minSegments = 2
|
||||
)
|
||||
|
||||
func namesForDefinition(parts sortref.SplitKey) ([][]string, int) {
|
||||
nm := parts.DefinitionName()
|
||||
if nm != "" {
|
||||
return [][]string{{parts.DefinitionName()}}, 2
|
||||
return [][]string{{parts.DefinitionName()}}, minStartIndex
|
||||
}
|
||||
|
||||
return [][]string{}, 0
|
||||
@@ -239,7 +244,7 @@ func namesForDefinition(parts sortref.SplitKey) ([][]string, int) {
|
||||
// partAdder knows how to interpret a schema when it comes to build a name from parts
|
||||
func partAdder(aschema *AnalyzedSchema) sortref.PartAdder {
|
||||
return func(part string) []string {
|
||||
segments := make([]string, 0, 2)
|
||||
segments := make([]string, 0, minSegments)
|
||||
|
||||
if part == "items" || part == "additionalItems" {
|
||||
if aschema.IsTuple || aschema.IsTupleWithExtra {
|
||||
@@ -265,8 +270,9 @@ func mangler(o *FlattenOpts) func(string) string {
|
||||
if o.KeepNames {
|
||||
return func(in string) string { return in }
|
||||
}
|
||||
mangler := mangling.NewNameMangler()
|
||||
|
||||
return swag.ToJSONName
|
||||
return mangler.ToJSONName
|
||||
}
|
||||
|
||||
func nameFromRef(ref spec.Ref, o *FlattenOpts) string {
|
||||
|
||||
+5
-3
@@ -2,12 +2,13 @@ package operations
|
||||
|
||||
import (
|
||||
"path"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/mangling"
|
||||
)
|
||||
|
||||
// AllOpRefsByRef returns an index of sortable operations
|
||||
@@ -50,12 +51,13 @@ type Provider interface {
|
||||
// GatherOperations builds a map of sorted operations from a spec
|
||||
func GatherOperations(specDoc Provider, operationIDs []string) map[string]OpRef {
|
||||
var oprefs OpRefs
|
||||
mangler := mangling.NewNameMangler()
|
||||
|
||||
for method, pathItem := range specDoc.Operations() {
|
||||
for pth, operation := range pathItem {
|
||||
vv := *operation
|
||||
oprefs = append(oprefs, OpRef{
|
||||
Key: swag.ToGoName(strings.ToLower(method) + " " + pth),
|
||||
Key: mangler.ToGoName(strings.ToLower(method) + " " + pth),
|
||||
Method: method,
|
||||
Path: pth,
|
||||
ID: vv.ID,
|
||||
@@ -79,7 +81,7 @@ func GatherOperations(specDoc Provider, operationIDs []string) map[string]OpRef
|
||||
nm = opr.Key
|
||||
}
|
||||
|
||||
if len(operationIDs) == 0 || swag.ContainsStrings(operationIDs, opr.ID) || swag.ContainsStrings(operationIDs, nm) {
|
||||
if len(operationIDs) == 0 || slices.Contains(operationIDs, opr.ID) || slices.Contains(operationIDs, nm) {
|
||||
opr.ID = nm
|
||||
opr.Op.ID = nm
|
||||
operations[nm] = opr
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package replace
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type replaceError string
|
||||
|
||||
const (
|
||||
ErrReplace replaceError = "flatten replace error"
|
||||
ErrUnexpectedType replaceError = "unexpected type used in getPointerFromKey"
|
||||
)
|
||||
|
||||
func (e replaceError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func ErrNoSchemaWithRef(key string, value any) error {
|
||||
return fmt.Errorf("no schema with ref found at %s for %T: %w", key, value, ErrReplace)
|
||||
}
|
||||
|
||||
func ErrNoSchema(key string) error {
|
||||
return fmt.Errorf("no schema found at %s: %w", key, ErrReplace)
|
||||
}
|
||||
|
||||
func ErrNotANumber(key string, err error) error {
|
||||
return errors.Join(
|
||||
ErrReplace,
|
||||
fmt.Errorf("%s not a number: %w", key, err),
|
||||
)
|
||||
}
|
||||
|
||||
func ErrUnhandledParentRewrite(key string, value any) error {
|
||||
return fmt.Errorf("unhandled parent schema rewrite %s: %T: %w", key, value, ErrReplace)
|
||||
}
|
||||
|
||||
func ErrUnhandledParentType(key string, value any) error {
|
||||
return fmt.Errorf("unhandled type for parent of %s: %T: %w", key, value, ErrReplace)
|
||||
}
|
||||
|
||||
func ErrNoParent(key string, err error) error {
|
||||
return errors.Join(
|
||||
fmt.Errorf("can't get parent for %s: %w", key, err),
|
||||
ErrReplace,
|
||||
)
|
||||
}
|
||||
|
||||
func ErrUnhandledContainerType(key string, value any) error {
|
||||
return fmt.Errorf("unhandled container type at %s: %T: %w", key, value, ErrReplace)
|
||||
}
|
||||
|
||||
func ErrCyclicChain(key string) error {
|
||||
return fmt.Errorf("cannot resolve cyclic chain of pointers under %s: %w", key, ErrReplace)
|
||||
}
|
||||
|
||||
func ErrInvalidPointerType(key string, value any, err error) error {
|
||||
return fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T (%v): %w",
|
||||
key, value, err, ErrReplace,
|
||||
)
|
||||
}
|
||||
+36
-41
@@ -2,6 +2,7 @@ package replace
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -13,7 +14,10 @@ import (
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
const definitionsPath = "#/definitions"
|
||||
const (
|
||||
definitionsPath = "#/definitions"
|
||||
allocMediumMap = 64
|
||||
)
|
||||
|
||||
var debugLog = debug.GetLogger("analysis/flatten/replace", os.Getenv("SWAGGER_DEBUG") != "")
|
||||
|
||||
@@ -44,7 +48,7 @@ func RewriteSchemaToRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
case map[string]interface{}: // this happens e.g. if a schema points to an extension unmarshaled as map[string]interface{}
|
||||
return rewriteParentRef(sp, key, ref)
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
return ErrNoSchemaWithRef(key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -69,7 +73,7 @@ func rewriteParentRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
case *spec.Responses:
|
||||
statusCode, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
return ErrNotANumber(key[1:], err)
|
||||
}
|
||||
resp := container.StatusCodeResponses[statusCode]
|
||||
resp.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
@@ -93,7 +97,7 @@ func rewriteParentRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
case []spec.Parameter:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
return ErrNotANumber(key[1:], err)
|
||||
}
|
||||
param := container[idx]
|
||||
param.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
@@ -108,7 +112,7 @@ func rewriteParentRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
return ErrNotANumber(key[1:], err)
|
||||
}
|
||||
container[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
@@ -116,7 +120,7 @@ func rewriteParentRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
return ErrNotANumber(key[1:], err)
|
||||
}
|
||||
container.Schemas[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
@@ -129,7 +133,7 @@ func rewriteParentRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled parent schema rewrite %s (%T)", key, pvalue)
|
||||
return ErrUnhandledParentRewrite(key, pvalue)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -141,7 +145,7 @@ func getPointerFromKey(sp interface{}, key string) (string, interface{}, error)
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
panic(ErrUnexpectedType)
|
||||
}
|
||||
if key == "#/" {
|
||||
return "", sp, nil
|
||||
@@ -150,14 +154,14 @@ func getPointerFromKey(sp interface{}, key string) (string, interface{}, error)
|
||||
pth, _ := url.PathUnescape(key[1:])
|
||||
ptr, err := jsonpointer.New(pth)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
return "", nil, errors.Join(err, ErrReplace)
|
||||
}
|
||||
|
||||
value, _, err := ptr.Get(sp)
|
||||
if err != nil {
|
||||
debugLog("error when getting key: %s with path: %s", key, pth)
|
||||
|
||||
return "", nil, err
|
||||
return "", nil, errors.Join(err, ErrReplace)
|
||||
}
|
||||
|
||||
return pth, value, nil
|
||||
@@ -169,7 +173,7 @@ func getParentFromKey(sp interface{}, key string) (string, string, interface{},
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
panic(ErrUnexpectedType)
|
||||
}
|
||||
// unescape chars in key, e.g. "{}" from path params
|
||||
pth, _ := url.PathUnescape(key[1:])
|
||||
@@ -179,11 +183,11 @@ func getParentFromKey(sp interface{}, key string) (string, string, interface{},
|
||||
|
||||
pptr, err := jsonpointer.New(parent)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
return "", "", nil, errors.Join(err, ErrReplace)
|
||||
}
|
||||
pvalue, _, err := pptr.Get(sp)
|
||||
if err != nil {
|
||||
return "", "", nil, fmt.Errorf("can't get parent for %s: %w", parent, err)
|
||||
return "", "", nil, ErrNoParent(parent, err)
|
||||
}
|
||||
|
||||
return parent, entry, pvalue, nil
|
||||
@@ -195,7 +199,7 @@ func UpdateRef(sp interface{}, key string, ref spec.Ref) error {
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
panic(ErrUnexpectedType)
|
||||
}
|
||||
debugLog("updating ref for %s with %s", key, ref.String())
|
||||
pth, value, err := getPointerFromKey(sp, key)
|
||||
@@ -218,7 +222,7 @@ func UpdateRef(sp interface{}, key string, ref spec.Ref) error {
|
||||
debugLog("rewriting holder for %T", refable)
|
||||
_, entry, pvalue, erp := getParentFromKey(sp, key)
|
||||
if erp != nil {
|
||||
return err
|
||||
return erp
|
||||
}
|
||||
switch container := pvalue.(type) {
|
||||
case spec.Definitions:
|
||||
@@ -230,7 +234,7 @@ func UpdateRef(sp interface{}, key string, ref spec.Ref) error {
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
return ErrNotANumber(pth, err)
|
||||
}
|
||||
container[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
@@ -238,7 +242,7 @@ func UpdateRef(sp interface{}, key string, ref spec.Ref) error {
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
return ErrNotANumber(pth, err)
|
||||
}
|
||||
container.Schemas[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
@@ -248,11 +252,11 @@ func UpdateRef(sp interface{}, key string, ref spec.Ref) error {
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled container type at %s: %T", key, value)
|
||||
return ErrUnhandledContainerType(key, value)
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
return ErrNoSchemaWithRef(key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -272,8 +276,9 @@ func UpdateRefWithSchema(sp *spec.Swagger, key string, sch *spec.Schema) error {
|
||||
case spec.Schema:
|
||||
_, entry, pvalue, erp := getParentFromKey(sp, key)
|
||||
if erp != nil {
|
||||
return err
|
||||
return erp
|
||||
}
|
||||
|
||||
switch container := pvalue.(type) {
|
||||
case spec.Definitions:
|
||||
container[entry] = *sch
|
||||
@@ -284,7 +289,7 @@ func UpdateRefWithSchema(sp *spec.Swagger, key string, sch *spec.Schema) error {
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
return ErrNotANumber(pth, err)
|
||||
}
|
||||
container[idx] = *sch
|
||||
|
||||
@@ -292,7 +297,7 @@ func UpdateRefWithSchema(sp *spec.Swagger, key string, sch *spec.Schema) error {
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
return ErrNotANumber(pth, err)
|
||||
}
|
||||
container.Schemas[idx] = *sch
|
||||
|
||||
@@ -302,7 +307,7 @@ func UpdateRefWithSchema(sp *spec.Swagger, key string, sch *spec.Schema) error {
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled type for parent of [%s]: %T", key, value)
|
||||
return ErrUnhandledParentType(key, value)
|
||||
}
|
||||
case *spec.SchemaOrArray:
|
||||
*refable.Schema = *sch
|
||||
@@ -310,7 +315,7 @@ func UpdateRefWithSchema(sp *spec.Swagger, key string, sch *spec.Schema) error {
|
||||
case *spec.SchemaOrBool:
|
||||
*refable.Schema = *sch
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
return ErrNoSchemaWithRef(key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -336,8 +341,8 @@ func DeepestRef(sp *spec.Swagger, opts *spec.ExpandOptions, ref spec.Ref) (*Deep
|
||||
}
|
||||
|
||||
currentRef := ref
|
||||
visited := make(map[string]bool, 64)
|
||||
warnings := make([]string, 0, 2)
|
||||
visited := make(map[string]bool, allocMediumMap)
|
||||
warnings := make([]string, 0)
|
||||
|
||||
DOWNREF:
|
||||
for currentRef.String() != "" {
|
||||
@@ -347,8 +352,7 @@ DOWNREF:
|
||||
}
|
||||
|
||||
if _, beenThere := visited[currentRef.String()]; beenThere {
|
||||
return nil,
|
||||
fmt.Errorf("cannot resolve cyclic chain of pointers under %s", currentRef.String())
|
||||
return nil, ErrCyclicChain(currentRef.String())
|
||||
}
|
||||
|
||||
visited[currentRef.String()] = true
|
||||
@@ -390,10 +394,7 @@ DOWNREF:
|
||||
|
||||
err := asSchema.UnmarshalJSON(asJSON)
|
||||
if err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T (%v)",
|
||||
currentRef.String(), value, err,
|
||||
)
|
||||
return nil, ErrInvalidPointerType(currentRef.String(), value, err)
|
||||
}
|
||||
warnings = append(warnings, fmt.Sprintf("found $ref %q (response) interpreted as schema", currentRef.String()))
|
||||
|
||||
@@ -408,10 +409,7 @@ DOWNREF:
|
||||
asJSON, _ := refable.MarshalJSON()
|
||||
var asSchema spec.Schema
|
||||
if err := asSchema.UnmarshalJSON(asJSON); err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T (%v)",
|
||||
currentRef.String(), value, err,
|
||||
)
|
||||
return nil, ErrInvalidPointerType(currentRef.String(), value, err)
|
||||
}
|
||||
|
||||
warnings = append(warnings, fmt.Sprintf("found $ref %q (parameter) interpreted as schema", currentRef.String()))
|
||||
@@ -430,10 +428,7 @@ DOWNREF:
|
||||
asJSON, _ := json.Marshal(refable)
|
||||
var asSchema spec.Schema
|
||||
if err := asSchema.UnmarshalJSON(asJSON); err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("unhandled type to resolve JSON pointer %s. Expected a Schema, got: %T (%v)",
|
||||
currentRef.String(), value, err,
|
||||
)
|
||||
return nil, ErrInvalidPointerType(currentRef.String(), value, err)
|
||||
}
|
||||
warnings = append(warnings, fmt.Sprintf("found $ref %q (%T) interpreted as schema", currentRef.String(), refable))
|
||||
|
||||
@@ -451,7 +446,7 @@ DOWNREF:
|
||||
}
|
||||
|
||||
if sch == nil {
|
||||
return nil, fmt.Errorf("no schema found at %s", currentRef.String())
|
||||
return nil, ErrNoSchema(currentRef.String())
|
||||
}
|
||||
|
||||
return &DeepestRefResult{Ref: currentRef, Schema: sch, Warnings: warnings}, nil
|
||||
|
||||
Generated
Vendored
+5
-3
@@ -4,9 +4,11 @@ package schutils
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
const allocLargeMap = 150
|
||||
|
||||
// Save registers a schema as an entry in spec #/definitions
|
||||
func Save(sp *spec.Swagger, name string, schema *spec.Schema) {
|
||||
if schema == nil {
|
||||
@@ -14,7 +16,7 @@ func Save(sp *spec.Swagger, name string, schema *spec.Schema) {
|
||||
}
|
||||
|
||||
if sp.Definitions == nil {
|
||||
sp.Definitions = make(map[string]spec.Schema, 150)
|
||||
sp.Definitions = make(map[string]spec.Schema, allocLargeMap)
|
||||
}
|
||||
|
||||
sp.Definitions[name] = *schema
|
||||
@@ -23,7 +25,7 @@ func Save(sp *spec.Swagger, name string, schema *spec.Schema) {
|
||||
// Clone deep-clones a schema
|
||||
func Clone(schema *spec.Schema) *spec.Schema {
|
||||
var sch spec.Schema
|
||||
_ = swag.FromDynamicJSON(schema, &sch)
|
||||
_ = jsonutils.FromDynamicJSON(schema, &sch)
|
||||
|
||||
return &sch
|
||||
}
|
||||
|
||||
+18
-17
@@ -86,22 +86,6 @@ func (s SplitKey) DefinitionName() string {
|
||||
return s[1]
|
||||
}
|
||||
|
||||
func (s SplitKey) isKeyName(i int) bool {
|
||||
if i <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
count := 0
|
||||
for idx := i - 1; idx > 0; idx-- {
|
||||
if s[idx] != "properties" {
|
||||
break
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
return count%2 != 0
|
||||
}
|
||||
|
||||
// PartAdder know how to construct the components of a new name
|
||||
type PartAdder func(string) []string
|
||||
|
||||
@@ -179,7 +163,8 @@ func (s SplitKey) ResponseName() string {
|
||||
|
||||
// PathItemRef constructs a $ref object from a split key of the form /{path}/{method}
|
||||
func (s SplitKey) PathItemRef() spec.Ref {
|
||||
if len(s) < 3 {
|
||||
const minValidPathItems = 3
|
||||
if len(s) < minValidPathItems {
|
||||
return spec.Ref{}
|
||||
}
|
||||
|
||||
@@ -199,3 +184,19 @@ func (s SplitKey) PathRef() spec.Ref {
|
||||
|
||||
return spec.MustCreateRef("#" + path.Join("/", paths, jsonpointer.Escape(s[1])))
|
||||
}
|
||||
|
||||
func (s SplitKey) isKeyName(i int) bool {
|
||||
if i <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
count := 0
|
||||
for idx := i - 1; idx > 0; idx-- {
|
||||
if s[idx] != "properties" {
|
||||
break
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
return count%2 != 0
|
||||
}
|
||||
|
||||
+6
-6
@@ -391,7 +391,7 @@ func mergeInfo(primary *spec.Info, m *spec.Info) []string {
|
||||
}
|
||||
|
||||
if primary.Title == "" {
|
||||
primary.Description = m.Description
|
||||
primary.Title = m.Title
|
||||
}
|
||||
|
||||
if primary.TermsOfService == "" {
|
||||
@@ -474,23 +474,23 @@ func initPrimary(primary *spec.Swagger) {
|
||||
}
|
||||
|
||||
if primary.Security == nil {
|
||||
primary.Security = make([]map[string][]string, 0, 10)
|
||||
primary.Security = make([]map[string][]string, 0, allocSmallMap)
|
||||
}
|
||||
|
||||
if primary.Produces == nil {
|
||||
primary.Produces = make([]string, 0, 10)
|
||||
primary.Produces = make([]string, 0, allocSmallMap)
|
||||
}
|
||||
|
||||
if primary.Consumes == nil {
|
||||
primary.Consumes = make([]string, 0, 10)
|
||||
primary.Consumes = make([]string, 0, allocSmallMap)
|
||||
}
|
||||
|
||||
if primary.Tags == nil {
|
||||
primary.Tags = make([]spec.Tag, 0, 10)
|
||||
primary.Tags = make([]spec.Tag, 0, allocSmallMap)
|
||||
}
|
||||
|
||||
if primary.Schemes == nil {
|
||||
primary.Schemes = make([]string, 0, 10)
|
||||
primary.Schemes = make([]string, 0, allocSmallMap)
|
||||
}
|
||||
|
||||
if primary.Paths == nil {
|
||||
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
@@ -19,7 +17,7 @@ type SchemaOpts struct {
|
||||
// patterns.
|
||||
func Schema(opts SchemaOpts) (*AnalyzedSchema, error) {
|
||||
if opts.Schema == nil {
|
||||
return nil, errors.New("no schema to analyze")
|
||||
return nil, ErrNoSchema
|
||||
}
|
||||
|
||||
a := &AnalyzedSchema{
|
||||
|
||||
+70
-57
@@ -1,62 +1,75 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- errname # this repo doesn't follow the convention advised by this linter
|
||||
- maligned
|
||||
- unparam
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- nlreturn
|
||||
- noinlineerr
|
||||
- nonamedreturns
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- wsl_v5
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text.
|
||||
# Set to 0 to disable.
|
||||
# Default: 3
|
||||
max-same-issues: 0
|
||||
|
||||
+4
-4
@@ -71,12 +71,12 @@ func NotFound(message string, args ...interface{}) Error {
|
||||
if message == "" {
|
||||
message = "Not found"
|
||||
}
|
||||
return New(http.StatusNotFound, fmt.Sprintf(message, args...))
|
||||
return New(http.StatusNotFound, message, args...)
|
||||
}
|
||||
|
||||
// NotImplemented creates a new not implemented error
|
||||
func NotImplemented(message string) Error {
|
||||
return New(http.StatusNotImplemented, message)
|
||||
return New(http.StatusNotImplemented, "%s", message)
|
||||
}
|
||||
|
||||
// MethodNotAllowedError represents an error for when the path matches but the method doesn't
|
||||
@@ -179,13 +179,13 @@ func ServeError(rw http.ResponseWriter, r *http.Request, err error) {
|
||||
default:
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
if r == nil || r.Method != http.MethodHead {
|
||||
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, err.Error())))
|
||||
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, "%v", err)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func asHTTPCode(input int) int {
|
||||
if input >= 600 {
|
||||
if input >= maximumValidHTTPCode {
|
||||
return DefaultHTTPCode
|
||||
}
|
||||
return input
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
// Validation represents a failure of a precondition
|
||||
type Validation struct {
|
||||
type Validation struct { //nolint: errname
|
||||
code int32
|
||||
Name string
|
||||
In string
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
// APIVerificationFailed is an error that contains all the missing info for a mismatched section
|
||||
// between the api registrations and the api spec
|
||||
type APIVerificationFailed struct {
|
||||
type APIVerificationFailed struct { //nolint: errname
|
||||
Section string `json:"section,omitempty"`
|
||||
MissingSpecification []string `json:"missingSpecification,omitempty"`
|
||||
MissingRegistration []string `json:"missingRegistration,omitempty"`
|
||||
@@ -35,7 +35,7 @@ func (v *APIVerificationFailed) Error() string {
|
||||
hasSpecMissing := len(v.MissingSpecification) > 0
|
||||
|
||||
if hasRegMissing {
|
||||
buf.WriteString(fmt.Sprintf("missing [%s] %s registrations", strings.Join(v.MissingRegistration, ", "), v.Section))
|
||||
fmt.Fprintf(buf, "missing [%s] %s registrations", strings.Join(v.MissingRegistration, ", "), v.Section)
|
||||
}
|
||||
|
||||
if hasRegMissing && hasSpecMissing {
|
||||
@@ -43,7 +43,7 @@ func (v *APIVerificationFailed) Error() string {
|
||||
}
|
||||
|
||||
if hasSpecMissing {
|
||||
buf.WriteString(fmt.Sprintf("missing from spec file [%s] %s", strings.Join(v.MissingSpecification, ", "), v.Section))
|
||||
fmt.Fprintf(buf, "missing from spec file [%s] %s", strings.Join(v.MissingSpecification, ", "), v.Section)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
|
||||
+19
-18
@@ -17,6 +17,7 @@ package errors
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ParseError represents a parsing error
|
||||
@@ -29,6 +30,24 @@ type ParseError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
// NewParseError creates a new parse error
|
||||
func NewParseError(name, in, value string, reason error) *ParseError {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(parseErrorTemplContentNoIn, name, value, reason)
|
||||
} else {
|
||||
msg = fmt.Sprintf(parseErrorTemplContent, name, in, value, reason)
|
||||
}
|
||||
return &ParseError{
|
||||
code: http.StatusBadRequest,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
Reason: reason,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ParseError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
@@ -58,21 +77,3 @@ const (
|
||||
parseErrorTemplContent = `parsing %s %s from %q failed, because %s`
|
||||
parseErrorTemplContentNoIn = `parsing %s from %q failed, because %s`
|
||||
)
|
||||
|
||||
// NewParseError creates a new parse error
|
||||
func NewParseError(name, in, value string, reason error) *ParseError {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(parseErrorTemplContentNoIn, name, value, reason)
|
||||
} else {
|
||||
msg = fmt.Sprintf(parseErrorTemplContent, name, in, value, reason)
|
||||
}
|
||||
return &ParseError{
|
||||
code: 400,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
Reason: reason,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
+57
-53
@@ -17,6 +17,7 @@ package errors
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -32,12 +33,12 @@ const (
|
||||
patternFail = "%s in %s should match '%s'"
|
||||
enumFail = "%s in %s should be one of %v"
|
||||
multipleOfFail = "%s in %s should be a multiple of %v"
|
||||
maxIncFail = "%s in %s should be less than or equal to %v"
|
||||
maxExcFail = "%s in %s should be less than %v"
|
||||
maximumIncFail = "%s in %s should be less than or equal to %v"
|
||||
maximumExcFail = "%s in %s should be less than %v"
|
||||
minIncFail = "%s in %s should be greater than or equal to %v"
|
||||
minExcFail = "%s in %s should be greater than %v"
|
||||
uniqueFail = "%s in %s shouldn't contain duplicates"
|
||||
maxItemsFail = "%s in %s should have at most %d items"
|
||||
maximumItemsFail = "%s in %s should have at most %d items"
|
||||
minItemsFail = "%s in %s should have at least %d items"
|
||||
typeFailNoIn = "%s must be of type %s"
|
||||
typeFailWithDataNoIn = "%s must be of type %s: %q"
|
||||
@@ -49,12 +50,12 @@ const (
|
||||
patternFailNoIn = "%s should match '%s'"
|
||||
enumFailNoIn = "%s should be one of %v"
|
||||
multipleOfFailNoIn = "%s should be a multiple of %v"
|
||||
maxIncFailNoIn = "%s should be less than or equal to %v"
|
||||
maxExcFailNoIn = "%s should be less than %v"
|
||||
maximumIncFailNoIn = "%s should be less than or equal to %v"
|
||||
maximumExcFailNoIn = "%s should be less than %v"
|
||||
minIncFailNoIn = "%s should be greater than or equal to %v"
|
||||
minExcFailNoIn = "%s should be greater than %v"
|
||||
uniqueFailNoIn = "%s shouldn't contain duplicates"
|
||||
maxItemsFailNoIn = "%s should have at most %d items"
|
||||
maximumItemsFailNoIn = "%s should have at most %d items"
|
||||
minItemsFailNoIn = "%s should have at least %d items"
|
||||
noAdditionalItems = "%s in %s can't have additional items"
|
||||
noAdditionalItemsNoIn = "%s can't have additional items"
|
||||
@@ -69,14 +70,17 @@ const (
|
||||
multipleOfMustBePositive = "factor MultipleOf declared for %s must be positive: %v"
|
||||
)
|
||||
|
||||
const maximumValidHTTPCode = 600
|
||||
|
||||
// All code responses can be used to differentiate errors for different handling
|
||||
// by the consuming program
|
||||
const (
|
||||
// CompositeErrorCode remains 422 for backwards-compatibility
|
||||
// and to separate it from validation errors with cause
|
||||
CompositeErrorCode = 422
|
||||
CompositeErrorCode = http.StatusUnprocessableEntity
|
||||
|
||||
// InvalidTypeCode is used for any subclass of invalid types
|
||||
InvalidTypeCode = 600 + iota
|
||||
InvalidTypeCode = maximumValidHTTPCode + iota
|
||||
RequiredFailCode
|
||||
TooLongFailCode
|
||||
TooShortFailCode
|
||||
@@ -298,10 +302,10 @@ func DuplicateItems(name, in string) *Validation {
|
||||
}
|
||||
|
||||
// TooManyItems error for when an array contains too many items
|
||||
func TooManyItems(name, in string, max int64, value interface{}) *Validation {
|
||||
msg := fmt.Sprintf(maxItemsFail, name, in, max)
|
||||
func TooManyItems(name, in string, maximum int64, value interface{}) *Validation {
|
||||
msg := fmt.Sprintf(maximumItemsFail, name, in, maximum)
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(maxItemsFailNoIn, name, max)
|
||||
msg = fmt.Sprintf(maximumItemsFailNoIn, name, maximum)
|
||||
}
|
||||
|
||||
return &Validation{
|
||||
@@ -314,10 +318,10 @@ func TooManyItems(name, in string, max int64, value interface{}) *Validation {
|
||||
}
|
||||
|
||||
// TooFewItems error for when an array contains too few items
|
||||
func TooFewItems(name, in string, min int64, value interface{}) *Validation {
|
||||
msg := fmt.Sprintf(minItemsFail, name, in, min)
|
||||
func TooFewItems(name, in string, minimum int64, value interface{}) *Validation {
|
||||
msg := fmt.Sprintf(minItemsFail, name, in, minimum)
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(minItemsFailNoIn, name, min)
|
||||
msg = fmt.Sprintf(minItemsFailNoIn, name, minimum)
|
||||
}
|
||||
return &Validation{
|
||||
code: MinItemsFailCode,
|
||||
@@ -328,21 +332,21 @@ func TooFewItems(name, in string, min int64, value interface{}) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximumInt error for when maximum validation fails
|
||||
func ExceedsMaximumInt(name, in string, max int64, exclusive bool, value interface{}) *Validation {
|
||||
// ExceedsMaximumInt error for when maximumimum validation fails
|
||||
func ExceedsMaximumInt(name, in string, maximum int64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
m := maximumIncFailNoIn
|
||||
if exclusive {
|
||||
m = maxExcFailNoIn
|
||||
m = maximumExcFailNoIn
|
||||
}
|
||||
message = fmt.Sprintf(m, name, max)
|
||||
message = fmt.Sprintf(m, name, maximum)
|
||||
} else {
|
||||
m := maxIncFail
|
||||
m := maximumIncFail
|
||||
if exclusive {
|
||||
m = maxExcFail
|
||||
m = maximumExcFail
|
||||
}
|
||||
message = fmt.Sprintf(m, name, in, max)
|
||||
message = fmt.Sprintf(m, name, in, maximum)
|
||||
}
|
||||
return &Validation{
|
||||
code: MaxFailCode,
|
||||
@@ -353,21 +357,21 @@ func ExceedsMaximumInt(name, in string, max int64, exclusive bool, value interfa
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximumUint error for when maximum validation fails
|
||||
func ExceedsMaximumUint(name, in string, max uint64, exclusive bool, value interface{}) *Validation {
|
||||
// ExceedsMaximumUint error for when maximumimum validation fails
|
||||
func ExceedsMaximumUint(name, in string, maximum uint64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
m := maximumIncFailNoIn
|
||||
if exclusive {
|
||||
m = maxExcFailNoIn
|
||||
m = maximumExcFailNoIn
|
||||
}
|
||||
message = fmt.Sprintf(m, name, max)
|
||||
message = fmt.Sprintf(m, name, maximum)
|
||||
} else {
|
||||
m := maxIncFail
|
||||
m := maximumIncFail
|
||||
if exclusive {
|
||||
m = maxExcFail
|
||||
m = maximumExcFail
|
||||
}
|
||||
message = fmt.Sprintf(m, name, in, max)
|
||||
message = fmt.Sprintf(m, name, in, maximum)
|
||||
}
|
||||
return &Validation{
|
||||
code: MaxFailCode,
|
||||
@@ -378,21 +382,21 @@ func ExceedsMaximumUint(name, in string, max uint64, exclusive bool, value inter
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximum error for when maximum validation fails
|
||||
func ExceedsMaximum(name, in string, max float64, exclusive bool, value interface{}) *Validation {
|
||||
// ExceedsMaximum error for when maximumimum validation fails
|
||||
func ExceedsMaximum(name, in string, maximum float64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
m := maximumIncFailNoIn
|
||||
if exclusive {
|
||||
m = maxExcFailNoIn
|
||||
m = maximumExcFailNoIn
|
||||
}
|
||||
message = fmt.Sprintf(m, name, max)
|
||||
message = fmt.Sprintf(m, name, maximum)
|
||||
} else {
|
||||
m := maxIncFail
|
||||
m := maximumIncFail
|
||||
if exclusive {
|
||||
m = maxExcFail
|
||||
m = maximumExcFail
|
||||
}
|
||||
message = fmt.Sprintf(m, name, in, max)
|
||||
message = fmt.Sprintf(m, name, in, maximum)
|
||||
}
|
||||
return &Validation{
|
||||
code: MaxFailCode,
|
||||
@@ -404,20 +408,20 @@ func ExceedsMaximum(name, in string, max float64, exclusive bool, value interfac
|
||||
}
|
||||
|
||||
// ExceedsMinimumInt error for when minimum validation fails
|
||||
func ExceedsMinimumInt(name, in string, min int64, exclusive bool, value interface{}) *Validation {
|
||||
func ExceedsMinimumInt(name, in string, minimum int64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
if exclusive {
|
||||
m = minExcFailNoIn
|
||||
}
|
||||
message = fmt.Sprintf(m, name, min)
|
||||
message = fmt.Sprintf(m, name, minimum)
|
||||
} else {
|
||||
m := minIncFail
|
||||
if exclusive {
|
||||
m = minExcFail
|
||||
}
|
||||
message = fmt.Sprintf(m, name, in, min)
|
||||
message = fmt.Sprintf(m, name, in, minimum)
|
||||
}
|
||||
return &Validation{
|
||||
code: MinFailCode,
|
||||
@@ -429,20 +433,20 @@ func ExceedsMinimumInt(name, in string, min int64, exclusive bool, value interfa
|
||||
}
|
||||
|
||||
// ExceedsMinimumUint error for when minimum validation fails
|
||||
func ExceedsMinimumUint(name, in string, min uint64, exclusive bool, value interface{}) *Validation {
|
||||
func ExceedsMinimumUint(name, in string, minimum uint64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
if exclusive {
|
||||
m = minExcFailNoIn
|
||||
}
|
||||
message = fmt.Sprintf(m, name, min)
|
||||
message = fmt.Sprintf(m, name, minimum)
|
||||
} else {
|
||||
m := minIncFail
|
||||
if exclusive {
|
||||
m = minExcFail
|
||||
}
|
||||
message = fmt.Sprintf(m, name, in, min)
|
||||
message = fmt.Sprintf(m, name, in, minimum)
|
||||
}
|
||||
return &Validation{
|
||||
code: MinFailCode,
|
||||
@@ -454,20 +458,20 @@ func ExceedsMinimumUint(name, in string, min uint64, exclusive bool, value inter
|
||||
}
|
||||
|
||||
// ExceedsMinimum error for when minimum validation fails
|
||||
func ExceedsMinimum(name, in string, min float64, exclusive bool, value interface{}) *Validation {
|
||||
func ExceedsMinimum(name, in string, minimum float64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
if exclusive {
|
||||
m = minExcFailNoIn
|
||||
}
|
||||
message = fmt.Sprintf(m, name, min)
|
||||
message = fmt.Sprintf(m, name, minimum)
|
||||
} else {
|
||||
m := minIncFail
|
||||
if exclusive {
|
||||
m = minExcFail
|
||||
}
|
||||
message = fmt.Sprintf(m, name, in, min)
|
||||
message = fmt.Sprintf(m, name, in, minimum)
|
||||
}
|
||||
return &Validation{
|
||||
code: MinFailCode,
|
||||
@@ -549,12 +553,12 @@ func ReadOnly(name, in string, value interface{}) *Validation {
|
||||
}
|
||||
|
||||
// TooLong error for when a string is too long
|
||||
func TooLong(name, in string, max int64, value interface{}) *Validation {
|
||||
func TooLong(name, in string, maximum int64, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(tooLongMessageNoIn, name, max)
|
||||
msg = fmt.Sprintf(tooLongMessageNoIn, name, maximum)
|
||||
} else {
|
||||
msg = fmt.Sprintf(tooLongMessage, name, in, max)
|
||||
msg = fmt.Sprintf(tooLongMessage, name, in, maximum)
|
||||
}
|
||||
return &Validation{
|
||||
code: TooLongFailCode,
|
||||
@@ -566,12 +570,12 @@ func TooLong(name, in string, max int64, value interface{}) *Validation {
|
||||
}
|
||||
|
||||
// TooShort error for when a string is too short
|
||||
func TooShort(name, in string, min int64, value interface{}) *Validation {
|
||||
func TooShort(name, in string, minimum int64, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(tooShortMessageNoIn, name, min)
|
||||
msg = fmt.Sprintf(tooShortMessageNoIn, name, minimum)
|
||||
} else {
|
||||
msg = fmt.Sprintf(tooShortMessage, name, in, min)
|
||||
msg = fmt.Sprintf(tooShortMessage, name, in, minimum)
|
||||
}
|
||||
|
||||
return &Validation{
|
||||
|
||||
+70
-56
@@ -1,61 +1,75 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- maligned
|
||||
- unparam
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- nlreturn
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- wsl_v5
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text.
|
||||
# Set to 0 to disable.
|
||||
# Default: 3
|
||||
max-same-issues: 0
|
||||
|
||||
+8
-1
@@ -13,7 +13,14 @@ Completed YES
|
||||
Tested YES
|
||||
|
||||
## References
|
||||
http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
|
||||
|
||||
<https://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07>
|
||||
|
||||
also known as [RFC6901](https://www.rfc-editor.org/rfc/rfc6901)
|
||||
|
||||
### Note
|
||||
|
||||
The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, the reference token MUST contain either...' is not implemented.
|
||||
|
||||
That is because our implementation of the JSON pointer only supports explicit references to array elements: the provision in the spec
|
||||
to resolve non-existent members as "the last element in the array", using the special trailing character "-".
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package jsonpointer
|
||||
|
||||
type pointerError string
|
||||
|
||||
func (e pointerError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
const (
|
||||
// ErrPointer is an error raised by the jsonpointer package
|
||||
ErrPointer pointerError = "JSON pointer error"
|
||||
|
||||
// ErrInvalidStart states that a JSON pointer must start with a separator ("/")
|
||||
ErrInvalidStart pointerError = `JSON pointer must be empty or start with a "` + pointerSeparator
|
||||
|
||||
// ErrUnsupportedValueType indicates that a value of the wrong type is being set
|
||||
ErrUnsupportedValueType pointerError = "only structs, pointers, maps and slices are supported for setting values"
|
||||
)
|
||||
+307
-303
@@ -33,19 +33,18 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonname"
|
||||
)
|
||||
|
||||
const (
|
||||
emptyPointer = ``
|
||||
pointerSeparator = `/`
|
||||
|
||||
invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator
|
||||
notFound = `Can't find the pointer in the document`
|
||||
)
|
||||
|
||||
var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem()
|
||||
var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem()
|
||||
var (
|
||||
jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem()
|
||||
jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem()
|
||||
)
|
||||
|
||||
// JSONPointable is an interface for structs to implement when they need to customize the
|
||||
// json pointer process
|
||||
@@ -59,303 +58,30 @@ type JSONSetable interface {
|
||||
JSONSet(string, any) error
|
||||
}
|
||||
|
||||
// New creates a new json pointer for the given string
|
||||
func New(jsonPointerString string) (Pointer, error) {
|
||||
|
||||
var p Pointer
|
||||
err := p.parse(jsonPointerString)
|
||||
return p, err
|
||||
|
||||
}
|
||||
|
||||
// Pointer the json pointer reprsentation
|
||||
// Pointer is a representation of a json pointer
|
||||
type Pointer struct {
|
||||
referenceTokens []string
|
||||
}
|
||||
|
||||
// "Constructor", parses the given string JSON pointer
|
||||
func (p *Pointer) parse(jsonPointerString string) error {
|
||||
// New creates a new json pointer for the given string
|
||||
func New(jsonPointerString string) (Pointer, error) {
|
||||
var p Pointer
|
||||
err := p.parse(jsonPointerString)
|
||||
|
||||
var err error
|
||||
|
||||
if jsonPointerString != emptyPointer {
|
||||
if !strings.HasPrefix(jsonPointerString, pointerSeparator) {
|
||||
err = errors.New(invalidStart)
|
||||
} else {
|
||||
referenceTokens := strings.Split(jsonPointerString, pointerSeparator)
|
||||
p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
return p, err
|
||||
}
|
||||
|
||||
// Get uses the pointer to retrieve a value from a JSON document
|
||||
func (p *Pointer) Get(document any) (any, reflect.Kind, error) {
|
||||
return p.get(document, swag.DefaultJSONNameProvider)
|
||||
return p.get(document, jsonname.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// Set uses the pointer to set a value from a JSON document
|
||||
func (p *Pointer) Set(document any, value any) (any, error) {
|
||||
return document, p.set(document, value, swag.DefaultJSONNameProvider)
|
||||
return document, p.set(document, value, jsonname.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// GetForToken gets a value for a json pointer token 1 level deep
|
||||
func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) {
|
||||
return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// SetForToken gets a value for a json pointer token 1 level deep
|
||||
func SetForToken(document any, decodedToken string, value any) (any, error) {
|
||||
return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
func isNil(input any) bool {
|
||||
if input == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
kind := reflect.TypeOf(input).Kind()
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:
|
||||
return reflect.ValueOf(input).IsNil()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
kind := rValue.Kind()
|
||||
if isNil(node) {
|
||||
return nil, kind, fmt.Errorf("nil value has not field %q", decodedToken)
|
||||
}
|
||||
|
||||
switch typed := node.(type) {
|
||||
case JSONPointable:
|
||||
r, err := typed.JSONLookup(decodedToken)
|
||||
if err != nil {
|
||||
return nil, kind, err
|
||||
}
|
||||
return r, kind, nil
|
||||
case *any: // case of a pointer to interface, that is not resolved by reflect.Indirect
|
||||
return getSingleImpl(*typed, decodedToken, nameProvider)
|
||||
}
|
||||
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return nil, kind, fmt.Errorf("object has no field %q", decodedToken)
|
||||
}
|
||||
fld := rValue.FieldByName(nm)
|
||||
return fld.Interface(), kind, nil
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
mv := rValue.MapIndex(kv)
|
||||
|
||||
if mv.IsValid() {
|
||||
return mv.Interface(), kind, nil
|
||||
}
|
||||
return nil, kind, fmt.Errorf("object has no key %q", decodedToken)
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return nil, kind, err
|
||||
}
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return nil, kind, fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength-1, tokenIndex)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
return elem.Interface(), kind, nil
|
||||
|
||||
default:
|
||||
return nil, kind, fmt.Errorf("invalid token reference %q", decodedToken)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error {
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
|
||||
if ns, ok := node.(JSONSetable); ok { // pointer impl
|
||||
return ns.JSONSet(decodedToken, data)
|
||||
}
|
||||
|
||||
if rValue.Type().Implements(jsonSetableType) {
|
||||
return node.(JSONSetable).JSONSet(decodedToken, data)
|
||||
}
|
||||
|
||||
switch rValue.Kind() { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return fmt.Errorf("object has no field %q", decodedToken)
|
||||
}
|
||||
fld := rValue.FieldByName(nm)
|
||||
if fld.IsValid() {
|
||||
fld.Set(reflect.ValueOf(data))
|
||||
}
|
||||
return nil
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
rValue.SetMapIndex(kv, reflect.ValueOf(data))
|
||||
return nil
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength, tokenIndex)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
if !elem.CanSet() {
|
||||
return fmt.Errorf("can't set slice index %s to %v", decodedToken, data)
|
||||
}
|
||||
elem.Set(reflect.ValueOf(data))
|
||||
return nil
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid token reference %q", decodedToken)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {
|
||||
|
||||
if nameProvider == nil {
|
||||
nameProvider = swag.DefaultJSONNameProvider
|
||||
}
|
||||
|
||||
kind := reflect.Invalid
|
||||
|
||||
// Full document when empty
|
||||
if len(p.referenceTokens) == 0 {
|
||||
return node, kind, nil
|
||||
}
|
||||
|
||||
for _, token := range p.referenceTokens {
|
||||
|
||||
decodedToken := Unescape(token)
|
||||
|
||||
r, knd, err := getSingleImpl(node, decodedToken, nameProvider)
|
||||
if err != nil {
|
||||
return nil, knd, err
|
||||
}
|
||||
node = r
|
||||
}
|
||||
|
||||
rValue := reflect.ValueOf(node)
|
||||
kind = rValue.Kind()
|
||||
|
||||
return node, kind, nil
|
||||
}
|
||||
|
||||
func (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error {
|
||||
knd := reflect.ValueOf(node).Kind()
|
||||
|
||||
if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array {
|
||||
return errors.New("only structs, pointers, maps and slices are supported for setting values")
|
||||
}
|
||||
|
||||
if nameProvider == nil {
|
||||
nameProvider = swag.DefaultJSONNameProvider
|
||||
}
|
||||
|
||||
// Full document when empty
|
||||
if len(p.referenceTokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
lastI := len(p.referenceTokens) - 1
|
||||
for i, token := range p.referenceTokens {
|
||||
isLastToken := i == lastI
|
||||
decodedToken := Unescape(token)
|
||||
|
||||
if isLastToken {
|
||||
|
||||
return setSingleImpl(node, data, decodedToken, nameProvider)
|
||||
}
|
||||
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
kind := rValue.Kind()
|
||||
|
||||
if rValue.Type().Implements(jsonPointableType) {
|
||||
r, err := node.(JSONPointable).JSONLookup(decodedToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fld := reflect.ValueOf(r)
|
||||
if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr {
|
||||
node = fld.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = r
|
||||
continue
|
||||
}
|
||||
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return fmt.Errorf("object has no field %q", decodedToken)
|
||||
}
|
||||
fld := rValue.FieldByName(nm)
|
||||
if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr {
|
||||
node = fld.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = fld.Interface()
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
mv := rValue.MapIndex(kv)
|
||||
|
||||
if !mv.IsValid() {
|
||||
return fmt.Errorf("object has no key %q", decodedToken)
|
||||
}
|
||||
if mv.CanAddr() && mv.Kind() != reflect.Interface && mv.Kind() != reflect.Map && mv.Kind() != reflect.Slice && mv.Kind() != reflect.Ptr {
|
||||
node = mv.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = mv.Interface()
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength, tokenIndex)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
if elem.CanAddr() && elem.Kind() != reflect.Interface && elem.Kind() != reflect.Map && elem.Kind() != reflect.Slice && elem.Kind() != reflect.Ptr {
|
||||
node = elem.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = elem.Interface()
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid token reference %q", decodedToken)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecodedTokens returns the decoded tokens
|
||||
// DecodedTokens returns the decoded tokens of this JSON pointer
|
||||
func (p *Pointer) DecodedTokens() []string {
|
||||
result := make([]string, 0, len(p.referenceTokens))
|
||||
for _, t := range p.referenceTokens {
|
||||
@@ -377,9 +103,7 @@ func (p *Pointer) String() string {
|
||||
return emptyPointer
|
||||
}
|
||||
|
||||
pointerString := pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator)
|
||||
|
||||
return pointerString
|
||||
return pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator)
|
||||
}
|
||||
|
||||
func (p *Pointer) Offset(document string) (int64, error) {
|
||||
@@ -404,15 +128,294 @@ func (p *Pointer) Offset(document string) (int64, error) {
|
||||
return 0, err
|
||||
}
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid token %#v", tk)
|
||||
return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer)
|
||||
}
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid token %#v", tk)
|
||||
return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer)
|
||||
}
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
// "Constructor", parses the given string JSON pointer
|
||||
func (p *Pointer) parse(jsonPointerString string) error {
|
||||
var err error
|
||||
|
||||
if jsonPointerString != emptyPointer {
|
||||
if !strings.HasPrefix(jsonPointerString, pointerSeparator) {
|
||||
err = errors.Join(ErrInvalidStart, ErrPointer)
|
||||
} else {
|
||||
referenceTokens := strings.Split(jsonPointerString, pointerSeparator)
|
||||
p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Pointer) get(node any, nameProvider *jsonname.NameProvider) (any, reflect.Kind, error) {
|
||||
if nameProvider == nil {
|
||||
nameProvider = jsonname.DefaultJSONNameProvider
|
||||
}
|
||||
|
||||
kind := reflect.Invalid
|
||||
|
||||
// Full document when empty
|
||||
if len(p.referenceTokens) == 0 {
|
||||
return node, kind, nil
|
||||
}
|
||||
|
||||
for _, token := range p.referenceTokens {
|
||||
decodedToken := Unescape(token)
|
||||
|
||||
r, knd, err := getSingleImpl(node, decodedToken, nameProvider)
|
||||
if err != nil {
|
||||
return nil, knd, err
|
||||
}
|
||||
node = r
|
||||
}
|
||||
|
||||
rValue := reflect.ValueOf(node)
|
||||
kind = rValue.Kind()
|
||||
|
||||
return node, kind, nil
|
||||
}
|
||||
|
||||
func (p *Pointer) set(node, data any, nameProvider *jsonname.NameProvider) error {
|
||||
knd := reflect.ValueOf(node).Kind()
|
||||
|
||||
if knd != reflect.Pointer && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array {
|
||||
return errors.Join(
|
||||
ErrUnsupportedValueType,
|
||||
ErrPointer,
|
||||
)
|
||||
}
|
||||
|
||||
if nameProvider == nil {
|
||||
nameProvider = jsonname.DefaultJSONNameProvider
|
||||
}
|
||||
|
||||
// Full document when empty
|
||||
if len(p.referenceTokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
lastI := len(p.referenceTokens) - 1
|
||||
for i, token := range p.referenceTokens {
|
||||
isLastToken := i == lastI
|
||||
decodedToken := Unescape(token)
|
||||
|
||||
if isLastToken {
|
||||
|
||||
return setSingleImpl(node, data, decodedToken, nameProvider)
|
||||
}
|
||||
|
||||
// Check for nil during traversal
|
||||
if isNil(node) {
|
||||
return fmt.Errorf("cannot traverse through nil value at %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
kind := rValue.Kind()
|
||||
|
||||
if rValue.Type().Implements(jsonPointableType) {
|
||||
r, err := node.(JSONPointable).JSONLookup(decodedToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fld := reflect.ValueOf(r)
|
||||
if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Pointer {
|
||||
node = fld.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = r
|
||||
continue
|
||||
}
|
||||
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
fld := rValue.FieldByName(nm)
|
||||
if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Pointer {
|
||||
node = fld.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = fld.Interface()
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
mv := rValue.MapIndex(kv)
|
||||
|
||||
if !mv.IsValid() {
|
||||
return fmt.Errorf("object has no key %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
if mv.CanAddr() && mv.Kind() != reflect.Interface && mv.Kind() != reflect.Map && mv.Kind() != reflect.Slice && mv.Kind() != reflect.Pointer {
|
||||
node = mv.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = mv.Interface()
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength, tokenIndex, ErrPointer)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
if elem.CanAddr() && elem.Kind() != reflect.Interface && elem.Kind() != reflect.Map && elem.Kind() != reflect.Slice && elem.Kind() != reflect.Pointer {
|
||||
node = elem.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = elem.Interface()
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isNil(input any) bool {
|
||||
if input == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
kind := reflect.TypeOf(input).Kind()
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Pointer, reflect.Map, reflect.Slice, reflect.Chan:
|
||||
return reflect.ValueOf(input).IsNil()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// GetForToken gets a value for a json pointer token 1 level deep
|
||||
func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) {
|
||||
return getSingleImpl(document, decodedToken, jsonname.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// SetForToken gets a value for a json pointer token 1 level deep
|
||||
func SetForToken(document any, decodedToken string, value any) (any, error) {
|
||||
return document, setSingleImpl(document, value, decodedToken, jsonname.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NameProvider) (any, reflect.Kind, error) {
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
kind := rValue.Kind()
|
||||
if isNil(node) {
|
||||
return nil, kind, fmt.Errorf("nil value has no field %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
switch typed := node.(type) {
|
||||
case JSONPointable:
|
||||
r, err := typed.JSONLookup(decodedToken)
|
||||
if err != nil {
|
||||
return nil, kind, err
|
||||
}
|
||||
return r, kind, nil
|
||||
case *any: // case of a pointer to interface, that is not resolved by reflect.Indirect
|
||||
return getSingleImpl(*typed, decodedToken, nameProvider)
|
||||
}
|
||||
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return nil, kind, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
fld := rValue.FieldByName(nm)
|
||||
return fld.Interface(), kind, nil
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
mv := rValue.MapIndex(kv)
|
||||
|
||||
if mv.IsValid() {
|
||||
return mv.Interface(), kind, nil
|
||||
}
|
||||
return nil, kind, fmt.Errorf("object has no key %q: %w", decodedToken, ErrPointer)
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return nil, kind, err
|
||||
}
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return nil, kind, fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength-1, tokenIndex, ErrPointer)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
return elem.Interface(), kind, nil
|
||||
|
||||
default:
|
||||
return nil, kind, fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
}
|
||||
|
||||
func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.NameProvider) error {
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
|
||||
// Check for nil to prevent panic when calling rValue.Type()
|
||||
if isNil(node) {
|
||||
return fmt.Errorf("cannot set field %q on nil value: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
if ns, ok := node.(JSONSetable); ok { // pointer impl
|
||||
return ns.JSONSet(decodedToken, data)
|
||||
}
|
||||
|
||||
if rValue.Type().Implements(jsonSetableType) {
|
||||
return node.(JSONSetable).JSONSet(decodedToken, data)
|
||||
}
|
||||
|
||||
switch rValue.Kind() { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
fld := rValue.FieldByName(nm)
|
||||
if fld.IsValid() {
|
||||
fld.Set(reflect.ValueOf(data))
|
||||
}
|
||||
return nil
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
rValue.SetMapIndex(kv, reflect.ValueOf(data))
|
||||
return nil
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength, tokenIndex, ErrPointer)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
if !elem.CanSet() {
|
||||
return fmt.Errorf("can't set slice index %s to %v: %w", decodedToken, data, ErrPointer)
|
||||
}
|
||||
elem.Set(reflect.ValueOf(data))
|
||||
return nil
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
}
|
||||
|
||||
func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
for dec.More() {
|
||||
offset := dec.InputOffset()
|
||||
@@ -437,16 +440,16 @@ func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
return offset, nil
|
||||
}
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid token %#v", tk)
|
||||
return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer)
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("token reference %q not found", decodedToken)
|
||||
return 0, fmt.Errorf("token reference %q not found: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
idx, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("token reference %q is not a number: %v", decodedToken, err)
|
||||
return 0, fmt.Errorf("token reference %q is not a number: %v: %w", decodedToken, err, ErrPointer)
|
||||
}
|
||||
var i int
|
||||
for i = 0; i < idx && dec.More(); i++ {
|
||||
@@ -470,7 +473,7 @@ func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
}
|
||||
|
||||
if !dec.More() {
|
||||
return 0, fmt.Errorf("token reference %q not found", decodedToken)
|
||||
return 0, fmt.Errorf("token reference %q not found: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
return dec.InputOffset(), nil
|
||||
}
|
||||
@@ -516,16 +519,17 @@ const (
|
||||
decRefTok1 = `/`
|
||||
)
|
||||
|
||||
var (
|
||||
encRefTokReplacer = strings.NewReplacer(encRefTok1, decRefTok1, encRefTok0, decRefTok0)
|
||||
decRefTokReplacer = strings.NewReplacer(decRefTok1, encRefTok1, decRefTok0, encRefTok0)
|
||||
)
|
||||
|
||||
// Unescape unescapes a json pointer reference token string to the original representation
|
||||
func Unescape(token string) string {
|
||||
step1 := strings.ReplaceAll(token, encRefTok1, decRefTok1)
|
||||
step2 := strings.ReplaceAll(step1, encRefTok0, decRefTok0)
|
||||
return step2
|
||||
return encRefTokReplacer.Replace(token)
|
||||
}
|
||||
|
||||
// Escape escapes a pointer reference token string
|
||||
func Escape(token string) string {
|
||||
step1 := strings.ReplaceAll(token, decRefTok0, encRefTok0)
|
||||
step2 := strings.ReplaceAll(step1, decRefTok1, encRefTok1)
|
||||
return step2
|
||||
return decRefTokReplacer.Replace(token)
|
||||
}
|
||||
|
||||
+70
-56
@@ -1,61 +1,75 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- maligned
|
||||
- unparam
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- nlreturn
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- wsl_v5
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text.
|
||||
# Set to 0 to disable.
|
||||
# Default: 3
|
||||
max-same-issues: 0
|
||||
|
||||
+38
-39
@@ -38,24 +38,7 @@ const (
|
||||
fragmentRune = `#`
|
||||
)
|
||||
|
||||
// New creates a new reference for the given string
|
||||
func New(jsonReferenceString string) (Ref, error) {
|
||||
|
||||
var r Ref
|
||||
err := r.parse(jsonReferenceString)
|
||||
return r, err
|
||||
|
||||
}
|
||||
|
||||
// MustCreateRef parses the ref string and panics when it's invalid.
|
||||
// Use the New method for a version that returns an error
|
||||
func MustCreateRef(ref string) Ref {
|
||||
r, err := New(ref)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
var ErrChildURL = errors.New("child url is nil")
|
||||
|
||||
// Ref represents a json reference object
|
||||
type Ref struct {
|
||||
@@ -69,6 +52,24 @@ type Ref struct {
|
||||
HasFullFilePath bool
|
||||
}
|
||||
|
||||
// New creates a new reference for the given string
|
||||
func New(jsonReferenceString string) (Ref, error) {
|
||||
var r Ref
|
||||
err := r.parse(jsonReferenceString)
|
||||
return r, err
|
||||
}
|
||||
|
||||
// MustCreateRef parses the ref string and panics when it's invalid.
|
||||
// Use the New method for a version that returns an error
|
||||
func MustCreateRef(ref string) Ref {
|
||||
r, err := New(ref)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// GetURL gets the URL for this reference
|
||||
func (r *Ref) GetURL() *url.URL {
|
||||
return r.referenceURL
|
||||
@@ -81,7 +82,6 @@ func (r *Ref) GetPointer() *jsonpointer.Pointer {
|
||||
|
||||
// String returns the best version of the url for this reference
|
||||
func (r *Ref) String() string {
|
||||
|
||||
if r.referenceURL != nil {
|
||||
return r.referenceURL.String()
|
||||
}
|
||||
@@ -106,9 +106,27 @@ func (r *Ref) IsCanonical() bool {
|
||||
return (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullURL)
|
||||
}
|
||||
|
||||
// Inherits creates a new reference from a parent and a child
|
||||
// If the child cannot inherit from the parent, an error is returned
|
||||
func (r *Ref) Inherits(child Ref) (*Ref, error) {
|
||||
childURL := child.GetURL()
|
||||
parentURL := r.GetURL()
|
||||
if childURL == nil {
|
||||
return nil, ErrChildURL
|
||||
}
|
||||
if parentURL == nil {
|
||||
return &child, nil
|
||||
}
|
||||
|
||||
ref, err := New(parentURL.ResolveReference(childURL).String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ref, nil
|
||||
}
|
||||
|
||||
// "Constructor", parses the given string JSON reference
|
||||
func (r *Ref) parse(jsonReferenceString string) error {
|
||||
|
||||
parsed, err := url.Parse(jsonReferenceString)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -137,22 +155,3 @@ func (r *Ref) parse(jsonReferenceString string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Inherits creates a new reference from a parent and a child
|
||||
// If the child cannot inherit from the parent, an error is returned
|
||||
func (r *Ref) Inherits(child Ref) (*Ref, error) {
|
||||
childURL := child.GetURL()
|
||||
parentURL := r.GetURL()
|
||||
if childURL == nil {
|
||||
return nil, errors.New("child url is nil")
|
||||
}
|
||||
if parentURL == nil {
|
||||
return &child, nil
|
||||
}
|
||||
|
||||
ref, err := New(parentURL.ResolveReference(childURL).String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ref, nil
|
||||
}
|
||||
|
||||
+70
-56
@@ -1,61 +1,75 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- maligned
|
||||
- unparam
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- nlreturn
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- wsl_v5
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text.
|
||||
# Set to 0 to disable.
|
||||
# Default: 3
|
||||
max-same-issues: 0
|
||||
|
||||
+23
-1
@@ -3,4 +3,26 @@
|
||||
[](https://raw.githubusercontent.com/go-openapi/loads/master/LICENSE) [](http://godoc.org/github.com/go-openapi/loads)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/loads)
|
||||
|
||||
Loading of OAI specification documents from local or remote locations. Supports JSON and YAML documents.
|
||||
Loading of OAI v2 API specification documents from local or remote locations. Supports JSON and YAML documents.
|
||||
|
||||
Primary usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/go-openapi/loads"
|
||||
)
|
||||
|
||||
...
|
||||
|
||||
// loads a YAML spec from a http file
|
||||
doc, err := loads.Spec(ts.URL)
|
||||
|
||||
...
|
||||
|
||||
// retrieves the object model for the API specification
|
||||
spec := doc.Spec()
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
See also the provided [examples](https://pkg.go.dev/github.com/go-openapi/loads#pkg-examples).
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package loads provides document loading methods for swagger (OAI) specifications.
|
||||
// Package loads provides document loading methods for swagger (OAI v2) API specifications.
|
||||
//
|
||||
// It is used by other go-openapi packages to load and run analysis on local or remote spec documents.
|
||||
package loads
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package loads
|
||||
|
||||
type loaderError string
|
||||
|
||||
func (e loaderError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
const (
|
||||
// ErrLoads is an error returned by the loads package
|
||||
ErrLoads loaderError = "loaderrs error"
|
||||
|
||||
// ErrNoLoader indicates that no configured loader matched the input
|
||||
ErrNoLoader loaderError = "no loader matched"
|
||||
)
|
||||
+31
-12
@@ -4,9 +4,10 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
"slices"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/loading"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -30,8 +31,8 @@ func init() {
|
||||
|
||||
loaders = jsonLoader.WithHead(&loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Match: swag.YAMLMatcher,
|
||||
Fn: swag.YAMLDoc,
|
||||
Match: loading.YAMLMatcher,
|
||||
Fn: loading.YAMLDoc,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -40,7 +41,7 @@ func init() {
|
||||
}
|
||||
|
||||
// DocLoader represents a doc loader type
|
||||
type DocLoader func(string) (json.RawMessage, error)
|
||||
type DocLoader func(string, ...loading.Option) (json.RawMessage, error)
|
||||
|
||||
// DocMatcher represents a predicate to check if a loader matches
|
||||
type DocMatcher func(string) bool
|
||||
@@ -61,6 +62,9 @@ func NewDocLoaderWithMatch(fn DocLoader, matcher DocMatcher) DocLoaderWithMatch
|
||||
|
||||
type loader struct {
|
||||
DocLoaderWithMatch
|
||||
|
||||
loadingOptions []loading.Option
|
||||
|
||||
Next *loader
|
||||
}
|
||||
|
||||
@@ -83,17 +87,17 @@ func (l *loader) WithNext(next *loader) *loader {
|
||||
func (l *loader) Load(path string) (json.RawMessage, error) {
|
||||
_, erp := url.Parse(path)
|
||||
if erp != nil {
|
||||
return nil, erp
|
||||
return nil, errors.Join(erp, ErrLoads)
|
||||
}
|
||||
|
||||
lastErr := errors.New("no loader matched") // default error if no match was found
|
||||
var lastErr error = ErrNoLoader // default error if no match was found
|
||||
for ldr := l; ldr != nil; ldr = ldr.Next {
|
||||
if ldr.Match != nil && !ldr.Match(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
// try then move to next one if there is an error
|
||||
b, err := ldr.Fn(path)
|
||||
b, err := ldr.Fn(path, l.loadingOptions...)
|
||||
if err == nil {
|
||||
return b, nil
|
||||
}
|
||||
@@ -101,14 +105,29 @@ func (l *loader) Load(path string) (json.RawMessage, error) {
|
||||
lastErr = err
|
||||
}
|
||||
|
||||
return nil, lastErr
|
||||
return nil, errors.Join(lastErr, ErrLoads)
|
||||
}
|
||||
|
||||
// JSONDoc loads a json document from either a file or a remote url
|
||||
func JSONDoc(path string) (json.RawMessage, error) {
|
||||
data, err := swag.LoadFromFileOrHTTP(path)
|
||||
func (l *loader) clone() *loader {
|
||||
if l == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &loader{
|
||||
DocLoaderWithMatch: l.DocLoaderWithMatch,
|
||||
loadingOptions: slices.Clone(l.loadingOptions),
|
||||
Next: l.Next.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
// JSONDoc loads a json document from either a file or a remote url.
|
||||
//
|
||||
// See [loading.Option] for available options (e.g. configuring authentifaction,
|
||||
// headers or using embedded file system resources).
|
||||
func JSONDoc(path string, opts ...loading.Option) (json.RawMessage, error) {
|
||||
data, err := loading.LoadFromFileOrHTTP(path, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Join(err, ErrLoads)
|
||||
}
|
||||
return json.RawMessage(data), nil
|
||||
}
|
||||
|
||||
+15
-2
@@ -1,7 +1,10 @@
|
||||
package loads
|
||||
|
||||
import "github.com/go-openapi/swag/loading"
|
||||
|
||||
type options struct {
|
||||
loader *loader
|
||||
loader *loader
|
||||
loadingOptions []loading.Option
|
||||
}
|
||||
|
||||
func defaultOptions() *options {
|
||||
@@ -16,7 +19,10 @@ func loaderFromOptions(options []LoaderOption) *loader {
|
||||
apply(opts)
|
||||
}
|
||||
|
||||
return opts.loader
|
||||
l := opts.loader.clone()
|
||||
l.loadingOptions = opts.loadingOptions
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// LoaderOption allows to fine-tune the spec loader behavior
|
||||
@@ -59,3 +65,10 @@ func WithDocLoaderMatches(l ...DocLoaderWithMatch) LoaderOption {
|
||||
opt.loader = final
|
||||
}
|
||||
}
|
||||
|
||||
// WithLoadingOptions adds some [loading.Option] to be added when calling a registered loader.
|
||||
func WithLoadingOptions(loadingOptions ...loading.Option) LoaderOption {
|
||||
return func(opt *options) {
|
||||
opt.loadingOptions = loadingOptions
|
||||
}
|
||||
}
|
||||
|
||||
+43
-31
@@ -18,16 +18,18 @@ import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/yamlutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
gob.Register(map[string]interface{}{})
|
||||
gob.Register([]interface{}{})
|
||||
gob.Register(map[string]any{})
|
||||
gob.Register([]any{})
|
||||
}
|
||||
|
||||
// Document represents a swagger spec document
|
||||
@@ -42,14 +44,21 @@ type Document struct {
|
||||
raw json.RawMessage
|
||||
}
|
||||
|
||||
// JSONSpec loads a spec from a json document
|
||||
func JSONSpec(path string, options ...LoaderOption) (*Document, error) {
|
||||
data, err := JSONDoc(path)
|
||||
// JSONSpec loads a spec from a json document, using the [JSONDoc] loader.
|
||||
//
|
||||
// A set of [loading.Option] may be passed to this loader using [WithLoadingOptions].
|
||||
func JSONSpec(path string, opts ...LoaderOption) (*Document, error) {
|
||||
var o options
|
||||
for _, apply := range opts {
|
||||
apply(&o)
|
||||
}
|
||||
|
||||
data, err := JSONDoc(path, o.loadingOptions...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// convert to json
|
||||
doc, err := Analyzed(data, "", options...)
|
||||
doc, err := Analyzed(data, "", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -59,8 +68,8 @@ func JSONSpec(path string, options ...LoaderOption) (*Document, error) {
|
||||
return doc, nil
|
||||
}
|
||||
|
||||
// Embedded returns a Document based on embedded specs. No analysis is required
|
||||
func Embedded(orig, flat json.RawMessage, options ...LoaderOption) (*Document, error) {
|
||||
// Embedded returns a Document based on embedded specs (i.e. as a raw [json.RawMessage]). No analysis is required
|
||||
func Embedded(orig, flat json.RawMessage, opts ...LoaderOption) (*Document, error) {
|
||||
var origSpec, flatSpec spec.Swagger
|
||||
if err := json.Unmarshal(orig, &origSpec); err != nil {
|
||||
return nil, err
|
||||
@@ -72,20 +81,22 @@ func Embedded(orig, flat json.RawMessage, options ...LoaderOption) (*Document, e
|
||||
raw: orig,
|
||||
origSpec: &origSpec,
|
||||
spec: &flatSpec,
|
||||
pathLoader: loaderFromOptions(options),
|
||||
pathLoader: loaderFromOptions(opts),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Spec loads a new spec document from a local or remote path
|
||||
func Spec(path string, options ...LoaderOption) (*Document, error) {
|
||||
ldr := loaderFromOptions(options)
|
||||
// Spec loads a new spec document from a local or remote path.
|
||||
//
|
||||
// By default it uses a JSON or YAML loader, with auto-detection based on the resource extension.
|
||||
func Spec(path string, opts ...LoaderOption) (*Document, error) {
|
||||
ldr := loaderFromOptions(opts)
|
||||
|
||||
b, err := ldr.Load(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
document, err := Analyzed(b, "", options...)
|
||||
document, err := Analyzed(b, "", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -102,7 +113,7 @@ func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*D
|
||||
version = "2.0"
|
||||
}
|
||||
if version != "2.0" {
|
||||
return nil, fmt.Errorf("spec version %q is not supported", version)
|
||||
return nil, fmt.Errorf("spec version %q is not supported: %w", version, ErrLoads)
|
||||
}
|
||||
|
||||
raw, err := trimData(data) // trim blanks, then convert yaml docs into json
|
||||
@@ -112,12 +123,12 @@ func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*D
|
||||
|
||||
swspec := new(spec.Swagger)
|
||||
if err = json.Unmarshal(raw, swspec); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Join(err, ErrLoads)
|
||||
}
|
||||
|
||||
origsqspec, err := cloneSpec(swspec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Join(err, ErrLoads)
|
||||
}
|
||||
|
||||
d := &Document{
|
||||
@@ -143,20 +154,20 @@ func trimData(in json.RawMessage) (json.RawMessage, error) {
|
||||
}
|
||||
|
||||
// assume yaml doc: convert it to json
|
||||
yml, err := swag.BytesToYAMLDoc(trimmed)
|
||||
yml, err := yamlutils.BytesToYAMLDoc(trimmed)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
return nil, fmt.Errorf("analyzed: %v: %w", err, ErrLoads)
|
||||
}
|
||||
|
||||
d, err := swag.YAMLToJSON(yml)
|
||||
d, err := yamlutils.YAMLToJSON(yml)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
return nil, fmt.Errorf("analyzed: %v: %w", err, ErrLoads)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Expanded expands the $ref fields in the spec document and returns a new spec document
|
||||
// Expanded expands the $ref fields in the spec [Document] and returns a new expanded [Document]
|
||||
func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
|
||||
swspec := new(spec.Swagger)
|
||||
if err := json.Unmarshal(d.raw, swspec); err != nil {
|
||||
@@ -202,20 +213,23 @@ func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
|
||||
|
||||
// BasePath the base path for the API specified by this spec
|
||||
func (d *Document) BasePath() string {
|
||||
if d.spec == nil {
|
||||
return ""
|
||||
}
|
||||
return d.spec.BasePath
|
||||
}
|
||||
|
||||
// Version returns the version of this spec
|
||||
// Version returns the OpenAPI version of this spec (e.g. 2.0)
|
||||
func (d *Document) Version() string {
|
||||
return d.spec.Swagger
|
||||
}
|
||||
|
||||
// Schema returns the swagger 2.0 schema
|
||||
// Schema returns the swagger 2.0 meta-schema
|
||||
func (d *Document) Schema() *spec.Schema {
|
||||
return d.schema
|
||||
}
|
||||
|
||||
// Spec returns the swagger spec object model
|
||||
// Spec returns the swagger object model for this API specification
|
||||
func (d *Document) Spec() *spec.Swagger {
|
||||
return d.spec
|
||||
}
|
||||
@@ -235,14 +249,11 @@ func (d *Document) OrigSpec() *spec.Swagger {
|
||||
return d.origSpec
|
||||
}
|
||||
|
||||
// ResetDefinitions gives a shallow copy with the models reset to the original spec
|
||||
// ResetDefinitions yields a shallow copy with the models reset to the original spec
|
||||
func (d *Document) ResetDefinitions() *Document {
|
||||
defs := make(map[string]spec.Schema, len(d.origSpec.Definitions))
|
||||
for k, v := range d.origSpec.Definitions {
|
||||
defs[k] = v
|
||||
}
|
||||
d.spec.Definitions = make(map[string]spec.Schema, len(d.origSpec.Definitions))
|
||||
maps.Copy(d.spec.Definitions, d.origSpec.Definitions)
|
||||
|
||||
d.spec.Definitions = defs
|
||||
return d
|
||||
}
|
||||
|
||||
@@ -271,5 +282,6 @@ func cloneSpec(src *spec.Swagger) (*spec.Swagger, error) {
|
||||
if err := gob.NewDecoder(&b).Decode(&dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &dst, nil
|
||||
}
|
||||
|
||||
+70
-56
@@ -1,61 +1,75 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- maligned
|
||||
- unparam
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- nlreturn
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- wsl_v5
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text.
|
||||
# Set to 0 to disable.
|
||||
# Default: 3
|
||||
max-same-issues: 0
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ package spec
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// ContactInfo contact information for the exposed API.
|
||||
@@ -53,5 +53,5 @@ func (c ContactInfo) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
return jsonutils.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
+3
@@ -16,4 +16,7 @@ var (
|
||||
|
||||
// ErrExpandUnsupportedType indicates that $ref expansion is attempted on some invalid type
|
||||
ErrExpandUnsupportedType = errors.New("expand: unsupported type. Input should be of type *Parameter or *Response")
|
||||
|
||||
// ErrSpec is an error raised by the spec package
|
||||
ErrSpec = errors.New("spec error")
|
||||
)
|
||||
|
||||
+6
-4
@@ -19,6 +19,8 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const smallPrealloc = 10
|
||||
|
||||
// ExpandOptions provides options for the spec expander.
|
||||
//
|
||||
// RelativeBase is the path to the root document. This can be a remote URL or a path to a local file.
|
||||
@@ -56,7 +58,7 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
|
||||
|
||||
if !options.SkipSchemas {
|
||||
for key, definition := range spec.Definitions {
|
||||
parentRefs := make([]string, 0, 10)
|
||||
parentRefs := make([]string, 0, smallPrealloc)
|
||||
parentRefs = append(parentRefs, "#/definitions/"+key)
|
||||
|
||||
def, err := expandSchema(definition, parentRefs, resolver, specBasePath)
|
||||
@@ -160,7 +162,7 @@ func ExpandSchemaWithBasePath(schema *Schema, cache ResolutionCache, opts *Expan
|
||||
|
||||
resolver := defaultSchemaLoader(nil, opts, cache, nil)
|
||||
|
||||
parentRefs := make([]string, 0, 10)
|
||||
parentRefs := make([]string, 0, smallPrealloc)
|
||||
s, err := expandSchema(*schema, parentRefs, resolver, opts.RelativeBase)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -386,7 +388,7 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string)
|
||||
return nil
|
||||
}
|
||||
|
||||
parentRefs := make([]string, 0, 10)
|
||||
parentRefs := make([]string, 0, smallPrealloc)
|
||||
if err := resolver.deref(pathItem, parentRefs, basePath); resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
@@ -546,7 +548,7 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa
|
||||
return nil
|
||||
}
|
||||
|
||||
parentRefs := make([]string, 0, 10)
|
||||
parentRefs := make([]string, 0, smallPrealloc)
|
||||
if ref != nil {
|
||||
// dereference this $ref
|
||||
if err = resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) {
|
||||
|
||||
+10
-10
@@ -19,7 +19,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -74,14 +74,14 @@ func (h *Header) WithDefault(defaultValue interface{}) *Header {
|
||||
}
|
||||
|
||||
// WithMaxLength sets a max length value
|
||||
func (h *Header) WithMaxLength(max int64) *Header {
|
||||
h.MaxLength = &max
|
||||
func (h *Header) WithMaxLength(maximum int64) *Header {
|
||||
h.MaxLength = &maximum
|
||||
return h
|
||||
}
|
||||
|
||||
// WithMinLength sets a min length value
|
||||
func (h *Header) WithMinLength(min int64) *Header {
|
||||
h.MinLength = &min
|
||||
func (h *Header) WithMinLength(minimum int64) *Header {
|
||||
h.MinLength = &minimum
|
||||
return h
|
||||
}
|
||||
|
||||
@@ -98,15 +98,15 @@ func (h *Header) WithMultipleOf(number float64) *Header {
|
||||
}
|
||||
|
||||
// WithMaximum sets a maximum number value
|
||||
func (h *Header) WithMaximum(max float64, exclusive bool) *Header {
|
||||
h.Maximum = &max
|
||||
func (h *Header) WithMaximum(maximum float64, exclusive bool) *Header {
|
||||
h.Maximum = &maximum
|
||||
h.ExclusiveMaximum = exclusive
|
||||
return h
|
||||
}
|
||||
|
||||
// WithMinimum sets a minimum number value
|
||||
func (h *Header) WithMinimum(min float64, exclusive bool) *Header {
|
||||
h.Minimum = &min
|
||||
func (h *Header) WithMinimum(minimum float64, exclusive bool) *Header {
|
||||
h.Minimum = &minimum
|
||||
h.ExclusiveMinimum = exclusive
|
||||
return h
|
||||
}
|
||||
@@ -161,7 +161,7 @@ func (h Header) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
return jsonutils.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals this header from JSON
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// Extensions vendor specific extensions
|
||||
@@ -172,7 +172,7 @@ func (i Info) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
return jsonutils.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON marshal this from JSON
|
||||
|
||||
+10
-10
@@ -19,7 +19,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -97,14 +97,14 @@ func (i *Items) WithDefault(defaultValue interface{}) *Items {
|
||||
}
|
||||
|
||||
// WithMaxLength sets a max length value
|
||||
func (i *Items) WithMaxLength(max int64) *Items {
|
||||
i.MaxLength = &max
|
||||
func (i *Items) WithMaxLength(maximum int64) *Items {
|
||||
i.MaxLength = &maximum
|
||||
return i
|
||||
}
|
||||
|
||||
// WithMinLength sets a min length value
|
||||
func (i *Items) WithMinLength(min int64) *Items {
|
||||
i.MinLength = &min
|
||||
func (i *Items) WithMinLength(minimum int64) *Items {
|
||||
i.MinLength = &minimum
|
||||
return i
|
||||
}
|
||||
|
||||
@@ -121,15 +121,15 @@ func (i *Items) WithMultipleOf(number float64) *Items {
|
||||
}
|
||||
|
||||
// WithMaximum sets a maximum number value
|
||||
func (i *Items) WithMaximum(max float64, exclusive bool) *Items {
|
||||
i.Maximum = &max
|
||||
func (i *Items) WithMaximum(maximum float64, exclusive bool) *Items {
|
||||
i.Maximum = &maximum
|
||||
i.ExclusiveMaximum = exclusive
|
||||
return i
|
||||
}
|
||||
|
||||
// WithMinimum sets a minimum number value
|
||||
func (i *Items) WithMinimum(min float64, exclusive bool) *Items {
|
||||
i.Minimum = &min
|
||||
func (i *Items) WithMinimum(minimum float64, exclusive bool) *Items {
|
||||
i.Minimum = &minimum
|
||||
i.ExclusiveMinimum = exclusive
|
||||
return i
|
||||
}
|
||||
@@ -213,7 +213,7 @@ func (i Items) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b4, b3, b1, b2), nil
|
||||
return jsonutils.ConcatJSON(b4, b3, b1, b2), nil
|
||||
}
|
||||
|
||||
// JSONLookup look up a value by the json property name
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ package spec
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// License information for the exposed API.
|
||||
@@ -52,5 +52,5 @@ func (l License) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
return jsonutils.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
+20
-17
@@ -21,12 +21,12 @@ import (
|
||||
"sort"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
gob.Register(map[string]interface{}{})
|
||||
gob.Register([]interface{}{})
|
||||
gob.Register(map[string]any{})
|
||||
gob.Register([]any{})
|
||||
}
|
||||
|
||||
// OperationProps describes an operation
|
||||
@@ -58,19 +58,22 @@ func (op OperationProps) MarshalJSON() ([]byte, error) {
|
||||
type Alias OperationProps
|
||||
if op.Security == nil {
|
||||
return json.Marshal(&struct {
|
||||
Security []map[string][]string `json:"security,omitempty"`
|
||||
*Alias
|
||||
|
||||
Security []map[string][]string `json:"security,omitempty"`
|
||||
}{
|
||||
Security: op.Security,
|
||||
Alias: (*Alias)(&op),
|
||||
Security: op.Security,
|
||||
})
|
||||
}
|
||||
|
||||
return json.Marshal(&struct {
|
||||
Security []map[string][]string `json:"security"`
|
||||
*Alias
|
||||
|
||||
Security []map[string][]string `json:"security"`
|
||||
}{
|
||||
Security: op.Security,
|
||||
Alias: (*Alias)(&op),
|
||||
Security: op.Security,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -82,6 +85,14 @@ type Operation struct {
|
||||
OperationProps
|
||||
}
|
||||
|
||||
// NewOperation creates a new operation instance.
|
||||
// It expects an ID as parameter but not passing an ID is also valid.
|
||||
func NewOperation(id string) *Operation {
|
||||
op := new(Operation)
|
||||
op.ID = id
|
||||
return op
|
||||
}
|
||||
|
||||
// SuccessResponse gets a success response model
|
||||
func (o *Operation) SuccessResponse() (*Response, int, bool) {
|
||||
if o.Responses == nil {
|
||||
@@ -104,7 +115,7 @@ func (o *Operation) SuccessResponse() (*Response, int, bool) {
|
||||
}
|
||||
|
||||
// JSONLookup look up a value by the json property name
|
||||
func (o Operation) JSONLookup(token string) (interface{}, error) {
|
||||
func (o Operation) JSONLookup(token string) (any, error) {
|
||||
if ex, ok := o.Extensions[token]; ok {
|
||||
return &ex, nil
|
||||
}
|
||||
@@ -130,18 +141,10 @@ func (o Operation) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
concated := swag.ConcatJSON(b1, b2)
|
||||
concated := jsonutils.ConcatJSON(b1, b2)
|
||||
return concated, nil
|
||||
}
|
||||
|
||||
// NewOperation creates a new operation instance.
|
||||
// It expects an ID as parameter but not passing an ID is also valid.
|
||||
func NewOperation(id string) *Operation {
|
||||
op := new(Operation)
|
||||
op.ID = id
|
||||
return op
|
||||
}
|
||||
|
||||
// WithID sets the ID property on this operation, allows for chaining.
|
||||
func (o *Operation) WithID(id string) *Operation {
|
||||
o.ID = id
|
||||
|
||||
+10
-10
@@ -19,7 +19,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// QueryParam creates a query parameter
|
||||
@@ -210,14 +210,14 @@ func (p *Parameter) AsRequired() *Parameter {
|
||||
}
|
||||
|
||||
// WithMaxLength sets a max length value
|
||||
func (p *Parameter) WithMaxLength(max int64) *Parameter {
|
||||
p.MaxLength = &max
|
||||
func (p *Parameter) WithMaxLength(maximum int64) *Parameter {
|
||||
p.MaxLength = &maximum
|
||||
return p
|
||||
}
|
||||
|
||||
// WithMinLength sets a min length value
|
||||
func (p *Parameter) WithMinLength(min int64) *Parameter {
|
||||
p.MinLength = &min
|
||||
func (p *Parameter) WithMinLength(minimum int64) *Parameter {
|
||||
p.MinLength = &minimum
|
||||
return p
|
||||
}
|
||||
|
||||
@@ -234,15 +234,15 @@ func (p *Parameter) WithMultipleOf(number float64) *Parameter {
|
||||
}
|
||||
|
||||
// WithMaximum sets a maximum number value
|
||||
func (p *Parameter) WithMaximum(max float64, exclusive bool) *Parameter {
|
||||
p.Maximum = &max
|
||||
func (p *Parameter) WithMaximum(maximum float64, exclusive bool) *Parameter {
|
||||
p.Maximum = &maximum
|
||||
p.ExclusiveMaximum = exclusive
|
||||
return p
|
||||
}
|
||||
|
||||
// WithMinimum sets a minimum number value
|
||||
func (p *Parameter) WithMinimum(min float64, exclusive bool) *Parameter {
|
||||
p.Minimum = &min
|
||||
func (p *Parameter) WithMinimum(minimum float64, exclusive bool) *Parameter {
|
||||
p.Minimum = &minimum
|
||||
p.ExclusiveMinimum = exclusive
|
||||
return p
|
||||
}
|
||||
@@ -322,5 +322,5 @@ func (p Parameter) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b3, b1, b2, b4, b5), nil
|
||||
return jsonutils.ConcatJSON(b3, b1, b2, b4, b5), nil
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// PathItemProps the path item specific properties
|
||||
@@ -82,6 +82,6 @@ func (p PathItem) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
concated := swag.ConcatJSON(b3, b4, b5)
|
||||
concated := jsonutils.ConcatJSON(b3, b4, b5)
|
||||
return concated, nil
|
||||
}
|
||||
|
||||
+7
-6
@@ -19,7 +19,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// Paths holds the relative paths to the individual endpoints.
|
||||
@@ -30,18 +30,19 @@ import (
|
||||
// For more information: http://goo.gl/8us55a#pathsObject
|
||||
type Paths struct {
|
||||
VendorExtensible
|
||||
|
||||
Paths map[string]PathItem `json:"-"` // custom serializer to flatten this, each entry must start with "/"
|
||||
}
|
||||
|
||||
// JSONLookup look up a value by the json property name
|
||||
func (p Paths) JSONLookup(token string) (interface{}, error) {
|
||||
func (p Paths) JSONLookup(token string) (any, error) {
|
||||
if pi, ok := p.Paths[token]; ok {
|
||||
return &pi, nil
|
||||
}
|
||||
if ex, ok := p.Extensions[token]; ok {
|
||||
return &ex, nil
|
||||
}
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
return nil, fmt.Errorf("object has no field %q: %w", token, ErrSpec)
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
@@ -53,9 +54,9 @@ func (p *Paths) UnmarshalJSON(data []byte) error {
|
||||
for k, v := range res {
|
||||
if strings.HasPrefix(strings.ToLower(k), "x-") {
|
||||
if p.Extensions == nil {
|
||||
p.Extensions = make(map[string]interface{})
|
||||
p.Extensions = make(map[string]any)
|
||||
}
|
||||
var d interface{}
|
||||
var d any
|
||||
if err := json.Unmarshal(v, &d); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -92,6 +93,6 @@ func (p Paths) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
concated := swag.ConcatJSON(b1, b2)
|
||||
concated := jsonutils.ConcatJSON(b1, b2)
|
||||
return concated, nil
|
||||
}
|
||||
|
||||
+2
-1
@@ -9,8 +9,9 @@ import (
|
||||
|
||||
// OrderSchemaItem holds a named schema (e.g. from a property of an object)
|
||||
type OrderSchemaItem struct {
|
||||
Name string
|
||||
Schema
|
||||
|
||||
Name string
|
||||
}
|
||||
|
||||
// OrderSchemaItems is a sortable slice of named schemas.
|
||||
|
||||
+23
-21
@@ -45,6 +45,23 @@ type Ref struct {
|
||||
jsonreference.Ref
|
||||
}
|
||||
|
||||
// NewRef creates a new instance of a ref object
|
||||
// returns an error when the reference uri is an invalid uri
|
||||
func NewRef(refURI string) (Ref, error) {
|
||||
ref, err := jsonreference.New(refURI)
|
||||
if err != nil {
|
||||
return Ref{}, err
|
||||
}
|
||||
|
||||
return Ref{Ref: ref}, nil
|
||||
}
|
||||
|
||||
// MustCreateRef creates a ref object but panics when refURI is invalid.
|
||||
// Use the NewRef method for a version that returns an error.
|
||||
func MustCreateRef(refURI string) Ref {
|
||||
return Ref{Ref: jsonreference.MustCreateRef(refURI)}
|
||||
}
|
||||
|
||||
// RemoteURI gets the remote uri part of the ref
|
||||
func (r *Ref) RemoteURI() string {
|
||||
if r.String() == "" {
|
||||
@@ -75,10 +92,11 @@ func (r *Ref) IsValidURI(basepaths ...string) bool {
|
||||
}
|
||||
defer rr.Body.Close()
|
||||
|
||||
return rr.StatusCode/100 == 2
|
||||
// true if the response is >= 200 and < 300
|
||||
return rr.StatusCode/100 == 2 //nolint:mnd
|
||||
}
|
||||
|
||||
if !(r.HasFileScheme || r.HasFullFilePath || r.HasURLPathOnly) {
|
||||
if !r.HasFileScheme && !r.HasFullFilePath && !r.HasURLPathOnly {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -114,22 +132,6 @@ func (r *Ref) Inherits(child Ref) (*Ref, error) {
|
||||
return &Ref{Ref: *ref}, nil
|
||||
}
|
||||
|
||||
// NewRef creates a new instance of a ref object
|
||||
// returns an error when the reference uri is an invalid uri
|
||||
func NewRef(refURI string) (Ref, error) {
|
||||
ref, err := jsonreference.New(refURI)
|
||||
if err != nil {
|
||||
return Ref{}, err
|
||||
}
|
||||
return Ref{Ref: ref}, nil
|
||||
}
|
||||
|
||||
// MustCreateRef creates a ref object but panics when refURI is invalid.
|
||||
// Use the NewRef method for a version that returns an error.
|
||||
func MustCreateRef(refURI string) Ref {
|
||||
return Ref{Ref: jsonreference.MustCreateRef(refURI)}
|
||||
}
|
||||
|
||||
// MarshalJSON marshals this ref into a JSON object
|
||||
func (r Ref) MarshalJSON() ([]byte, error) {
|
||||
str := r.String()
|
||||
@@ -139,13 +141,13 @@ func (r Ref) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
return []byte("{}"), nil
|
||||
}
|
||||
v := map[string]interface{}{"$ref": str}
|
||||
v := map[string]any{"$ref": str}
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals this ref from a JSON object
|
||||
func (r *Ref) UnmarshalJSON(d []byte) error {
|
||||
var v map[string]interface{}
|
||||
var v map[string]any
|
||||
if err := json.Unmarshal(d, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -174,7 +176,7 @@ func (r *Ref) GobDecode(b []byte) error {
|
||||
return json.Unmarshal(raw, r)
|
||||
}
|
||||
|
||||
func (r *Ref) fromMap(v map[string]interface{}) error {
|
||||
func (r *Ref) fromMap(v map[string]any) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ package spec
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
func resolveAnyWithBase(root interface{}, ref *Ref, result interface{}, options *ExpandOptions) error {
|
||||
@@ -45,7 +45,7 @@ func ResolveRef(root interface{}, ref *Ref) (*Schema, error) {
|
||||
return sch, nil
|
||||
case map[string]interface{}:
|
||||
newSch := new(Schema)
|
||||
if err = swag.DynamicJSONToStruct(sch, newSch); err != nil {
|
||||
if err = jsonutils.FromDynamicJSON(sch, newSch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newSch, nil
|
||||
|
||||
+17
-17
@@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// ResponseProps properties specific to a response
|
||||
@@ -38,6 +38,18 @@ type Response struct {
|
||||
VendorExtensible
|
||||
}
|
||||
|
||||
// NewResponse creates a new response instance
|
||||
func NewResponse() *Response {
|
||||
return new(Response)
|
||||
}
|
||||
|
||||
// ResponseRef creates a response as a json reference
|
||||
func ResponseRef(url string) *Response {
|
||||
resp := NewResponse()
|
||||
resp.Ref = MustCreateRef(url)
|
||||
return resp
|
||||
}
|
||||
|
||||
// JSONLookup look up a value by the json property name
|
||||
func (r Response) JSONLookup(token string) (interface{}, error) {
|
||||
if ex, ok := r.Extensions[token]; ok {
|
||||
@@ -79,9 +91,9 @@ func (r Response) MarshalJSON() ([]byte, error) {
|
||||
Headers map[string]Header `json:"headers,omitempty"`
|
||||
Examples map[string]interface{} `json:"examples,omitempty"`
|
||||
}{
|
||||
Description: r.ResponseProps.Description,
|
||||
Schema: r.ResponseProps.Schema,
|
||||
Examples: r.ResponseProps.Examples,
|
||||
Description: r.Description,
|
||||
Schema: r.Schema,
|
||||
Examples: r.Examples,
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
@@ -96,19 +108,7 @@ func (r Response) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
// NewResponse creates a new response instance
|
||||
func NewResponse() *Response {
|
||||
return new(Response)
|
||||
}
|
||||
|
||||
// ResponseRef creates a response as a json reference
|
||||
func ResponseRef(url string) *Response {
|
||||
resp := NewResponse()
|
||||
resp.Ref = MustCreateRef(url)
|
||||
return resp
|
||||
return jsonutils.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
// WithDescription sets the description on this response, allows for chaining
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// Responses is a container for the expected responses of an operation.
|
||||
@@ -55,7 +55,7 @@ func (r Responses) JSONLookup(token string) (interface{}, error) {
|
||||
return scr, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
return nil, fmt.Errorf("object has no field %q: %w", token, ErrSpec)
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
@@ -83,7 +83,7 @@ func (r Responses) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
concated := swag.ConcatJSON(b1, b2)
|
||||
concated := jsonutils.ConcatJSON(b1, b2)
|
||||
return concated, nil
|
||||
}
|
||||
|
||||
|
||||
+38
-36
@@ -20,7 +20,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonname"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// BooleanProperty creates a boolean property
|
||||
@@ -125,20 +126,20 @@ func (r SchemaURL) MarshalJSON() ([]byte, error) {
|
||||
if r == "" {
|
||||
return []byte("{}"), nil
|
||||
}
|
||||
v := map[string]interface{}{"$schema": string(r)}
|
||||
v := map[string]any{"$schema": string(r)}
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshal this from JSON
|
||||
func (r *SchemaURL) UnmarshalJSON(data []byte) error {
|
||||
var v map[string]interface{}
|
||||
var v map[string]any
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
return r.fromMap(v)
|
||||
}
|
||||
|
||||
func (r *SchemaURL) fromMap(v map[string]interface{}) error {
|
||||
func (r *SchemaURL) fromMap(v map[string]any) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -165,7 +166,7 @@ type SchemaProps struct {
|
||||
Nullable bool `json:"nullable,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Default interface{} `json:"default,omitempty"`
|
||||
Default any `json:"default,omitempty"`
|
||||
Maximum *float64 `json:"maximum,omitempty"`
|
||||
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
|
||||
Minimum *float64 `json:"minimum,omitempty"`
|
||||
@@ -177,7 +178,7 @@ type SchemaProps struct {
|
||||
MinItems *int64 `json:"minItems,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitempty"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty"`
|
||||
Enum []interface{} `json:"enum,omitempty"`
|
||||
Enum []any `json:"enum,omitempty"`
|
||||
MaxProperties *int64 `json:"maxProperties,omitempty"`
|
||||
MinProperties *int64 `json:"minProperties,omitempty"`
|
||||
Required []string `json:"required,omitempty"`
|
||||
@@ -200,7 +201,7 @@ type SwaggerSchemaProps struct {
|
||||
ReadOnly bool `json:"readOnly,omitempty"`
|
||||
XML *XMLObject `json:"xml,omitempty"`
|
||||
ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
Example any `json:"example,omitempty"`
|
||||
}
|
||||
|
||||
// Schema the schema object allows the definition of input and output data types.
|
||||
@@ -214,11 +215,12 @@ type Schema struct {
|
||||
VendorExtensible
|
||||
SchemaProps
|
||||
SwaggerSchemaProps
|
||||
ExtraProps map[string]interface{} `json:"-"`
|
||||
|
||||
ExtraProps map[string]any `json:"-"`
|
||||
}
|
||||
|
||||
// JSONLookup implements an interface to customize json pointer lookup
|
||||
func (s Schema) JSONLookup(token string) (interface{}, error) {
|
||||
func (s Schema) JSONLookup(token string) (any, error) {
|
||||
if ex, ok := s.Extensions[token]; ok {
|
||||
return &ex, nil
|
||||
}
|
||||
@@ -275,14 +277,14 @@ func (s *Schema) WithAllOf(schemas ...Schema) *Schema {
|
||||
}
|
||||
|
||||
// WithMaxProperties sets the max number of properties an object can have
|
||||
func (s *Schema) WithMaxProperties(max int64) *Schema {
|
||||
s.MaxProperties = &max
|
||||
func (s *Schema) WithMaxProperties(maximum int64) *Schema {
|
||||
s.MaxProperties = &maximum
|
||||
return s
|
||||
}
|
||||
|
||||
// WithMinProperties sets the min number of properties an object must have
|
||||
func (s *Schema) WithMinProperties(min int64) *Schema {
|
||||
s.MinProperties = &min
|
||||
func (s *Schema) WithMinProperties(minimum int64) *Schema {
|
||||
s.MinProperties = &minimum
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -316,7 +318,7 @@ func (s *Schema) CollectionOf(items Schema) *Schema {
|
||||
}
|
||||
|
||||
// WithDefault sets the default value on this parameter
|
||||
func (s *Schema) WithDefault(defaultValue interface{}) *Schema {
|
||||
func (s *Schema) WithDefault(defaultValue any) *Schema {
|
||||
s.Default = defaultValue
|
||||
return s
|
||||
}
|
||||
@@ -334,14 +336,14 @@ func (s *Schema) AddRequired(items ...string) *Schema {
|
||||
}
|
||||
|
||||
// WithMaxLength sets a max length value
|
||||
func (s *Schema) WithMaxLength(max int64) *Schema {
|
||||
s.MaxLength = &max
|
||||
func (s *Schema) WithMaxLength(maximum int64) *Schema {
|
||||
s.MaxLength = &maximum
|
||||
return s
|
||||
}
|
||||
|
||||
// WithMinLength sets a min length value
|
||||
func (s *Schema) WithMinLength(min int64) *Schema {
|
||||
s.MinLength = &min
|
||||
func (s *Schema) WithMinLength(minimum int64) *Schema {
|
||||
s.MinLength = &minimum
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -358,22 +360,22 @@ func (s *Schema) WithMultipleOf(number float64) *Schema {
|
||||
}
|
||||
|
||||
// WithMaximum sets a maximum number value
|
||||
func (s *Schema) WithMaximum(max float64, exclusive bool) *Schema {
|
||||
s.Maximum = &max
|
||||
func (s *Schema) WithMaximum(maximum float64, exclusive bool) *Schema {
|
||||
s.Maximum = &maximum
|
||||
s.ExclusiveMaximum = exclusive
|
||||
return s
|
||||
}
|
||||
|
||||
// WithMinimum sets a minimum number value
|
||||
func (s *Schema) WithMinimum(min float64, exclusive bool) *Schema {
|
||||
s.Minimum = &min
|
||||
func (s *Schema) WithMinimum(minimum float64, exclusive bool) *Schema {
|
||||
s.Minimum = &minimum
|
||||
s.ExclusiveMinimum = exclusive
|
||||
return s
|
||||
}
|
||||
|
||||
// WithEnum sets a the enum values (replace)
|
||||
func (s *Schema) WithEnum(values ...interface{}) *Schema {
|
||||
s.Enum = append([]interface{}{}, values...)
|
||||
func (s *Schema) WithEnum(values ...any) *Schema {
|
||||
s.Enum = append([]any{}, values...)
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -426,7 +428,7 @@ func (s *Schema) AsWritable() *Schema {
|
||||
}
|
||||
|
||||
// WithExample sets the example for this schema
|
||||
func (s *Schema) WithExample(example interface{}) *Schema {
|
||||
func (s *Schema) WithExample(example any) *Schema {
|
||||
s.Example = example
|
||||
return s
|
||||
}
|
||||
@@ -566,33 +568,33 @@ func (s Schema) Validations() SchemaValidations {
|
||||
func (s Schema) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(s.SchemaProps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("schema props %v", err)
|
||||
return nil, fmt.Errorf("schema props %v: %w", err, ErrSpec)
|
||||
}
|
||||
b2, err := json.Marshal(s.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("vendor props %v", err)
|
||||
return nil, fmt.Errorf("vendor props %v: %w", err, ErrSpec)
|
||||
}
|
||||
b3, err := s.Ref.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ref prop %v", err)
|
||||
return nil, fmt.Errorf("ref prop %v: %w", err, ErrSpec)
|
||||
}
|
||||
b4, err := s.Schema.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("schema prop %v", err)
|
||||
return nil, fmt.Errorf("schema prop %v: %w", err, ErrSpec)
|
||||
}
|
||||
b5, err := json.Marshal(s.SwaggerSchemaProps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("common validations %v", err)
|
||||
return nil, fmt.Errorf("common validations %v: %w", err, ErrSpec)
|
||||
}
|
||||
var b6 []byte
|
||||
if s.ExtraProps != nil {
|
||||
jj, err := json.Marshal(s.ExtraProps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("extra props %v", err)
|
||||
return nil, fmt.Errorf("extra props %v: %w", err, ErrSpec)
|
||||
}
|
||||
b6 = jj
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil
|
||||
return jsonutils.ConcatJSON(b1, b2, b3, b4, b5, b6), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON marshal this from JSON
|
||||
@@ -610,7 +612,7 @@ func (s *Schema) UnmarshalJSON(data []byte) error {
|
||||
SwaggerSchemaProps: props.SwaggerSchemaProps,
|
||||
}
|
||||
|
||||
var d map[string]interface{}
|
||||
var d map[string]any
|
||||
if err := json.Unmarshal(data, &d); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -620,7 +622,7 @@ func (s *Schema) UnmarshalJSON(data []byte) error {
|
||||
|
||||
delete(d, "$ref")
|
||||
delete(d, "$schema")
|
||||
for _, pn := range swag.DefaultJSONNameProvider.GetJSONNames(s) {
|
||||
for _, pn := range jsonname.DefaultJSONNameProvider.GetJSONNames(s) {
|
||||
delete(d, pn)
|
||||
}
|
||||
|
||||
@@ -628,13 +630,13 @@ func (s *Schema) UnmarshalJSON(data []byte) error {
|
||||
lk := strings.ToLower(k)
|
||||
if strings.HasPrefix(lk, "x-") {
|
||||
if sch.Extensions == nil {
|
||||
sch.Extensions = map[string]interface{}{}
|
||||
sch.Extensions = map[string]any{}
|
||||
}
|
||||
sch.Extensions[k] = vv
|
||||
continue
|
||||
}
|
||||
if sch.ExtraProps == nil {
|
||||
sch.ExtraProps = map[string]interface{}{}
|
||||
sch.ExtraProps = map[string]any{}
|
||||
}
|
||||
sch.ExtraProps[k] = vv
|
||||
}
|
||||
|
||||
+26
-24
@@ -22,7 +22,9 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
"github.com/go-openapi/swag/loading"
|
||||
"github.com/go-openapi/swag/stringutils"
|
||||
)
|
||||
|
||||
// PathLoader is a function to use when loading remote refs.
|
||||
@@ -34,7 +36,7 @@ import (
|
||||
// this value with its own default (a loader to retrieve YAML documents as
|
||||
// well as JSON ones).
|
||||
var PathLoader = func(pth string) (json.RawMessage, error) {
|
||||
data, err := swag.LoadFromFileOrHTTP(pth)
|
||||
data, err := loading.LoadFromFileOrHTTP(pth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -73,12 +75,23 @@ func newResolverContext(options *ExpandOptions) *resolverContext {
|
||||
}
|
||||
|
||||
type schemaLoader struct {
|
||||
root interface{}
|
||||
root any
|
||||
options *ExpandOptions
|
||||
cache ResolutionCache
|
||||
context *resolverContext
|
||||
}
|
||||
|
||||
// Resolve resolves a reference against basePath and stores the result in target.
|
||||
//
|
||||
// Resolve is not in charge of following references: it only resolves ref by following its URL.
|
||||
//
|
||||
// If the schema the ref is referring to holds nested refs, Resolve doesn't resolve them.
|
||||
//
|
||||
// If basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct
|
||||
func (r *schemaLoader) Resolve(ref *Ref, target any, basePath string) error {
|
||||
return r.resolveRef(ref, target, basePath)
|
||||
}
|
||||
|
||||
func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) *schemaLoader {
|
||||
if ref.IsRoot() || ref.HasFragmentOnly {
|
||||
return r
|
||||
@@ -113,7 +126,7 @@ func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string)
|
||||
return basePath
|
||||
}
|
||||
|
||||
func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string) error {
|
||||
func (r *schemaLoader) resolveRef(ref *Ref, target any, basePath string) error {
|
||||
tgt := reflect.ValueOf(target)
|
||||
if tgt.Kind() != reflect.Ptr {
|
||||
return ErrResolveRefNeedsAPointer
|
||||
@@ -124,8 +137,8 @@ func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string)
|
||||
}
|
||||
|
||||
var (
|
||||
res interface{}
|
||||
data interface{}
|
||||
res any
|
||||
data any
|
||||
err error
|
||||
)
|
||||
|
||||
@@ -155,10 +168,10 @@ func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return swag.DynamicJSONToStruct(res, target)
|
||||
return jsonutils.FromDynamicJSON(res, target)
|
||||
}
|
||||
|
||||
func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error) {
|
||||
func (r *schemaLoader) load(refURL *url.URL) (any, url.URL, bool, error) {
|
||||
debugLog("loading schema from url: %s", refURL)
|
||||
toFetch := *refURL
|
||||
toFetch.Fragment = ""
|
||||
@@ -178,7 +191,7 @@ func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error)
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
|
||||
var doc interface{}
|
||||
var doc any
|
||||
if err := json.Unmarshal(b, &doc); err != nil {
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
@@ -197,25 +210,14 @@ func (r *schemaLoader) isCircular(ref *Ref, basePath string, parentRefs ...strin
|
||||
foundCycle = true
|
||||
return
|
||||
}
|
||||
foundCycle = swag.ContainsStrings(parentRefs, normalizedRef) // normalized windows url's are lower cased
|
||||
foundCycle = stringutils.ContainsStrings(parentRefs, normalizedRef) // normalized windows url's are lower cased
|
||||
if foundCycle {
|
||||
r.context.circulars[normalizedRef] = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve resolves a reference against basePath and stores the result in target.
|
||||
//
|
||||
// Resolve is not in charge of following references: it only resolves ref by following its URL.
|
||||
//
|
||||
// If the schema the ref is referring to holds nested refs, Resolve doesn't resolve them.
|
||||
//
|
||||
// If basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct
|
||||
func (r *schemaLoader) Resolve(ref *Ref, target interface{}, basePath string) error {
|
||||
return r.resolveRef(ref, target, basePath)
|
||||
}
|
||||
|
||||
func (r *schemaLoader) deref(input interface{}, parentRefs []string, basePath string) error {
|
||||
func (r *schemaLoader) deref(input any, parentRefs []string, basePath string) error {
|
||||
var ref *Ref
|
||||
switch refable := input.(type) {
|
||||
case *Schema:
|
||||
@@ -267,7 +269,7 @@ func (r *schemaLoader) shouldStopOnError(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *schemaLoader) setSchemaID(target interface{}, id, basePath string) (string, string) {
|
||||
func (r *schemaLoader) setSchemaID(target any, id, basePath string) (string, string) {
|
||||
debugLog("schema has ID: %s", id)
|
||||
|
||||
// handling the case when id is a folder
|
||||
@@ -299,7 +301,7 @@ func (r *schemaLoader) setSchemaID(target interface{}, id, basePath string) (str
|
||||
}
|
||||
|
||||
func defaultSchemaLoader(
|
||||
root interface{},
|
||||
root any,
|
||||
expandOptions *ExpandOptions,
|
||||
cache ResolutionCache,
|
||||
context *resolverContext) *schemaLoader {
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -158,7 +158,7 @@ func (s SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
return jsonutils.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON marshal this from JSON
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// Swagger this is the root document object for the API specification.
|
||||
@@ -54,7 +54,7 @@ func (s Swagger) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
return jsonutils.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals a swagger spec from json
|
||||
@@ -379,7 +379,7 @@ func (s *StringOrArray) UnmarshalJSON(data []byte) error {
|
||||
*s = StringOrArray([]string{v})
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("only string or array is allowed, not %T", single)
|
||||
return fmt.Errorf("only string or array is allowed, not %T: %w", single, ErrSpec)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/swag/jsonutils"
|
||||
)
|
||||
|
||||
// TagProps describe a tag entry in the top level tags section of a swagger spec
|
||||
@@ -28,11 +28,6 @@ type TagProps struct {
|
||||
ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
|
||||
}
|
||||
|
||||
// NewTag creates a new tag
|
||||
func NewTag(name, description string, externalDocs *ExternalDocumentation) Tag {
|
||||
return Tag{TagProps: TagProps{Description: description, Name: name, ExternalDocs: externalDocs}}
|
||||
}
|
||||
|
||||
// Tag allows adding meta data to a single tag that is used by the
|
||||
// [Operation Object](http://goo.gl/8us55a#operationObject).
|
||||
// It is not mandatory to have a Tag Object per tag used there.
|
||||
@@ -43,6 +38,11 @@ type Tag struct {
|
||||
TagProps
|
||||
}
|
||||
|
||||
// NewTag creates a new tag
|
||||
func NewTag(name, description string, externalDocs *ExternalDocumentation) Tag {
|
||||
return Tag{TagProps: TagProps{Description: description, Name: name, ExternalDocs: externalDocs}}
|
||||
}
|
||||
|
||||
// JSONLookup implements an interface to customize json pointer lookup
|
||||
func (t Tag) JSONLookup(token string) (interface{}, error) {
|
||||
if ex, ok := t.Extensions[token]; ok {
|
||||
@@ -63,7 +63,7 @@ func (t Tag) MarshalJSON() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
return jsonutils.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON marshal this from JSON
|
||||
|
||||
+8
-4
@@ -54,7 +54,8 @@ func (c clearedValidations) apply(cbs []func(string, interface{})) {
|
||||
//
|
||||
// Some callbacks may be set by the caller to capture changed values.
|
||||
func (v *CommonValidations) ClearNumberValidations(cbs ...func(string, interface{})) {
|
||||
done := make(clearedValidations, 0, 5)
|
||||
const maxNumberValidations = 5
|
||||
done := make(clearedValidations, 0, maxNumberValidations)
|
||||
defer func() {
|
||||
done.apply(cbs)
|
||||
}()
|
||||
@@ -85,7 +86,8 @@ func (v *CommonValidations) ClearNumberValidations(cbs ...func(string, interface
|
||||
//
|
||||
// Some callbacks may be set by the caller to capture changed values.
|
||||
func (v *CommonValidations) ClearStringValidations(cbs ...func(string, interface{})) {
|
||||
done := make(clearedValidations, 0, 3)
|
||||
const maxStringValidations = 3
|
||||
done := make(clearedValidations, 0, maxStringValidations)
|
||||
defer func() {
|
||||
done.apply(cbs)
|
||||
}()
|
||||
@@ -108,7 +110,8 @@ func (v *CommonValidations) ClearStringValidations(cbs ...func(string, interface
|
||||
//
|
||||
// Some callbacks may be set by the caller to capture changed values.
|
||||
func (v *CommonValidations) ClearArrayValidations(cbs ...func(string, interface{})) {
|
||||
done := make(clearedValidations, 0, 3)
|
||||
const maxArrayValidations = 3
|
||||
done := make(clearedValidations, 0, maxArrayValidations)
|
||||
defer func() {
|
||||
done.apply(cbs)
|
||||
}()
|
||||
@@ -195,7 +198,8 @@ func (v SchemaValidations) Validations() SchemaValidations {
|
||||
//
|
||||
// Some callbacks may be set by the caller to capture changed values.
|
||||
func (v *SchemaValidations) ClearObjectValidations(cbs ...func(string, interface{})) {
|
||||
done := make(clearedValidations, 0, 3)
|
||||
const maxObjectValidations = 3
|
||||
done := make(clearedValidations, 0, maxObjectValidations)
|
||||
defer func() {
|
||||
done.apply(cbs)
|
||||
}()
|
||||
|
||||
+70
-56
@@ -1,61 +1,75 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- maligned
|
||||
- unparam
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- nlreturn
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- wsl_v5
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text.
|
||||
# Set to 0 to disable.
|
||||
# Default: 3
|
||||
max-same-issues: 0
|
||||
|
||||
+3
-3
@@ -39,10 +39,10 @@ func IsBSONObjectID(str string) bool {
|
||||
// ObjectId represents a BSON object ID (alias to go.mongodb.org/mongo-driver/bson/primitive.ObjectID)
|
||||
//
|
||||
// swagger:strfmt bsonobjectid
|
||||
type ObjectId bsonprim.ObjectID //nolint:revive,stylecheck
|
||||
type ObjectId bsonprim.ObjectID //nolint:revive
|
||||
|
||||
// NewObjectId creates a ObjectId from a Hex String
|
||||
func NewObjectId(hex string) ObjectId { //nolint:revive,stylecheck
|
||||
func NewObjectId(hex string) ObjectId { //nolint:revive
|
||||
oid, err := bsonprim.ObjectIDFromHex(hex)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -83,7 +83,7 @@ func (id *ObjectId) Scan(raw interface{}) error {
|
||||
case string:
|
||||
data = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.URI from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.URI from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return id.UnmarshalText(data)
|
||||
|
||||
+2
-3
@@ -17,7 +17,6 @@ package strfmt
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -84,7 +83,7 @@ func (d *Date) Scan(raw interface{}) error {
|
||||
*d = Date{}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Date from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Date from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +133,7 @@ func (d *Date) UnmarshalBSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New("couldn't unmarshal bson bytes value as Date")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes value as Date: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
|
||||
+292
-85
@@ -18,46 +18,23 @@ import (
|
||||
"database/sql/driver"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/mail"
|
||||
"regexp"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/google/uuid"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"golang.org/x/net/idna"
|
||||
)
|
||||
|
||||
const (
|
||||
// HostnamePattern http://json-schema.org/latest/json-schema-validation.html#anchor114
|
||||
// A string instance is valid against this attribute if it is a valid
|
||||
// representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034].
|
||||
// http://tools.ietf.org/html/rfc1034#section-3.5
|
||||
// <digit> ::= any one of the ten digits 0 through 9
|
||||
// var digit = /[0-9]/;
|
||||
// <letter> ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
|
||||
// var letter = /[a-zA-Z]/;
|
||||
// <let-dig> ::= <letter> | <digit>
|
||||
// var letDig = /[0-9a-zA-Z]/;
|
||||
// <let-dig-hyp> ::= <let-dig> | "-"
|
||||
// var letDigHyp = /[-0-9a-zA-Z]/;
|
||||
// <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
|
||||
// var ldhStr = /[-0-9a-zA-Z]+/;
|
||||
// <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
|
||||
// var label = /[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?/;
|
||||
// <subdomain> ::= <label> | <subdomain> "." <label>
|
||||
// var subdomain = /^[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?(\.[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?)*$/;
|
||||
// <domain> ::= <subdomain> | " "
|
||||
// HostnamePattern http://json-schema.org/latest/json-schema-validation.html#anchor114.
|
||||
//
|
||||
// Additional validations:
|
||||
// - for FDQNs, top-level domain (e.g. ".com"), is at least to letters long (no special characters here)
|
||||
// - hostnames may start with a digit [RFC1123]
|
||||
// - special registered names with an underscore ('_') are not allowed in this context
|
||||
// - dashes are permitted, but not at the start or the end of a segment
|
||||
// - long top-level domain names (e.g. example.london) are permitted
|
||||
// - symbol unicode points are permitted (e.g. emoji) (not for top-level domain)
|
||||
HostnamePattern = `^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$`
|
||||
// Deprecated: this package no longer uses regular expressions to validate hostnames.
|
||||
HostnamePattern = `^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z0-9-\p{L}]){2,63})$`
|
||||
|
||||
// json null type
|
||||
jsonNull = "null"
|
||||
@@ -85,30 +62,254 @@ const (
|
||||
UUID5Pattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$)|(^[0-9a-f]{12}5[0-9a-f]{3}[89ab][0-9a-f]{15}$)`
|
||||
)
|
||||
|
||||
var (
|
||||
rxHostname = regexp.MustCompile(HostnamePattern)
|
||||
var idnaHostChecker = idna.New(
|
||||
idna.ValidateForRegistration(), // shorthand for [idna.StrictDomainName], [idna.ValidateLabels], [idna.VerifyDNSLength], [idna.BidiRule]
|
||||
)
|
||||
|
||||
// IsHostname returns true when the string is a valid hostname
|
||||
// IsHostname returns true when the string is a valid hostname.
|
||||
//
|
||||
// It follows the rules detailed at https://url.spec.whatwg.org/#concept-host-parser
|
||||
// and implemented by most modern web browsers.
|
||||
//
|
||||
// It supports IDNA rules regarding internationalized names with unicode.
|
||||
//
|
||||
// Besides:
|
||||
// * the empty string is not a valid host name
|
||||
// * a trailing dot is allowed in names and IPv4's (not IPv6)
|
||||
// * a host name can be a valid IPv4 (with decimal, octal or hexadecimal numbers) or IPv6 address
|
||||
// * IPv6 zones are disallowed
|
||||
// * top-level domains can be unicode (cf. https://www.iana.org/domains/root/db).
|
||||
//
|
||||
// NOTE: this validator doesn't check top-level domains against the IANA root database.
|
||||
// It merely ensures that a top-level domain in a FQDN is at least 2 code points long.
|
||||
func IsHostname(str string) bool {
|
||||
if !rxHostname.MatchString(str) {
|
||||
if len(str) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// the sum of all label octets and label lengths is limited to 255.
|
||||
if len(str) > 255 {
|
||||
// IP v6 check
|
||||
if ipv6Cleaned, found := strings.CutPrefix(str, "["); found {
|
||||
ipv6Cleaned, found = strings.CutSuffix(ipv6Cleaned, "]")
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
|
||||
return isValidIPv6(ipv6Cleaned)
|
||||
}
|
||||
|
||||
// IDNA check
|
||||
res, err := idnaHostChecker.ToASCII(strings.ToLower(str))
|
||||
if err != nil || res == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Each node has a label, which is zero to 63 octets in length
|
||||
parts := strings.Split(str, ".")
|
||||
valid := true
|
||||
for _, p := range parts {
|
||||
if len(p) > 63 {
|
||||
valid = false
|
||||
parts := strings.Split(res, ".")
|
||||
|
||||
// IP v4 check
|
||||
lastPart, lastIndex, shouldBeIPv4 := domainEndsAsNumber(parts)
|
||||
if shouldBeIPv4 {
|
||||
// domain ends in a number: must be an IPv4
|
||||
return isValidIPv4(parts[:lastIndex+1]) // if the last part is a trailing dot, remove it
|
||||
}
|
||||
|
||||
// check TLD length (excluding trailing dot)
|
||||
const minTLDLength = 2
|
||||
if lastIndex > 0 && len(lastPart) < minTLDLength {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// domainEndsAsNumber determines if a domain name ends with a decimal, octal or hex digit,
|
||||
// accounting for a possible trailing dot (the last part being empty in that case).
|
||||
//
|
||||
// It returns the last non-trailing dot part and if that part consists only of (dec/hex/oct) digits.
|
||||
func domainEndsAsNumber(parts []string) (lastPart string, lastIndex int, ok bool) {
|
||||
// NOTE: using ParseUint(x, 0, 32) is not an option, as the IPv4 format supported why WHATWG
|
||||
// doesn't support notations such as "0b1001" (binary digits) or "0o666" (alternate notation for octal digits).
|
||||
lastIndex = len(parts) - 1
|
||||
lastPart = parts[lastIndex]
|
||||
if len(lastPart) == 0 {
|
||||
// trailing dot
|
||||
if len(parts) == 1 { // dot-only string: normally already ruled out by the IDNA check above
|
||||
return lastPart, lastIndex, false
|
||||
}
|
||||
|
||||
lastIndex--
|
||||
lastPart = parts[lastIndex]
|
||||
}
|
||||
|
||||
if startOfHexDigit(lastPart) {
|
||||
for _, b := range []byte(lastPart[2:]) {
|
||||
if !isHexDigit(b) {
|
||||
return lastPart, lastIndex, false
|
||||
}
|
||||
}
|
||||
|
||||
return lastPart, lastIndex, true
|
||||
}
|
||||
|
||||
// check for decimal and octal
|
||||
for _, b := range []byte(lastPart) {
|
||||
if !isASCIIDigit(b) {
|
||||
return lastPart, lastIndex, false
|
||||
}
|
||||
}
|
||||
return valid
|
||||
|
||||
return lastPart, lastIndex, true
|
||||
}
|
||||
|
||||
func startOfHexDigit(str string) bool {
|
||||
return strings.HasPrefix(str, "0x") // the input has already been lower-cased
|
||||
}
|
||||
|
||||
func startOfOctalDigit(str string) bool {
|
||||
if str == "0" {
|
||||
// a single "0" is considered decimal
|
||||
return false
|
||||
}
|
||||
|
||||
return strings.HasPrefix(str, "0")
|
||||
}
|
||||
|
||||
func isValidIPv6(str string) bool {
|
||||
// disallow empty ipv6 address
|
||||
if len(str) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
addr, err := netip.ParseAddr(str)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if !addr.Is6() {
|
||||
return false
|
||||
}
|
||||
|
||||
// explicit desupport of IPv6 zones
|
||||
if addr.Zone() != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// isValidIPv4 parses an IPv4 with deciaml, hex or octal digit parts.
|
||||
//
|
||||
// We can't rely on [netip.ParseAddr] because we may get a mix of decimal, octal and hex digits.
|
||||
//
|
||||
// Examples of valid addresses not supported by [netip.ParseAddr] or [net.ParseIP]:
|
||||
//
|
||||
// "192.0x00A80001"
|
||||
// "0300.0250.0340.001"
|
||||
// "1.0x.1.1"
|
||||
//
|
||||
// But not:
|
||||
//
|
||||
// "0b1010.2.3.4"
|
||||
// "0o07.2.3.4"
|
||||
func isValidIPv4(parts []string) bool {
|
||||
// NOTE: using ParseUint(x, 0, 32) is not an option, even though it would simplify this code a lot.
|
||||
// The IPv4 format supported why WHATWG doesn't support notations such as "0b1001" (binary digits)
|
||||
// or "0o666" (alternate notation for octal digits).
|
||||
const (
|
||||
maxPartsInIPv4 = 4
|
||||
maxDigitsInPart = 11 // max size of a 4-bytes hex or octal digit
|
||||
)
|
||||
|
||||
if len(parts) == 0 || len(parts) > maxPartsInIPv4 {
|
||||
return false
|
||||
}
|
||||
|
||||
// we call this when we know that the last part is a digit part, so len(lastPart)>0
|
||||
|
||||
digits := make([]uint64, 0, maxPartsInIPv4)
|
||||
for _, part := range parts {
|
||||
if len(part) == 0 { // empty part: this case has normally been already ruled out by the IDNA check above
|
||||
return false
|
||||
}
|
||||
|
||||
if len(part) > maxDigitsInPart { // whether decimal, octal or hex, an address can't exceed that length
|
||||
return false
|
||||
}
|
||||
|
||||
if !isASCIIDigit(part[0]) { // start of an IPv4 part is always a digit
|
||||
return false
|
||||
}
|
||||
|
||||
switch {
|
||||
case startOfHexDigit(part):
|
||||
const hexDigitOffset = 2
|
||||
hexString := part[hexDigitOffset:]
|
||||
if len(hexString) == 0 { // 0x part: assume 0
|
||||
digits = append(digits, 0)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
hexDigit, err := strconv.ParseUint(hexString, 16, 32)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
digits = append(digits, hexDigit)
|
||||
|
||||
continue
|
||||
|
||||
case startOfOctalDigit(part):
|
||||
const octDigitOffset = 1
|
||||
octString := part[octDigitOffset:] // we know that this is not empty
|
||||
octDigit, err := strconv.ParseUint(octString, 8, 32)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
digits = append(digits, octDigit)
|
||||
|
||||
default: // assume decimal digits (0-255)
|
||||
// we know that we don't have a leading 0 (would have been caught by octal digit)
|
||||
decDigit, err := strconv.ParseUint(part, 10, 8)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
digits = append(digits, decDigit)
|
||||
}
|
||||
}
|
||||
|
||||
// now check the digits: the last digit may encompass several parts of the address
|
||||
lastDigit := digits[len(digits)-1]
|
||||
if lastDigit > uint64(1)<<uint64(8*(maxPartsInIPv4+1-len(digits))) { //nolint:gosec,mnd // 256^(5 - len(digits)) - safe conversion
|
||||
return false
|
||||
}
|
||||
|
||||
if len(digits) > 1 {
|
||||
const maxUint8 = uint64(^uint8(0))
|
||||
|
||||
for i := range len(digits) - 2 {
|
||||
if digits[i] > maxUint8 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func isHexDigit(c byte) bool {
|
||||
switch {
|
||||
case '0' <= c && c <= '9':
|
||||
return true
|
||||
case 'a' <= c && c <= 'f': // assume the input string to be lower case
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isASCIIDigit(c byte) bool {
|
||||
return c >= '0' && c <= '9'
|
||||
}
|
||||
|
||||
// IsUUID returns true is the string matches a UUID (in any version, including v6 and v7), upper case is allowed
|
||||
@@ -117,22 +318,28 @@ func IsUUID(str string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
const (
|
||||
uuidV3 = 3
|
||||
uuidV4 = 4
|
||||
uuidV5 = 5
|
||||
)
|
||||
|
||||
// IsUUID3 returns true is the string matches a UUID v3, upper case is allowed
|
||||
func IsUUID3(str string) bool {
|
||||
id, err := uuid.Parse(str)
|
||||
return err == nil && id.Version() == uuid.Version(3)
|
||||
return err == nil && id.Version() == uuid.Version(uuidV3)
|
||||
}
|
||||
|
||||
// IsUUID4 returns true is the string matches a UUID v4, upper case is allowed
|
||||
func IsUUID4(str string) bool {
|
||||
id, err := uuid.Parse(str)
|
||||
return err == nil && id.Version() == uuid.Version(4)
|
||||
return err == nil && id.Version() == uuid.Version(uuidV4)
|
||||
}
|
||||
|
||||
// IsUUID5 returns true is the string matches a UUID v5, upper case is allowed
|
||||
func IsUUID5(str string) bool {
|
||||
id, err := uuid.Parse(str)
|
||||
return err == nil && id.Version() == uuid.Version(5)
|
||||
return err == nil && id.Version() == uuid.Version(uuidV5)
|
||||
}
|
||||
|
||||
// IsEmail validates an email address.
|
||||
@@ -269,7 +476,7 @@ func (b *Base64) Scan(raw interface{}) error {
|
||||
}
|
||||
*b = Base64(vv)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Base64 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Base64 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -323,7 +530,7 @@ func (b *Base64) UnmarshalBSON(data []byte) error {
|
||||
*b = Base64(vb)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as base64")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as base64: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -365,7 +572,7 @@ func (u *URI) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = URI(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.URI from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.URI from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -411,7 +618,7 @@ func (u *URI) UnmarshalBSON(data []byte) error {
|
||||
*u = URI(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as uri")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as uri: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -453,7 +660,7 @@ func (e *Email) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*e = Email(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Email from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Email from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -499,7 +706,7 @@ func (e *Email) UnmarshalBSON(data []byte) error {
|
||||
*e = Email(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as email")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as email: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -541,7 +748,7 @@ func (h *Hostname) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*h = Hostname(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Hostname from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Hostname from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -587,7 +794,7 @@ func (h *Hostname) UnmarshalBSON(data []byte) error {
|
||||
*h = Hostname(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as hostname")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as hostname: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -629,7 +836,7 @@ func (u *IPv4) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = IPv4(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.IPv4 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.IPv4 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -675,7 +882,7 @@ func (u *IPv4) UnmarshalBSON(data []byte) error {
|
||||
*u = IPv4(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as ipv4")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as ipv4: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -717,7 +924,7 @@ func (u *IPv6) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = IPv6(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.IPv6 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.IPv6 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -763,7 +970,7 @@ func (u *IPv6) UnmarshalBSON(data []byte) error {
|
||||
*u = IPv6(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as ipv6")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as ipv6: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -805,7 +1012,7 @@ func (u *CIDR) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = CIDR(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.CIDR from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.CIDR from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -851,7 +1058,7 @@ func (u *CIDR) UnmarshalBSON(data []byte) error {
|
||||
*u = CIDR(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as CIDR")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as CIDR: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -893,7 +1100,7 @@ func (u *MAC) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = MAC(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.IPv4 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.IPv4 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -939,7 +1146,7 @@ func (u *MAC) UnmarshalBSON(data []byte) error {
|
||||
*u = MAC(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as MAC")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as MAC: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -981,7 +1188,7 @@ func (u *UUID) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = UUID(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.UUID from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.UUID from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1030,7 +1237,7 @@ func (u *UUID) UnmarshalBSON(data []byte) error {
|
||||
*u = UUID(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as UUID")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as UUID: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1072,7 +1279,7 @@ func (u *UUID3) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = UUID3(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.UUID3 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.UUID3 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1121,7 +1328,7 @@ func (u *UUID3) UnmarshalBSON(data []byte) error {
|
||||
*u = UUID3(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as UUID3")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as UUID3: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1163,7 +1370,7 @@ func (u *UUID4) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = UUID4(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.UUID4 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.UUID4 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1212,7 +1419,7 @@ func (u *UUID4) UnmarshalBSON(data []byte) error {
|
||||
*u = UUID4(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as UUID4")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as UUID4: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1254,7 +1461,7 @@ func (u *UUID5) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = UUID5(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.UUID5 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.UUID5 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1303,7 +1510,7 @@ func (u *UUID5) UnmarshalBSON(data []byte) error {
|
||||
*u = UUID5(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as UUID5")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as UUID5: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1345,7 +1552,7 @@ func (u *ISBN) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = ISBN(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.ISBN from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.ISBN from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1394,7 +1601,7 @@ func (u *ISBN) UnmarshalBSON(data []byte) error {
|
||||
*u = ISBN(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as ISBN")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as ISBN: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1436,7 +1643,7 @@ func (u *ISBN10) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = ISBN10(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.ISBN10 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.ISBN10 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1485,7 +1692,7 @@ func (u *ISBN10) UnmarshalBSON(data []byte) error {
|
||||
*u = ISBN10(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as ISBN10")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as ISBN10: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1527,7 +1734,7 @@ func (u *ISBN13) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = ISBN13(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.ISBN13 from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.ISBN13 from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1576,7 +1783,7 @@ func (u *ISBN13) UnmarshalBSON(data []byte) error {
|
||||
*u = ISBN13(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as ISBN13")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as ISBN13: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1618,7 +1825,7 @@ func (u *CreditCard) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = CreditCard(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.CreditCard from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.CreditCard from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1667,7 +1874,7 @@ func (u *CreditCard) UnmarshalBSON(data []byte) error {
|
||||
*u = CreditCard(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as CreditCard")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as CreditCard: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1709,7 +1916,7 @@ func (u *SSN) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*u = SSN(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.SSN from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.SSN from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1758,7 +1965,7 @@ func (u *SSN) UnmarshalBSON(data []byte) error {
|
||||
*u = SSN(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as SSN")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as SSN: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1800,7 +2007,7 @@ func (h *HexColor) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*h = HexColor(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.HexColor from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.HexColor from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1849,7 +2056,7 @@ func (h *HexColor) UnmarshalBSON(data []byte) error {
|
||||
*h = HexColor(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as HexColor")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as HexColor: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1891,7 +2098,7 @@ func (r *RGBColor) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*r = RGBColor(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.RGBColor from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.RGBColor from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1940,7 +2147,7 @@ func (r *RGBColor) UnmarshalBSON(data []byte) error {
|
||||
*r = RGBColor(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as RGBColor")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as RGBColor: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
@@ -1983,7 +2190,7 @@ func (r *Password) Scan(raw interface{}) error {
|
||||
case string:
|
||||
*r = Password(v)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Password from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Password from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -2032,7 +2239,7 @@ func (r *Password) UnmarshalBSON(data []byte) error {
|
||||
*r = Password(ud)
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as Password")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as Password: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
|
||||
+39
-9
@@ -17,8 +17,8 @@ package strfmt
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -33,6 +33,11 @@ func init() {
|
||||
Default.Add("duration", &d, IsDuration)
|
||||
}
|
||||
|
||||
const (
|
||||
hoursInDay = 24
|
||||
daysInWeek = 7
|
||||
)
|
||||
|
||||
var (
|
||||
timeUnits = [][]string{
|
||||
{"ns", "nano"},
|
||||
@@ -52,11 +57,11 @@ var (
|
||||
"s": time.Second,
|
||||
"m": time.Minute,
|
||||
"h": time.Hour,
|
||||
"d": 24 * time.Hour,
|
||||
"w": 7 * 24 * time.Hour,
|
||||
"d": hoursInDay * time.Hour,
|
||||
"w": hoursInDay * daysInWeek * time.Hour,
|
||||
}
|
||||
|
||||
durationMatcher = regexp.MustCompile(`((\d+)\s*([A-Za-zµ]+))`)
|
||||
durationMatcher = regexp.MustCompile(`^(((?:-\s?)?\d+)(\.\d+)?\s*([A-Za-zµ]+))`)
|
||||
)
|
||||
|
||||
// IsDuration returns true if the provided string is a valid duration
|
||||
@@ -96,13 +101,35 @@ func ParseDuration(cand string) (time.Duration, error) {
|
||||
|
||||
var dur time.Duration
|
||||
ok := false
|
||||
const expectGroups = 4
|
||||
for _, match := range durationMatcher.FindAllStringSubmatch(cand, -1) {
|
||||
if len(match) < expectGroups {
|
||||
continue
|
||||
}
|
||||
|
||||
factor, err := strconv.Atoi(match[2]) // converts string to int
|
||||
// remove possible leading - and spaces
|
||||
value, negative := strings.CutPrefix(match[2], "-")
|
||||
|
||||
// if the duration contains a decimal separator determine a divising factor
|
||||
const neutral = 1.0
|
||||
divisor := neutral
|
||||
decimal, hasDecimal := strings.CutPrefix(match[3], ".")
|
||||
if hasDecimal {
|
||||
divisor = math.Pow10(len(decimal))
|
||||
value += decimal // consider the value as an integer: will change units later on
|
||||
}
|
||||
|
||||
// if the string is a valid duration, parse it
|
||||
factor, err := strconv.Atoi(strings.TrimSpace(value)) // converts string to int
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
unit := strings.ToLower(strings.TrimSpace(match[3]))
|
||||
|
||||
if negative {
|
||||
factor = -factor
|
||||
}
|
||||
|
||||
unit := strings.ToLower(strings.TrimSpace(match[4]))
|
||||
|
||||
for _, variants := range timeUnits {
|
||||
last := len(variants) - 1
|
||||
@@ -111,6 +138,9 @@ func ParseDuration(cand string) (time.Duration, error) {
|
||||
for i, variant := range variants {
|
||||
if (last == i && strings.HasPrefix(unit, variant)) || strings.EqualFold(variant, unit) {
|
||||
ok = true
|
||||
if divisor != neutral {
|
||||
multiplier = time.Duration(float64(multiplier) / divisor) // convert to duration only after having reduced the scale
|
||||
}
|
||||
dur += (time.Duration(factor) * multiplier)
|
||||
}
|
||||
}
|
||||
@@ -120,7 +150,7 @@ func ParseDuration(cand string) (time.Duration, error) {
|
||||
if ok {
|
||||
return dur, nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to parse %s as duration", cand)
|
||||
return 0, fmt.Errorf("unable to parse %s as duration: %w", cand, ErrFormat)
|
||||
}
|
||||
|
||||
// Scan reads a Duration value from database driver type.
|
||||
@@ -134,7 +164,7 @@ func (d *Duration) Scan(raw interface{}) error {
|
||||
case nil:
|
||||
*d = Duration(0)
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Duration from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.Duration from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -192,7 +222,7 @@ func (d *Duration) UnmarshalBSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New("couldn't unmarshal bson bytes value as Date")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes value as Date: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package strfmt
|
||||
|
||||
type strfmtError string
|
||||
|
||||
// ErrFormat is an error raised by the strfmt package
|
||||
const ErrFormat strfmtError = "format error"
|
||||
|
||||
func (e strfmtError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
+28
-28
@@ -16,7 +16,6 @@ package strfmt
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -24,7 +23,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
// Default is the default formats registry
|
||||
@@ -50,31 +49,10 @@ type Registry interface {
|
||||
GetType(string) (reflect.Type, bool)
|
||||
ContainsName(string) bool
|
||||
Validates(string, string) bool
|
||||
Parse(string, string) (interface{}, error)
|
||||
Parse(string, string) (any, error)
|
||||
MapStructureHookFunc() mapstructure.DecodeHookFunc
|
||||
}
|
||||
|
||||
type knownFormat struct {
|
||||
Name string
|
||||
OrigName string
|
||||
Type reflect.Type
|
||||
Validator Validator
|
||||
}
|
||||
|
||||
// NameNormalizer is a function that normalizes a format name.
|
||||
type NameNormalizer func(string) string
|
||||
|
||||
// DefaultNameNormalizer removes all dashes
|
||||
func DefaultNameNormalizer(name string) string {
|
||||
return strings.ReplaceAll(name, "-", "")
|
||||
}
|
||||
|
||||
type defaultFormats struct {
|
||||
sync.Mutex
|
||||
data []knownFormat
|
||||
normalizeName NameNormalizer
|
||||
}
|
||||
|
||||
// NewFormats creates a new formats registry seeded with the values from the default
|
||||
func NewFormats() Registry {
|
||||
//nolint:forcetypeassert
|
||||
@@ -94,15 +72,37 @@ func NewSeededFormats(seeds []knownFormat, normalizer NameNormalizer) Registry {
|
||||
}
|
||||
}
|
||||
|
||||
type knownFormat struct {
|
||||
Name string
|
||||
OrigName string
|
||||
Type reflect.Type
|
||||
Validator Validator
|
||||
}
|
||||
|
||||
// NameNormalizer is a function that normalizes a format name.
|
||||
type NameNormalizer func(string) string
|
||||
|
||||
// DefaultNameNormalizer removes all dashes
|
||||
func DefaultNameNormalizer(name string) string {
|
||||
return strings.ReplaceAll(name, "-", "")
|
||||
}
|
||||
|
||||
type defaultFormats struct {
|
||||
sync.Mutex
|
||||
|
||||
data []knownFormat
|
||||
normalizeName NameNormalizer
|
||||
}
|
||||
|
||||
// MapStructureHookFunc is a decode hook function for mapstructure
|
||||
func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc {
|
||||
return func(from reflect.Type, to reflect.Type, obj interface{}) (interface{}, error) {
|
||||
return func(from reflect.Type, to reflect.Type, obj any) (any, error) {
|
||||
if from.Kind() != reflect.String {
|
||||
return obj, nil
|
||||
}
|
||||
data, ok := obj.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to cast %+v to string", obj)
|
||||
return nil, fmt.Errorf("failed to cast %+v to string: %w", obj, ErrFormat)
|
||||
}
|
||||
|
||||
for _, v := range f.data {
|
||||
@@ -118,7 +118,7 @@ func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc {
|
||||
case "datetime":
|
||||
input := data
|
||||
if len(input) == 0 {
|
||||
return nil, stderrors.New("empty string is an invalid datetime format")
|
||||
return nil, fmt.Errorf("empty string is an invalid datetime format: %w", ErrFormat)
|
||||
}
|
||||
return ParseDateTime(input)
|
||||
case "duration":
|
||||
@@ -307,7 +307,7 @@ func (f *defaultFormats) Validates(name, data string) bool {
|
||||
// Parse a string into the appropriate format representation type.
|
||||
//
|
||||
// E.g. parsing a string a "date" will return a Date type.
|
||||
func (f *defaultFormats) Parse(name, data string) (interface{}, error) {
|
||||
func (f *defaultFormats) Parse(name, data string) (any, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
nme := f.normalizeName(name)
|
||||
|
||||
+46
-30
@@ -18,7 +18,6 @@ import (
|
||||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -30,7 +29,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// UnixZero sets the zero unix timestamp we want to compare against.
|
||||
// UnixZero sets the zero unix UTC timestamp we want to compare against.
|
||||
//
|
||||
// Unix 0 for an EST timezone is not equivalent to a UTC timezone.
|
||||
UnixZero = time.Unix(0, 0).UTC()
|
||||
)
|
||||
@@ -40,13 +40,19 @@ func init() {
|
||||
Default.Add("datetime", &dt, IsDateTime)
|
||||
}
|
||||
|
||||
// IsDateTime returns true when the string is a valid date-time
|
||||
// IsDateTime returns true when the string is a valid date-time.
|
||||
//
|
||||
// JSON datetime format consist of a date and a time separated by a "T", e.g. 2012-04-23T18:25:43.511Z.
|
||||
func IsDateTime(str string) bool {
|
||||
if len(str) < 4 {
|
||||
const (
|
||||
minDateTimeLength = 4
|
||||
minParts = 2
|
||||
)
|
||||
if len(str) < minDateTimeLength {
|
||||
return false
|
||||
}
|
||||
s := strings.Split(strings.ToLower(str), "t")
|
||||
if len(s) < 2 || !IsDate(s[0]) {
|
||||
if len(s) < minParts || !IsDate(s[0]) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -76,7 +82,7 @@ const (
|
||||
ISO8601TimeWithReducedPrecisionLocaltime = "2006-01-02T15:04"
|
||||
// ISO8601TimeUniversalSortableDateTimePattern represents a ISO8601 universal sortable date time pattern.
|
||||
ISO8601TimeUniversalSortableDateTimePattern = "2006-01-02 15:04:05"
|
||||
// short form of ISO8601TimeUniversalSortableDateTimePattern
|
||||
// ISO8601TimeUniversalSortableDateTimePatternShortForm is the short form of ISO8601TimeUniversalSortableDateTimePattern
|
||||
ISO8601TimeUniversalSortableDateTimePatternShortForm = "2006-01-02"
|
||||
// DateTimePattern pattern to match for the date-time format from http://tools.ietf.org/html/rfc3339#section-5.6
|
||||
DateTimePattern = `^([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$`
|
||||
@@ -91,7 +97,7 @@ var (
|
||||
// MarshalFormat sets the time resolution format used for marshaling time (set to milliseconds)
|
||||
MarshalFormat = RFC3339Millis
|
||||
|
||||
// NormalizeTimeForMarshal provides a normalization function on time befeore marshalling (e.g. time.UTC).
|
||||
// NormalizeTimeForMarshal provides a normalization function on time before marshalling (e.g. time.UTC).
|
||||
// By default, the time value is not changed.
|
||||
NormalizeTimeForMarshal = func(t time.Time) time.Time { return t }
|
||||
|
||||
@@ -116,7 +122,8 @@ func ParseDateTime(data string) (DateTime, error) {
|
||||
return DateTime{}, lastError
|
||||
}
|
||||
|
||||
// DateTime is a time but it serializes to ISO8601 format with millis
|
||||
// DateTime is a time but it serializes to ISO8601 format with millis.
|
||||
//
|
||||
// It knows how to read 3 different variations of a RFC3339 date time.
|
||||
// Most APIs we encounter want either millisecond or second precision times.
|
||||
// This just tries to make it worry-free.
|
||||
@@ -124,30 +131,35 @@ func ParseDateTime(data string) (DateTime, error) {
|
||||
// swagger:strfmt date-time
|
||||
type DateTime time.Time
|
||||
|
||||
// NewDateTime is a representation of zero value for DateTime type
|
||||
// NewDateTime is a representation of the UNIX epoch (January 1, 1970 00:00:00 UTC) for the [DateTime] type.
|
||||
//
|
||||
// Notice that this is not the zero value of the [DateTime] type.
|
||||
//
|
||||
// You may use [DateTime.IsUNIXZero] to check against this value.
|
||||
func NewDateTime() DateTime {
|
||||
return DateTime(time.Unix(0, 0).UTC())
|
||||
}
|
||||
|
||||
// MakeDateTime is a representation of the zero value of the [DateTime] type (January 1, year 1, 00:00:00 UTC).
|
||||
//
|
||||
// You may use [Datetime.IsZero] to check against this value.
|
||||
func MakeDateTime() DateTime {
|
||||
return DateTime(time.Time{})
|
||||
}
|
||||
|
||||
// String converts this time to a string
|
||||
func (t DateTime) String() string {
|
||||
return NormalizeTimeForMarshal(time.Time(t)).Format(MarshalFormat)
|
||||
}
|
||||
|
||||
// IsZero returns whether the date time is a zero value
|
||||
func (t *DateTime) IsZero() bool {
|
||||
if t == nil {
|
||||
return true
|
||||
}
|
||||
return time.Time(*t).IsZero()
|
||||
func (t DateTime) IsZero() bool {
|
||||
return time.Time(t).IsZero()
|
||||
}
|
||||
|
||||
// IsUnixZerom returns whether the date time is equivalent to time.Unix(0, 0).UTC().
|
||||
func (t *DateTime) IsUnixZero() bool {
|
||||
if t == nil {
|
||||
return true
|
||||
}
|
||||
return time.Time(*t).Equal(UnixZero)
|
||||
// IsUnixZero returns whether the date time is equivalent to time.Unix(0, 0).UTC().
|
||||
func (t DateTime) IsUnixZero() bool {
|
||||
return time.Time(t).Equal(UnixZero)
|
||||
}
|
||||
|
||||
// MarshalText implements the text marshaller interface
|
||||
@@ -178,7 +190,7 @@ func (t *DateTime) Scan(raw interface{}) error {
|
||||
case nil:
|
||||
*t = DateTime{}
|
||||
default:
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.DateTime from: %#v", v)
|
||||
return fmt.Errorf("cannot sql.Scan() strfmt.DateTime from: %#v: %w", v, ErrFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -232,20 +244,23 @@ func (t *DateTime) UnmarshalBSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
const bsonDateLength = 8
|
||||
|
||||
// MarshalBSONValue is an interface implemented by types that can marshal themselves
|
||||
// into a BSON document represented as bytes. The bytes returned must be a valid
|
||||
// BSON document if the error is nil.
|
||||
//
|
||||
// Marshals a DateTime as a bsontype.DateTime, an int64 representing
|
||||
// milliseconds since epoch.
|
||||
func (t DateTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
|
||||
// UnixNano cannot be used directly, the result of calling UnixNano on the zero
|
||||
// Time is undefined. Thats why we use time.Nanosecond() instead.
|
||||
|
||||
// Time is undefined. That's why we use time.Nanosecond() instead.
|
||||
tNorm := NormalizeTimeForMarshal(time.Time(t))
|
||||
i64 := tNorm.Unix()*1000 + int64(tNorm.Nanosecond())/1e6
|
||||
i64 := tNorm.UnixMilli()
|
||||
|
||||
buf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(buf, uint64(i64))
|
||||
buf := make([]byte, bsonDateLength)
|
||||
// int64 -> uint64 conversion is safe here
|
||||
binary.LittleEndian.PutUint64(buf, uint64(i64)) //nolint:gosec
|
||||
|
||||
return bson.TypeDateTime, buf, nil
|
||||
}
|
||||
@@ -260,13 +275,14 @@ func (t *DateTime) UnmarshalBSONValue(tpe bsontype.Type, data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(data) != 8 {
|
||||
return errors.New("bson date field length not exactly 8 bytes")
|
||||
if len(data) != bsonDateLength {
|
||||
return fmt.Errorf("bson date field length not exactly 8 bytes: %w", ErrFormat)
|
||||
}
|
||||
|
||||
i64 := int64(binary.LittleEndian.Uint64(data))
|
||||
// it's ok to get negative values after conversion
|
||||
i64 := int64(binary.LittleEndian.Uint64(data)) //nolint:gosec
|
||||
// TODO: Use bsonprim.DateTime.Time() method
|
||||
*t = DateTime(time.Unix(i64/1000, i64%1000*1000000))
|
||||
*t = DateTime(time.UnixMilli(i64))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+3
-4
@@ -4,7 +4,6 @@ import (
|
||||
cryptorand "crypto/rand"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
@@ -98,7 +97,7 @@ func NewULID() (ULID, error) {
|
||||
obj := ulidEntropyPool.Get()
|
||||
entropy, ok := obj.(io.Reader)
|
||||
if !ok {
|
||||
return u, fmt.Errorf("failed to cast %+v to io.Reader", obj)
|
||||
return u, fmt.Errorf("failed to cast %+v to io.Reader: %w", obj, ErrFormat)
|
||||
}
|
||||
|
||||
id, err := ulid.New(ulid.Now(), entropy)
|
||||
@@ -181,12 +180,12 @@ func (u *ULID) UnmarshalBSON(data []byte) error {
|
||||
if ud, ok := m["data"].(string); ok {
|
||||
id, err := ulid.ParseStrict(ud)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse bson bytes as ULID: %w", err)
|
||||
return fmt.Errorf("couldn't parse bson bytes as ULID: %w: %w", err, ErrFormat)
|
||||
}
|
||||
u.ULID = id
|
||||
return nil
|
||||
}
|
||||
return errors.New("couldn't unmarshal bson bytes as ULID")
|
||||
return fmt.Errorf("couldn't unmarshal bson bytes as ULID: %w", ErrFormat)
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver and writes its value into out.
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
ignore:
|
||||
- jsonutils/fixtures_test
|
||||
- jsonutils/adapters/ifaces/mocks
|
||||
- jsonutils/adapters/testintegration/benchmarks
|
||||
+72
-55
@@ -1,60 +1,77 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 3
|
||||
min-occurrences: 3
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- maligned
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gomoddirectives
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
- intrange
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- nlreturn
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tagliatelle
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- wsl_v5
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text.
|
||||
# Set to 0 to disable.
|
||||
# Default: 3
|
||||
max-same-issues: 0
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
all: false
|
||||
dir: '{{.InterfaceDir}}'
|
||||
filename: mocks_test.go
|
||||
force-file-write: true
|
||||
formatter: goimports
|
||||
include-auto-generated: false
|
||||
log-level: info
|
||||
structname: '{{.Mock}}{{.InterfaceName}}'
|
||||
pkgname: '{{.SrcPackageName}}'
|
||||
recursive: false
|
||||
require-template-schema-exists: true
|
||||
template: matryer
|
||||
template-schema: '{{.Template}}.schema.json'
|
||||
packages:
|
||||
github.com/go-openapi/swag/jsonutils/adapters/ifaces:
|
||||
config:
|
||||
dir: jsonutils/adapters/ifaces/mocks
|
||||
filename: mocks.go
|
||||
pkgname: 'mocks'
|
||||
force-file-write: true
|
||||
all: true
|
||||
github.com/go-openapi/swag/jsonutils/adapters/testintegration:
|
||||
config:
|
||||
inpackage: true
|
||||
dir: jsonutils/adapters/testintegration
|
||||
force-file-write: true
|
||||
all: true
|
||||
interfaces:
|
||||
EJMarshaler:
|
||||
EJUnmarshaler:
|
||||
+180
-11
@@ -1,23 +1,192 @@
|
||||
# Swag [](https://github.com/go-openapi/swag/actions?query=workflow%3A"go+test") [](https://codecov.io/gh/go-openapi/swag)
|
||||
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
|
||||
[](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/swag)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/swag)
|
||||
|
||||
Contains a bunch of helper functions for go-openapi and go-swagger projects.
|
||||
Package `swag` contains a bunch of helper functions for go-openapi and go-swagger projects.
|
||||
|
||||
You may also use it standalone for your projects.
|
||||
|
||||
* convert between value and pointers for builtin types
|
||||
* convert from string to builtin types (wraps strconv)
|
||||
* fast json concatenation
|
||||
* search in path
|
||||
* load from file or http
|
||||
* name mangling
|
||||
> **NOTE**
|
||||
> `swag` is one of the foundational building blocks of the go-openapi initiative.
|
||||
> Most repositories in `github.com/go-openapi/...` depend on it in some way.
|
||||
> And so does our CLI tool `github.com/go-swagger/go-swagger`,
|
||||
> as well as the code generated by this tool.
|
||||
|
||||
* [Contents](#contents)
|
||||
* [Dependencies](#dependencies)
|
||||
* [Release Notes](#release-notes)
|
||||
* [Note to contributors](#note-to-contributors)
|
||||
* [TODOs, suggestions and plans](#todos-suggestions-and-plans)
|
||||
|
||||
## Contents
|
||||
|
||||
`go-openapi/swag` exposes a collection of relatively independent modules.
|
||||
|
||||
Moving forward, no additional feature will be added to the `swag` API directly at the root package level,
|
||||
which remains there for backward-compatibility purposes. All exported top-level features are now deprecated.
|
||||
|
||||
Child modules will continue to evolve and some new ones may be added in the future.
|
||||
|
||||
| Module | Content | Main features |
|
||||
|---------------|---------|---------------|
|
||||
| `cmdutils` | utilities to work with CLIs ||
|
||||
| `conv` | type conversion utilities | convert between values and pointers for any types<br />convert from string to builtin types (wraps `strconv`)<br />require `./typeutils` (test dependency)<br /> |
|
||||
| `fileutils` | file utilities | |
|
||||
| `jsonname` | JSON utilities | infer JSON names from `go` properties<br /> |
|
||||
| `jsonutils` | JSON utilities | fast json concatenation<br />read and write JSON from and to dynamic `go` data structures<br />~require `github.com/mailru/easyjson`~<br /> |
|
||||
| `loading` | file loading | load from file or http<br />require `./yamlutils`<br /> |
|
||||
| `mangling` | safe name generation | name mangling for `go`<br /> |
|
||||
| `netutils` | networking utilities | host, port from address<br /> |
|
||||
| `stringutils` | `string` utilities | search in slice (with case-insensitive)<br />split/join query parameters as arrays<br /> |
|
||||
| `typeutils` | `go` types utilities | check the zero value for any type<br />safe check for a nil value<br /> |
|
||||
| `yamlutils` | YAML utilities | converting YAML to JSON<br />loading YAML into a dynamic YAML document<br />maintaining the original order of keys in YAML objects<br />require `./jsonutils`<br />~require `github.com/mailru/easyjson`~<br />require `go.yaml.in/yaml/v3`<br /> |
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
The root module `github.com/go-openapi/swag` at the repo level maintains a few
|
||||
dependencies outside of the standard library.
|
||||
|
||||
* YAML utilities depend on `go.yaml.in/yaml/v3`
|
||||
* JSON utilities depend on their registered adapter module:
|
||||
* by default, only the standard library is used
|
||||
* `github.com/mailru/easyjson` is now only a dependency for module
|
||||
`github.com/go-openapi/swag/jsonutils/adapters/easyjson/json`,
|
||||
for users willing to import that module.
|
||||
* integration tests and benchmarks use all the dependencies are published as their own module
|
||||
* other dependencies are test dependencies drawn from `github.com/stretchr/testify`
|
||||
|
||||
## Release notes
|
||||
|
||||
### v0.25.1
|
||||
|
||||
* fixes a data race that could occur when using the standard library implementation of a JSON ordered map
|
||||
|
||||
### v0.25.0
|
||||
|
||||
**New with this release**:
|
||||
|
||||
* requires `go1.24`, as iterators are being introduced
|
||||
* removes the dependency to `mailru/easyjson` by default (#68)
|
||||
* functionality remains the same, but performance may somewhat degrade for applications
|
||||
that relied on `easyjson`
|
||||
* users of the JSON or YAML utilities who want to use `easyjson` as their prefered JSON serializer library
|
||||
will be able to do so by registering this the corresponding JSON adapter at runtime. See below.
|
||||
* ordered keys in JSON and YAML objects: this feature used to rely solely on `easyjson`.
|
||||
With this release, an implementation relying on the standard `encoding/json` is provided.
|
||||
* an independent [benchmark](./jsonutils/adapters/testintegration/benchmarks/README.md) to compare the different adapters
|
||||
* improves the "float is integer" check (`conv.IsFloat64AJSONInteger`) (#59)
|
||||
* removes the _direct_ dependency to `gopkg.in/yaml.v3` (indirect dependency is still incurred through `stretchr/testify`) (#127)
|
||||
* exposed `conv.IsNil()` (previously kept private): a safe nil check (accounting for the "non-nil interface with nil value" nonsensical go trick)
|
||||
|
||||
**What coming next?**
|
||||
|
||||
Moving forward, we want to :
|
||||
* provide an implementation of the JSON adapter based on `encoding/json/v2`, for `go1.25` builds.
|
||||
* provide similar implementations for `goccy/go-json` and `jsoniterator/go`, and perhaps some other
|
||||
similar libraries may be interesting too.
|
||||
|
||||
|
||||
This repo has only few dependencies outside of the standard library:
|
||||
**How to explicitly register a dependency at runtime**?
|
||||
|
||||
* YAML utilities depend on `gopkg.in/yaml.v3`
|
||||
* `github.com/mailru/easyjson v0.7.7`
|
||||
The following would maintain how JSON utilities proposed by `swag` used work, up to `v0.24.1`.
|
||||
|
||||
```go
|
||||
import "github.com/go-openapi/swag/jsonutils/adapters/easyjson/json"
|
||||
|
||||
func init() {
|
||||
json.Register()
|
||||
}
|
||||
```
|
||||
|
||||
Subsequent calls to `jsonutils.ReadJSON()` or `jsonutils.WriteJSON()` will switch to `easyjson`
|
||||
whenever the passed data structures implement the `easyjson.Unmarshaler` or `easyjson.Marshaler` respectively,
|
||||
or fallback to the standard library.
|
||||
|
||||
### v0.24.0
|
||||
|
||||
With this release, we have largely modernized the API of `swag`:
|
||||
|
||||
* The traditional `swag` API is still supported: code that imports `swag` will still
|
||||
compile and work the same.
|
||||
* A deprecation notice is published to encourage consumers of this library to adopt
|
||||
the newer API
|
||||
* **Deprecation notice**
|
||||
* configuration through global variables is now deprecated, in favor of options passed as parameters
|
||||
* all helper functions are moved to more specialized packages, which are exposed as
|
||||
go modules. Importing such a module would reduce the footprint of dependencies.
|
||||
* _all_ functions, variables, constants exposed by the deprecated API have now moved, so
|
||||
that consumers of the new API no longer need to import github.com/go-openapi/swag, but
|
||||
should import the desired sub-module(s).
|
||||
|
||||
**New with this release**:
|
||||
|
||||
* [x] type converters and pointer to value helpers now support generic types
|
||||
* [x] name mangling now support pluralized initialisms (issue #46)
|
||||
Strings like "contact IDs" are now recognized as such a plural form and mangled as a linter would expect.
|
||||
* [x] performance: small improvements to reduce the overhead of convert/format wrappers (see issues #110, or PR #108)
|
||||
* [x] performance: name mangling utilities run ~ 10% faster (PR #115)
|
||||
|
||||
---
|
||||
|
||||
## Note to contributors
|
||||
|
||||
A mono-repo structure comes with some unavoidable extra pains...
|
||||
|
||||
* Testing
|
||||
|
||||
> The usual `go test ./...` command, run from the root of this repo won't work any longer to test all submodules.
|
||||
>
|
||||
> Each module constitutes an independant unit of test. So you have to run `go test` inside each module.
|
||||
> Or you may take a look at how this is achieved by CI
|
||||
> [here] https://github.com/go-openapi/swag/blob/master/.github/workflows/go-test.yml).
|
||||
>
|
||||
> There are also some alternative tricks using `go work`, for local development, if you feel comfortable with
|
||||
> go workspaces. Perhaps some day, we'll have a `go work test` to run all tests without any hack.
|
||||
|
||||
* Releasing
|
||||
|
||||
> Each module follows its own independant module versioning.
|
||||
>
|
||||
> So you have tags like `mangling/v0.24.0`, `fileutils/v0.24.0` etc that are used by `go mod` and `go get`
|
||||
> to refer to the tagged version of each module specifically.
|
||||
>
|
||||
> This means we may release patches etc to each module independently.
|
||||
>
|
||||
> We'd like to adopt the rule that modules in this repo would only differ by a patch version
|
||||
> (e.g. `v0.24.5` vs `v0.24.3`), and we'll level all modules whenever a minor version is introduced.
|
||||
>
|
||||
> A script in `./hack` is provided to tag all modules with the same version in one go.
|
||||
|
||||
* Continuous integration
|
||||
|
||||
> At this moment, all tests in all modules are systematically run over the full test matrix (3 platform x 2 go releases).
|
||||
> This generates quite a lot of jobs.
|
||||
>
|
||||
> We ought to reduce the number of jobs required to test a PR focused on only a few modules.
|
||||
|
||||
## Todos, suggestions and plans
|
||||
|
||||
All kinds of contributions are welcome.
|
||||
|
||||
A few ideas:
|
||||
|
||||
* [x] Complete the split of dependencies to isolate easyjson from the rest
|
||||
* [x] Improve CI to reduce needed tests
|
||||
* [x] Replace dependency to `gopkg.in/yaml.v3` (`yamlutil`)
|
||||
* [ ] Improve mangling utilities (improve readability, support for capitalized words,
|
||||
better word substitution for non-letter symbols...)
|
||||
* [ ] Move back to this common shared pot a few of the technical features introduced by go-swagger independently
|
||||
(e.g. mangle go package names, search package with go modules support, ...)
|
||||
* [ ] Apply a similar mono-repo approach to go-openapi/strfmt which suffer from similar woes: bloated API,
|
||||
imposed dependency to some database driver.
|
||||
* [ ] Adapt `go-swagger` (incl. generated code) to the new `swag` API.
|
||||
* [ ] Factorize some tests, as there is a lot of redundant testing code in `jsonutils`
|
||||
* [ ] Benchmark & profiling: publish independently the tool built to analyze and chart benchmarks (e.g. similar to `benchvisual`)
|
||||
* [ ] more thorough testing for nil / null case
|
||||
* [ ] ci pipeline to manage releases
|
||||
* [ ] cleaner mockery generation (doesn't work out of the box for all sub-modules)
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
fix data race https://github.com/go-openapi/swag/actions/runs/17989156861/job/51174860188
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cmdutils
|
||||
|
||||
// CommandLineOptionsGroup represents a group of user-defined command line options.
|
||||
//
|
||||
// This is for instance used to configure command line arguments in API servers generated by go-swagger.
|
||||
type CommandLineOptionsGroup struct {
|
||||
ShortDescription string
|
||||
LongDescription string
|
||||
Options interface{}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package cmdutils brings helpers for CLIs produced by go-openapi
|
||||
package cmdutils
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import "github.com/go-openapi/swag/cmdutils"
|
||||
|
||||
// CommandLineOptionsGroup represents a group of user-defined command line options.
|
||||
//
|
||||
// Deprecated: use [cmdutils.CommandLineOptionsGroup] instead.
|
||||
type CommandLineOptionsGroup = cmdutils.CommandLineOptionsGroup
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package conv
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
|
||||
const (
|
||||
maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1
|
||||
minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1
|
||||
epsilon float64 = 1e-9
|
||||
)
|
||||
|
||||
// IsFloat64AJSONInteger allows for integers [-2^53, 2^53-1] inclusive.
|
||||
func IsFloat64AJSONInteger(f float64) bool {
|
||||
if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat {
|
||||
return false
|
||||
}
|
||||
rounded := math.Round(f)
|
||||
if f == rounded {
|
||||
return true
|
||||
}
|
||||
if rounded == 0 { // f = 0.0 exited above
|
||||
return false
|
||||
}
|
||||
|
||||
diff := math.Abs(f - rounded)
|
||||
if diff == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
// relative error Abs{f - Round(f)) / Round(f)} < ε ; Round(f)
|
||||
return diff < epsilon*math.Abs(rounded)
|
||||
}
|
||||
|
||||
// ConvertFloat turns a string into a float numerical value.
|
||||
func ConvertFloat[T Float](str string) (T, error) {
|
||||
var v T
|
||||
f, err := strconv.ParseFloat(str, bitsize(v))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return T(f), nil
|
||||
}
|
||||
|
||||
// ConvertInteger turns a string into a signed integer.
|
||||
func ConvertInteger[T Signed](str string) (T, error) {
|
||||
var v T
|
||||
f, err := strconv.ParseInt(str, 10, bitsize(v))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return T(f), nil
|
||||
}
|
||||
|
||||
// ConvertUinteger turns a string into an unsigned integer.
|
||||
func ConvertUinteger[T Unsigned](str string) (T, error) {
|
||||
var v T
|
||||
f, err := strconv.ParseUint(str, 10, bitsize(v))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return T(f), nil
|
||||
}
|
||||
|
||||
// ConvertBool turns a string into a boolean.
|
||||
//
|
||||
// It supports a few more "true" strings than [strconv.ParseBool]:
|
||||
//
|
||||
// - it is not case sensitive ("trUe" or "FalsE" work)
|
||||
// - "ok", "yes", "y", "on", "selected", "checked", "enabled" are all true
|
||||
// - everything that is not true is false: there is never an actual error returned
|
||||
func ConvertBool(str string) (bool, error) {
|
||||
switch strings.ToLower(str) {
|
||||
case "true",
|
||||
"1",
|
||||
"yes",
|
||||
"ok",
|
||||
"y",
|
||||
"on",
|
||||
"selected",
|
||||
"checked",
|
||||
"t",
|
||||
"enabled":
|
||||
return true, nil
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertFloat32 turns a string into a float32.
|
||||
func ConvertFloat32(str string) (float32, error) { return ConvertFloat[float32](str) }
|
||||
|
||||
// ConvertFloat64 turns a string into a float64
|
||||
func ConvertFloat64(str string) (float64, error) { return ConvertFloat[float64](str) }
|
||||
|
||||
// ConvertInt8 turns a string into an int8
|
||||
func ConvertInt8(str string) (int8, error) { return ConvertInteger[int8](str) }
|
||||
|
||||
// ConvertInt16 turns a string into an int16
|
||||
func ConvertInt16(str string) (int16, error) {
|
||||
i, err := strconv.ParseInt(str, 10, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int16(i), nil
|
||||
}
|
||||
|
||||
// ConvertInt32 turns a string into an int32
|
||||
func ConvertInt32(str string) (int32, error) {
|
||||
i, err := strconv.ParseInt(str, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(i), nil
|
||||
}
|
||||
|
||||
// ConvertInt64 turns a string into an int64
|
||||
func ConvertInt64(str string) (int64, error) {
|
||||
return strconv.ParseInt(str, 10, 64)
|
||||
}
|
||||
|
||||
// ConvertUint8 turns a string into an uint8
|
||||
func ConvertUint8(str string) (uint8, error) {
|
||||
i, err := strconv.ParseUint(str, 10, 8)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint8(i), nil
|
||||
}
|
||||
|
||||
// ConvertUint16 turns a string into an uint16
|
||||
func ConvertUint16(str string) (uint16, error) {
|
||||
i, err := strconv.ParseUint(str, 10, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint16(i), nil
|
||||
}
|
||||
|
||||
// ConvertUint32 turns a string into an uint32
|
||||
func ConvertUint32(str string) (uint32, error) {
|
||||
i, err := strconv.ParseUint(str, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(i), nil
|
||||
}
|
||||
|
||||
// ConvertUint64 turns a string into an uint64
|
||||
func ConvertUint64(str string) (uint64, error) {
|
||||
return strconv.ParseUint(str, 10, 64)
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package conv
|
||||
|
||||
// The original version of this file, eons ago, was taken from the aws go sdk
|
||||
|
||||
// Pointer returns a pointer to the value passed in.
|
||||
func Pointer[T any](v T) *T {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Value returns a shallow copy of the value of the pointer passed in.
|
||||
//
|
||||
// If the pointer is nil, the returned value is the zero value.
|
||||
func Value[T any](v *T) T {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
|
||||
var zero T
|
||||
return zero
|
||||
}
|
||||
|
||||
// PointerSlice converts a slice of values into a slice of pointers.
|
||||
func PointerSlice[T any](src []T) []*T {
|
||||
dst := make([]*T, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// ValueSlice converts a slice of pointers into a slice of values.
|
||||
//
|
||||
// nil elements are zero values.
|
||||
func ValueSlice[T any](src []*T) []T {
|
||||
dst := make([]T, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// PointerMap converts a map of values into a map of pointers.
|
||||
func PointerMap[K comparable, T any](src map[K]T) map[K]*T {
|
||||
dst := make(map[K]*T)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// ValueMap converts a map of pointers into a map of values.
|
||||
//
|
||||
// nil elements are skipped.
|
||||
func ValueMap[K comparable, T any](src map[K]*T) map[K]T {
|
||||
dst := make(map[K]T)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package conv exposes utilities to convert types.
|
||||
//
|
||||
// The Convert and Format families of functions are essentially a shorthand to [strconv] functions,
|
||||
// using the decimal representation of numbers.
|
||||
//
|
||||
// Features:
|
||||
//
|
||||
// - from string representation to value ("Convert*") and reciprocally ("Format*")
|
||||
// - from pointer to value ([Value]) and reciprocally ([Pointer])
|
||||
// - from slice of values to slice of pointers ([PointerSlice]) and reciprocally ([ValueSlice])
|
||||
// - from map of values to map of pointers ([PointerMap]) and reciprocally ([ValueMap])
|
||||
package conv
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package conv
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// FormatInteger turns an integer type into a string.
|
||||
func FormatInteger[T Signed](value T) string {
|
||||
return strconv.FormatInt(int64(value), 10)
|
||||
}
|
||||
|
||||
// FormatUinteger turns an unsigned integer type into a string.
|
||||
func FormatUinteger[T Unsigned](value T) string {
|
||||
return strconv.FormatUint(uint64(value), 10)
|
||||
}
|
||||
|
||||
// FormatFloat turns a floating point numerical value into a string.
|
||||
func FormatFloat[T Float](value T) string {
|
||||
return strconv.FormatFloat(float64(value), 'f', -1, bitsize(value))
|
||||
}
|
||||
|
||||
// FormatBool turns a boolean into a string.
|
||||
func FormatBool(value bool) string {
|
||||
return strconv.FormatBool(value)
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package conv
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// bitsize returns the size in bits of a type.
|
||||
//
|
||||
// NOTE: [unsafe.SizeOf] simply returns the size in bytes of the value.
|
||||
// For primitive types T, the generic stencil is precompiled and this value
|
||||
// is resolved at compile time, resulting in an immediate call to [strconv.ParseFloat].
|
||||
//
|
||||
// We may leave up to the go compiler to simplify this function into a
|
||||
// constant value, which happens in practice at least for primitive types
|
||||
// (e.g. numerical types).
|
||||
func bitsize[T Numerical](value T) int {
|
||||
const bitsPerByte = 8
|
||||
return int(unsafe.Sizeof(value)) * bitsPerByte
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package conv
|
||||
|
||||
type (
|
||||
// these type constraints are redefined after golang.org/x/exp/constraints,
|
||||
// because importing that package causes an undesired go upgrade.
|
||||
|
||||
// Signed integer types, cf. [golang.org/x/exp/constraints.Signed]
|
||||
Signed interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64
|
||||
}
|
||||
|
||||
// Unsigned integer types, cf. [golang.org/x/exp/constraints.Unsigned]
|
||||
Unsigned interface {
|
||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
|
||||
}
|
||||
|
||||
// Float numerical types, cf. [golang.org/x/exp/constraints.Float]
|
||||
Float interface {
|
||||
~float32 | ~float64
|
||||
}
|
||||
|
||||
// Numerical types
|
||||
Numerical interface {
|
||||
Signed | Unsigned | Float
|
||||
}
|
||||
)
|
||||
+497
@@ -0,0 +1,497 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/swag/conv"
|
||||
)
|
||||
|
||||
// IsFloat64AJSONInteger allows for integers [-2^53, 2^53-1] inclusive.
|
||||
//
|
||||
// Deprecated: use [conv.IsFloat64AJSONInteger] instead.
|
||||
func IsFloat64AJSONInteger(f float64) bool { return conv.IsFloat64AJSONInteger(f) }
|
||||
|
||||
// ConvertBool turns a string into a boolean.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertBool] instead.
|
||||
func ConvertBool(str string) (bool, error) { return conv.ConvertBool(str) }
|
||||
|
||||
// ConvertFloat32 turns a string into a float32.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertFloat32] instead. Alternatively, you may use the generic version [conv.ConvertFloat].
|
||||
func ConvertFloat32(str string) (float32, error) { return conv.ConvertFloat[float32](str) }
|
||||
|
||||
// ConvertFloat64 turns a string into a float64.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertFloat64] instead. Alternatively, you may use the generic version [conv.ConvertFloat].
|
||||
func ConvertFloat64(str string) (float64, error) { return conv.ConvertFloat[float64](str) }
|
||||
|
||||
// ConvertInt8 turns a string into an int8.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertInt8] instead. Alternatively, you may use the generic version [conv.ConvertInteger].
|
||||
func ConvertInt8(str string) (int8, error) { return conv.ConvertInteger[int8](str) }
|
||||
|
||||
// ConvertInt16 turns a string into an int16.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertInt16] instead. Alternatively, you may use the generic version [conv.ConvertInteger].
|
||||
func ConvertInt16(str string) (int16, error) { return conv.ConvertInteger[int16](str) }
|
||||
|
||||
// ConvertInt32 turns a string into an int32.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertInt32] instead. Alternatively, you may use the generic version [conv.ConvertInteger].
|
||||
func ConvertInt32(str string) (int32, error) { return conv.ConvertInteger[int32](str) }
|
||||
|
||||
// ConvertInt64 turns a string into an int64.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertInt64] instead. Alternatively, you may use the generic version [conv.ConvertInteger].
|
||||
func ConvertInt64(str string) (int64, error) { return conv.ConvertInteger[int64](str) }
|
||||
|
||||
// ConvertUint8 turns a string into an uint8.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertUint8] instead. Alternatively, you may use the generic version [conv.ConvertUinteger].
|
||||
func ConvertUint8(str string) (uint8, error) { return conv.ConvertUinteger[uint8](str) }
|
||||
|
||||
// ConvertUint16 turns a string into an uint16.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertUint16] instead. Alternatively, you may use the generic version [conv.ConvertUinteger].
|
||||
func ConvertUint16(str string) (uint16, error) { return conv.ConvertUinteger[uint16](str) }
|
||||
|
||||
// ConvertUint32 turns a string into an uint32.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertUint32] instead. Alternatively, you may use the generic version [conv.ConvertUinteger].
|
||||
func ConvertUint32(str string) (uint32, error) { return conv.ConvertUinteger[uint32](str) }
|
||||
|
||||
// ConvertUint64 turns a string into an uint64.
|
||||
//
|
||||
// Deprecated: use [conv.ConvertUint64] instead. Alternatively, you may use the generic version [conv.ConvertUinteger].
|
||||
func ConvertUint64(str string) (uint64, error) { return conv.ConvertUinteger[uint64](str) }
|
||||
|
||||
// FormatBool turns a boolean into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatBool] instead.
|
||||
func FormatBool(value bool) string { return conv.FormatBool(value) }
|
||||
|
||||
// FormatFloat32 turns a float32 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatFloat] instead.
|
||||
func FormatFloat32(value float32) string { return conv.FormatFloat(value) }
|
||||
|
||||
// FormatFloat64 turns a float64 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatFloat] instead.
|
||||
func FormatFloat64(value float64) string { return conv.FormatFloat(value) }
|
||||
|
||||
// FormatInt8 turns an int8 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatInteger] instead.
|
||||
func FormatInt8(value int8) string { return conv.FormatInteger(value) }
|
||||
|
||||
// FormatInt16 turns an int16 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatInteger] instead.
|
||||
func FormatInt16(value int16) string { return conv.FormatInteger(value) }
|
||||
|
||||
// FormatInt32 turns an int32 into a string
|
||||
//
|
||||
// Deprecated: use [conv.FormatInteger] instead.
|
||||
func FormatInt32(value int32) string { return conv.FormatInteger(value) }
|
||||
|
||||
// FormatInt64 turns an int64 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatInteger] instead.
|
||||
func FormatInt64(value int64) string { return conv.FormatInteger(value) }
|
||||
|
||||
// FormatUint8 turns an uint8 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatUinteger] instead.
|
||||
func FormatUint8(value uint8) string { return conv.FormatUinteger(value) }
|
||||
|
||||
// FormatUint16 turns an uint16 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatUinteger] instead.
|
||||
func FormatUint16(value uint16) string { return conv.FormatUinteger(value) }
|
||||
|
||||
// FormatUint32 turns an uint32 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatUinteger] instead.
|
||||
func FormatUint32(value uint32) string { return conv.FormatUinteger(value) }
|
||||
|
||||
// FormatUint64 turns an uint64 into a string.
|
||||
//
|
||||
// Deprecated: use [conv.FormatUinteger] instead.
|
||||
func FormatUint64(value uint64) string { return conv.FormatUinteger(value) }
|
||||
|
||||
// String turn a pointer to of the string value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func String(v string) *string { return conv.Pointer(v) }
|
||||
|
||||
// StringValue turn the value of the string pointer passed in or
|
||||
// "" if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func StringValue(v *string) string { return conv.Value(v) }
|
||||
|
||||
// StringSlice converts a slice of string values into a slice of string pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func StringSlice(src []string) []*string { return conv.PointerSlice(src) }
|
||||
|
||||
// StringValueSlice converts a slice of string pointers into a slice of string values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func StringValueSlice(src []*string) []string { return conv.ValueSlice(src) }
|
||||
|
||||
// StringMap converts a string map of string values into a string map of string pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func StringMap(src map[string]string) map[string]*string { return conv.PointerMap(src) }
|
||||
|
||||
// StringValueMap converts a string map of string pointers into a string map of string values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func StringValueMap(src map[string]*string) map[string]string { return conv.ValueMap(src) }
|
||||
|
||||
// Bool turn a pointer to of the bool value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Bool(v bool) *bool { return conv.Pointer(v) }
|
||||
|
||||
// BoolValue turn the value of the bool pointer passed in or false if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func BoolValue(v *bool) bool { return conv.Value(v) }
|
||||
|
||||
// BoolSlice converts a slice of bool values into a slice of bool pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func BoolSlice(src []bool) []*bool { return conv.PointerSlice(src) }
|
||||
|
||||
// BoolValueSlice converts a slice of bool pointers into a slice of bool values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func BoolValueSlice(src []*bool) []bool { return conv.ValueSlice(src) }
|
||||
|
||||
// BoolMap converts a string map of bool values into a string map of bool pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func BoolMap(src map[string]bool) map[string]*bool { return conv.PointerMap(src) }
|
||||
|
||||
// BoolValueMap converts a string map of bool pointers into a string map of bool values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func BoolValueMap(src map[string]*bool) map[string]bool { return conv.ValueMap(src) }
|
||||
|
||||
// Int turn a pointer to of the int value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Int(v int) *int { return conv.Pointer(v) }
|
||||
|
||||
// IntValue turn the value of the int pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func IntValue(v *int) int { return conv.Value(v) }
|
||||
|
||||
// IntSlice converts a slice of int values into a slice of int pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func IntSlice(src []int) []*int { return conv.PointerSlice(src) }
|
||||
|
||||
// IntValueSlice converts a slice of int pointers into a slice of int values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func IntValueSlice(src []*int) []int { return conv.ValueSlice(src) }
|
||||
|
||||
// IntMap converts a string map of int values into a string map of int pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func IntMap(src map[string]int) map[string]*int { return conv.PointerMap(src) }
|
||||
|
||||
// IntValueMap converts a string map of int pointers into a string map of int values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func IntValueMap(src map[string]*int) map[string]int { return conv.ValueMap(src) }
|
||||
|
||||
// Int32 turn a pointer to of the int32 value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Int32(v int32) *int32 { return conv.Pointer(v) }
|
||||
|
||||
// Int32Value turn the value of the int32 pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func Int32Value(v *int32) int32 { return conv.Value(v) }
|
||||
|
||||
// Int32Slice converts a slice of int32 values into a slice of int32 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func Int32Slice(src []int32) []*int32 { return conv.PointerSlice(src) }
|
||||
|
||||
// Int32ValueSlice converts a slice of int32 pointers into a slice of int32 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func Int32ValueSlice(src []*int32) []int32 { return conv.ValueSlice(src) }
|
||||
|
||||
// Int32Map converts a string map of int32 values into a string map of int32 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func Int32Map(src map[string]int32) map[string]*int32 { return conv.PointerMap(src) }
|
||||
|
||||
// Int32ValueMap converts a string map of int32 pointers into a string map of int32 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func Int32ValueMap(src map[string]*int32) map[string]int32 { return conv.ValueMap(src) }
|
||||
|
||||
// Int64 turn a pointer to of the int64 value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Int64(v int64) *int64 { return conv.Pointer(v) }
|
||||
|
||||
// Int64Value turn the value of the int64 pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func Int64Value(v *int64) int64 { return conv.Value(v) }
|
||||
|
||||
// Int64Slice converts a slice of int64 values into a slice of int64 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func Int64Slice(src []int64) []*int64 { return conv.PointerSlice(src) }
|
||||
|
||||
// Int64ValueSlice converts a slice of int64 pointers into a slice of int64 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func Int64ValueSlice(src []*int64) []int64 { return conv.ValueSlice(src) }
|
||||
|
||||
// Int64Map converts a string map of int64 values into a string map of int64 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func Int64Map(src map[string]int64) map[string]*int64 { return conv.PointerMap(src) }
|
||||
|
||||
// Int64ValueMap converts a string map of int64 pointers into a string map of int64 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func Int64ValueMap(src map[string]*int64) map[string]int64 { return conv.ValueMap(src) }
|
||||
|
||||
// Uint16 turn a pointer to of the uint16 value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Uint16(v uint16) *uint16 { return conv.Pointer(v) }
|
||||
|
||||
// Uint16Value turn the value of the uint16 pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func Uint16Value(v *uint16) uint16 { return conv.Value(v) }
|
||||
|
||||
// Uint16Slice converts a slice of uint16 values into a slice of uint16 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func Uint16Slice(src []uint16) []*uint16 { return conv.PointerSlice(src) }
|
||||
|
||||
// Uint16ValueSlice converts a slice of uint16 pointers into a slice of uint16 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func Uint16ValueSlice(src []*uint16) []uint16 { return conv.ValueSlice(src) }
|
||||
|
||||
// Uint16Map converts a string map of uint16 values into a string map of uint16 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func Uint16Map(src map[string]uint16) map[string]*uint16 { return conv.PointerMap(src) }
|
||||
|
||||
// Uint16ValueMap converts a string map of uint16 pointers into a string map of uint16 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func Uint16ValueMap(src map[string]*uint16) map[string]uint16 { return conv.ValueMap(src) }
|
||||
|
||||
// Uint turn a pointer to of the uint value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Uint(v uint) *uint { return conv.Pointer(v) }
|
||||
|
||||
// UintValue turn the value of the uint pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func UintValue(v *uint) uint { return conv.Value(v) }
|
||||
|
||||
// UintSlice converts a slice of uint values into a slice of uint pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func UintSlice(src []uint) []*uint { return conv.PointerSlice(src) }
|
||||
|
||||
// UintValueSlice converts a slice of uint pointers into a slice of uint values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func UintValueSlice(src []*uint) []uint { return conv.ValueSlice(src) }
|
||||
|
||||
// UintMap converts a string map of uint values into a string map of uint pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func UintMap(src map[string]uint) map[string]*uint { return conv.PointerMap(src) }
|
||||
|
||||
// UintValueMap converts a string map of uint pointers into a string map of uint values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func UintValueMap(src map[string]*uint) map[string]uint { return conv.ValueMap(src) }
|
||||
|
||||
// Uint32 turn a pointer to of the uint32 value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Uint32(v uint32) *uint32 { return conv.Pointer(v) }
|
||||
|
||||
// Uint32Value turn the value of the uint32 pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func Uint32Value(v *uint32) uint32 { return conv.Value(v) }
|
||||
|
||||
// Uint32Slice converts a slice of uint32 values into a slice of uint32 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func Uint32Slice(src []uint32) []*uint32 { return conv.PointerSlice(src) }
|
||||
|
||||
// Uint32ValueSlice converts a slice of uint32 pointers into a slice of uint32 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func Uint32ValueSlice(src []*uint32) []uint32 { return conv.ValueSlice(src) }
|
||||
|
||||
// Uint32Map converts a string map of uint32 values into a string map of uint32 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func Uint32Map(src map[string]uint32) map[string]*uint32 { return conv.PointerMap(src) }
|
||||
|
||||
// Uint32ValueMap converts a string map of uint32 pointers into a string map of uint32 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 { return conv.ValueMap(src) }
|
||||
|
||||
// Uint64 turn a pointer to of the uint64 value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Uint64(v uint64) *uint64 { return conv.Pointer(v) }
|
||||
|
||||
// Uint64Value turn the value of the uint64 pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func Uint64Value(v *uint64) uint64 { return conv.Value(v) }
|
||||
|
||||
// Uint64Slice converts a slice of uint64 values into a slice of uint64 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func Uint64Slice(src []uint64) []*uint64 { return conv.PointerSlice(src) }
|
||||
|
||||
// Uint64ValueSlice converts a slice of uint64 pointers into a slice of uint64 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func Uint64ValueSlice(src []*uint64) []uint64 { return conv.ValueSlice(src) }
|
||||
|
||||
// Uint64Map converts a string map of uint64 values into a string map of uint64 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func Uint64Map(src map[string]uint64) map[string]*uint64 { return conv.PointerMap(src) }
|
||||
|
||||
// Uint64ValueMap converts a string map of uint64 pointers into a string map of uint64 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 { return conv.ValueMap(src) }
|
||||
|
||||
// Float32 turn a pointer to of the float32 value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Float32(v float32) *float32 { return conv.Pointer(v) }
|
||||
|
||||
// Float32Value turn the value of the float32 pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func Float32Value(v *float32) float32 { return conv.Value(v) }
|
||||
|
||||
// Float32Slice converts a slice of float32 values into a slice of float32 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func Float32Slice(src []float32) []*float32 { return conv.PointerSlice(src) }
|
||||
|
||||
// Float32ValueSlice converts a slice of float32 pointers into a slice of float32 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func Float32ValueSlice(src []*float32) []float32 { return conv.ValueSlice(src) }
|
||||
|
||||
// Float32Map converts a string map of float32 values into a string map of float32 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func Float32Map(src map[string]float32) map[string]*float32 { return conv.PointerMap(src) }
|
||||
|
||||
// Float32ValueMap converts a string map of float32 pointers into a string map of float32 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func Float32ValueMap(src map[string]*float32) map[string]float32 { return conv.ValueMap(src) }
|
||||
|
||||
// Float64 turn a pointer to of the float64 value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Float64(v float64) *float64 { return conv.Pointer(v) }
|
||||
|
||||
// Float64Value turn the value of the float64 pointer passed in or 0 if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func Float64Value(v *float64) float64 { return conv.Value(v) }
|
||||
|
||||
// Float64Slice converts a slice of float64 values into a slice of float64 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func Float64Slice(src []float64) []*float64 { return conv.PointerSlice(src) }
|
||||
|
||||
// Float64ValueSlice converts a slice of float64 pointers into a slice of float64 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func Float64ValueSlice(src []*float64) []float64 { return conv.ValueSlice(src) }
|
||||
|
||||
// Float64Map converts a string map of float64 values into a string map of float64 pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func Float64Map(src map[string]float64) map[string]*float64 { return conv.PointerMap(src) }
|
||||
|
||||
// Float64ValueMap converts a string map of float64 pointers into a string map of float64 values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func Float64ValueMap(src map[string]*float64) map[string]float64 { return conv.ValueMap(src) }
|
||||
|
||||
// Time turn a pointer to of the time.Time value passed in.
|
||||
//
|
||||
// Deprecated: use [conv.Pointer] instead.
|
||||
func Time(v time.Time) *time.Time { return conv.Pointer(v) }
|
||||
|
||||
// TimeValue turn the value of the time.Time pointer passed in or time.Time{} if the pointer is nil.
|
||||
//
|
||||
// Deprecated: use [conv.Value] instead.
|
||||
func TimeValue(v *time.Time) time.Time { return conv.Value(v) }
|
||||
|
||||
// TimeSlice converts a slice of time.Time values into a slice of time.Time pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerSlice] instead.
|
||||
func TimeSlice(src []time.Time) []*time.Time { return conv.PointerSlice(src) }
|
||||
|
||||
// TimeValueSlice converts a slice of time.Time pointers into a slice of time.Time values
|
||||
//
|
||||
// Deprecated: use [conv.ValueSlice] instead.
|
||||
func TimeValueSlice(src []*time.Time) []time.Time { return conv.ValueSlice(src) }
|
||||
|
||||
// TimeMap converts a string map of time.Time values into a string map of time.Time pointers.
|
||||
//
|
||||
// Deprecated: use [conv.PointerMap] instead.
|
||||
func TimeMap(src map[string]time.Time) map[string]*time.Time { return conv.PointerMap(src) }
|
||||
|
||||
// TimeValueMap converts a string map of time.Time pointers into a string map of time.Time values.
|
||||
//
|
||||
// Deprecated: use [conv.ValueMap] instead.
|
||||
func TimeValueMap(src map[string]*time.Time) map[string]time.Time { return conv.ValueMap(src) }
|
||||
-208
@@ -1,208 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
|
||||
const (
|
||||
maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1
|
||||
minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1
|
||||
epsilon float64 = 1e-9
|
||||
)
|
||||
|
||||
// IsFloat64AJSONInteger allow for integers [-2^53, 2^53-1] inclusive
|
||||
func IsFloat64AJSONInteger(f float64) bool {
|
||||
if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat {
|
||||
return false
|
||||
}
|
||||
fa := math.Abs(f)
|
||||
g := float64(uint64(f))
|
||||
ga := math.Abs(g)
|
||||
|
||||
diff := math.Abs(f - g)
|
||||
|
||||
// more info: https://floating-point-gui.de/errors/comparison/#look-out-for-edge-cases
|
||||
switch {
|
||||
case f == g: // best case
|
||||
return true
|
||||
case f == float64(int64(f)) || f == float64(uint64(f)): // optimistic case
|
||||
return true
|
||||
case f == 0 || g == 0 || diff < math.SmallestNonzeroFloat64: // very close to 0 values
|
||||
return diff < (epsilon * math.SmallestNonzeroFloat64)
|
||||
}
|
||||
// check the relative error
|
||||
return diff/math.Min(fa+ga, math.MaxFloat64) < epsilon
|
||||
}
|
||||
|
||||
var evaluatesAsTrue map[string]struct{}
|
||||
|
||||
func init() {
|
||||
evaluatesAsTrue = map[string]struct{}{
|
||||
"true": {},
|
||||
"1": {},
|
||||
"yes": {},
|
||||
"ok": {},
|
||||
"y": {},
|
||||
"on": {},
|
||||
"selected": {},
|
||||
"checked": {},
|
||||
"t": {},
|
||||
"enabled": {},
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertBool turn a string into a boolean
|
||||
func ConvertBool(str string) (bool, error) {
|
||||
_, ok := evaluatesAsTrue[strings.ToLower(str)]
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
// ConvertFloat32 turn a string into a float32
|
||||
func ConvertFloat32(str string) (float32, error) {
|
||||
f, err := strconv.ParseFloat(str, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return float32(f), nil
|
||||
}
|
||||
|
||||
// ConvertFloat64 turn a string into a float64
|
||||
func ConvertFloat64(str string) (float64, error) {
|
||||
return strconv.ParseFloat(str, 64)
|
||||
}
|
||||
|
||||
// ConvertInt8 turn a string into an int8
|
||||
func ConvertInt8(str string) (int8, error) {
|
||||
i, err := strconv.ParseInt(str, 10, 8)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int8(i), nil
|
||||
}
|
||||
|
||||
// ConvertInt16 turn a string into an int16
|
||||
func ConvertInt16(str string) (int16, error) {
|
||||
i, err := strconv.ParseInt(str, 10, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int16(i), nil
|
||||
}
|
||||
|
||||
// ConvertInt32 turn a string into an int32
|
||||
func ConvertInt32(str string) (int32, error) {
|
||||
i, err := strconv.ParseInt(str, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(i), nil
|
||||
}
|
||||
|
||||
// ConvertInt64 turn a string into an int64
|
||||
func ConvertInt64(str string) (int64, error) {
|
||||
return strconv.ParseInt(str, 10, 64)
|
||||
}
|
||||
|
||||
// ConvertUint8 turn a string into an uint8
|
||||
func ConvertUint8(str string) (uint8, error) {
|
||||
i, err := strconv.ParseUint(str, 10, 8)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint8(i), nil
|
||||
}
|
||||
|
||||
// ConvertUint16 turn a string into an uint16
|
||||
func ConvertUint16(str string) (uint16, error) {
|
||||
i, err := strconv.ParseUint(str, 10, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint16(i), nil
|
||||
}
|
||||
|
||||
// ConvertUint32 turn a string into an uint32
|
||||
func ConvertUint32(str string) (uint32, error) {
|
||||
i, err := strconv.ParseUint(str, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(i), nil
|
||||
}
|
||||
|
||||
// ConvertUint64 turn a string into an uint64
|
||||
func ConvertUint64(str string) (uint64, error) {
|
||||
return strconv.ParseUint(str, 10, 64)
|
||||
}
|
||||
|
||||
// FormatBool turns a boolean into a string
|
||||
func FormatBool(value bool) string {
|
||||
return strconv.FormatBool(value)
|
||||
}
|
||||
|
||||
// FormatFloat32 turns a float32 into a string
|
||||
func FormatFloat32(value float32) string {
|
||||
return strconv.FormatFloat(float64(value), 'f', -1, 32)
|
||||
}
|
||||
|
||||
// FormatFloat64 turns a float64 into a string
|
||||
func FormatFloat64(value float64) string {
|
||||
return strconv.FormatFloat(value, 'f', -1, 64)
|
||||
}
|
||||
|
||||
// FormatInt8 turns an int8 into a string
|
||||
func FormatInt8(value int8) string {
|
||||
return strconv.FormatInt(int64(value), 10)
|
||||
}
|
||||
|
||||
// FormatInt16 turns an int16 into a string
|
||||
func FormatInt16(value int16) string {
|
||||
return strconv.FormatInt(int64(value), 10)
|
||||
}
|
||||
|
||||
// FormatInt32 turns an int32 into a string
|
||||
func FormatInt32(value int32) string {
|
||||
return strconv.Itoa(int(value))
|
||||
}
|
||||
|
||||
// FormatInt64 turns an int64 into a string
|
||||
func FormatInt64(value int64) string {
|
||||
return strconv.FormatInt(value, 10)
|
||||
}
|
||||
|
||||
// FormatUint8 turns an uint8 into a string
|
||||
func FormatUint8(value uint8) string {
|
||||
return strconv.FormatUint(uint64(value), 10)
|
||||
}
|
||||
|
||||
// FormatUint16 turns an uint16 into a string
|
||||
func FormatUint16(value uint16) string {
|
||||
return strconv.FormatUint(uint64(value), 10)
|
||||
}
|
||||
|
||||
// FormatUint32 turns an uint32 into a string
|
||||
func FormatUint32(value uint32) string {
|
||||
return strconv.FormatUint(uint64(value), 10)
|
||||
}
|
||||
|
||||
// FormatUint64 turns an uint64 into a string
|
||||
func FormatUint64(value uint64) string {
|
||||
return strconv.FormatUint(value, 10)
|
||||
}
|
||||
-730
@@ -1,730 +0,0 @@
|
||||
package swag
|
||||
|
||||
import "time"
|
||||
|
||||
// This file was taken from the aws go sdk
|
||||
|
||||
// String returns a pointer to of the string value passed in.
|
||||
func String(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// StringValue returns the value of the string pointer passed in or
|
||||
// "" if the pointer is nil.
|
||||
func StringValue(v *string) string {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// StringSlice converts a slice of string values into a slice of
|
||||
// string pointers
|
||||
func StringSlice(src []string) []*string {
|
||||
dst := make([]*string, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringValueSlice converts a slice of string pointers into a slice of
|
||||
// string values
|
||||
func StringValueSlice(src []*string) []string {
|
||||
dst := make([]string, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringMap converts a string map of string values into a string
|
||||
// map of string pointers
|
||||
func StringMap(src map[string]string) map[string]*string {
|
||||
dst := make(map[string]*string)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringValueMap converts a string map of string pointers into a string
|
||||
// map of string values
|
||||
func StringValueMap(src map[string]*string) map[string]string {
|
||||
dst := make(map[string]string)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Bool returns a pointer to of the bool value passed in.
|
||||
func Bool(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// BoolValue returns the value of the bool pointer passed in or
|
||||
// false if the pointer is nil.
|
||||
func BoolValue(v *bool) bool {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// BoolSlice converts a slice of bool values into a slice of
|
||||
// bool pointers
|
||||
func BoolSlice(src []bool) []*bool {
|
||||
dst := make([]*bool, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolValueSlice converts a slice of bool pointers into a slice of
|
||||
// bool values
|
||||
func BoolValueSlice(src []*bool) []bool {
|
||||
dst := make([]bool, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolMap converts a string map of bool values into a string
|
||||
// map of bool pointers
|
||||
func BoolMap(src map[string]bool) map[string]*bool {
|
||||
dst := make(map[string]*bool)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolValueMap converts a string map of bool pointers into a string
|
||||
// map of bool values
|
||||
func BoolValueMap(src map[string]*bool) map[string]bool {
|
||||
dst := make(map[string]bool)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int returns a pointer to of the int value passed in.
|
||||
func Int(v int) *int {
|
||||
return &v
|
||||
}
|
||||
|
||||
// IntValue returns the value of the int pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func IntValue(v *int) int {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// IntSlice converts a slice of int values into a slice of
|
||||
// int pointers
|
||||
func IntSlice(src []int) []*int {
|
||||
dst := make([]*int, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntValueSlice converts a slice of int pointers into a slice of
|
||||
// int values
|
||||
func IntValueSlice(src []*int) []int {
|
||||
dst := make([]int, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntMap converts a string map of int values into a string
|
||||
// map of int pointers
|
||||
func IntMap(src map[string]int) map[string]*int {
|
||||
dst := make(map[string]*int)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntValueMap converts a string map of int pointers into a string
|
||||
// map of int values
|
||||
func IntValueMap(src map[string]*int) map[string]int {
|
||||
dst := make(map[string]int)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int32 returns a pointer to of the int32 value passed in.
|
||||
func Int32(v int32) *int32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int32Value returns the value of the int32 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Int32Value(v *int32) int32 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Int32Slice converts a slice of int32 values into a slice of
|
||||
// int32 pointers
|
||||
func Int32Slice(src []int32) []*int32 {
|
||||
dst := make([]*int32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int32ValueSlice converts a slice of int32 pointers into a slice of
|
||||
// int32 values
|
||||
func Int32ValueSlice(src []*int32) []int32 {
|
||||
dst := make([]int32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int32Map converts a string map of int32 values into a string
|
||||
// map of int32 pointers
|
||||
func Int32Map(src map[string]int32) map[string]*int32 {
|
||||
dst := make(map[string]*int32)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int32ValueMap converts a string map of int32 pointers into a string
|
||||
// map of int32 values
|
||||
func Int32ValueMap(src map[string]*int32) map[string]int32 {
|
||||
dst := make(map[string]int32)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64 returns a pointer to of the int64 value passed in.
|
||||
func Int64(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int64Value returns the value of the int64 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Int64Value(v *int64) int64 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Int64Slice converts a slice of int64 values into a slice of
|
||||
// int64 pointers
|
||||
func Int64Slice(src []int64) []*int64 {
|
||||
dst := make([]*int64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64ValueSlice converts a slice of int64 pointers into a slice of
|
||||
// int64 values
|
||||
func Int64ValueSlice(src []*int64) []int64 {
|
||||
dst := make([]int64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64Map converts a string map of int64 values into a string
|
||||
// map of int64 pointers
|
||||
func Int64Map(src map[string]int64) map[string]*int64 {
|
||||
dst := make(map[string]*int64)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64ValueMap converts a string map of int64 pointers into a string
|
||||
// map of int64 values
|
||||
func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
||||
dst := make(map[string]int64)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint16 returns a pointer to of the uint16 value passed in.
|
||||
func Uint16(v uint16) *uint16 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint16Value returns the value of the uint16 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Uint16Value(v *uint16) uint16 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Uint16Slice converts a slice of uint16 values into a slice of
|
||||
// uint16 pointers
|
||||
func Uint16Slice(src []uint16) []*uint16 {
|
||||
dst := make([]*uint16, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint16ValueSlice converts a slice of uint16 pointers into a slice of
|
||||
// uint16 values
|
||||
func Uint16ValueSlice(src []*uint16) []uint16 {
|
||||
dst := make([]uint16, len(src))
|
||||
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint16Map converts a string map of uint16 values into a string
|
||||
// map of uint16 pointers
|
||||
func Uint16Map(src map[string]uint16) map[string]*uint16 {
|
||||
dst := make(map[string]*uint16)
|
||||
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint16ValueMap converts a string map of uint16 pointers into a string
|
||||
// map of uint16 values
|
||||
func Uint16ValueMap(src map[string]*uint16) map[string]uint16 {
|
||||
dst := make(map[string]uint16)
|
||||
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint returns a pointer to of the uint value passed in.
|
||||
func Uint(v uint) *uint {
|
||||
return &v
|
||||
}
|
||||
|
||||
// UintValue returns the value of the uint pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func UintValue(v *uint) uint {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// UintSlice converts a slice of uint values into a slice of
|
||||
// uint pointers
|
||||
func UintSlice(src []uint) []*uint {
|
||||
dst := make([]*uint, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UintValueSlice converts a slice of uint pointers into a slice of
|
||||
// uint values
|
||||
func UintValueSlice(src []*uint) []uint {
|
||||
dst := make([]uint, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UintMap converts a string map of uint values into a string
|
||||
// map of uint pointers
|
||||
func UintMap(src map[string]uint) map[string]*uint {
|
||||
dst := make(map[string]*uint)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UintValueMap converts a string map of uint pointers into a string
|
||||
// map of uint values
|
||||
func UintValueMap(src map[string]*uint) map[string]uint {
|
||||
dst := make(map[string]uint)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint32 returns a pointer to of the uint32 value passed in.
|
||||
func Uint32(v uint32) *uint32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint32Value returns the value of the uint32 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Uint32Value(v *uint32) uint32 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Uint32Slice converts a slice of uint32 values into a slice of
|
||||
// uint32 pointers
|
||||
func Uint32Slice(src []uint32) []*uint32 {
|
||||
dst := make([]*uint32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint32ValueSlice converts a slice of uint32 pointers into a slice of
|
||||
// uint32 values
|
||||
func Uint32ValueSlice(src []*uint32) []uint32 {
|
||||
dst := make([]uint32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint32Map converts a string map of uint32 values into a string
|
||||
// map of uint32 pointers
|
||||
func Uint32Map(src map[string]uint32) map[string]*uint32 {
|
||||
dst := make(map[string]*uint32)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint32ValueMap converts a string map of uint32 pointers into a string
|
||||
// map of uint32 values
|
||||
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
|
||||
dst := make(map[string]uint32)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint64 returns a pointer to of the uint64 value passed in.
|
||||
func Uint64(v uint64) *uint64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint64Value returns the value of the uint64 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Uint64Value(v *uint64) uint64 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Uint64Slice converts a slice of uint64 values into a slice of
|
||||
// uint64 pointers
|
||||
func Uint64Slice(src []uint64) []*uint64 {
|
||||
dst := make([]*uint64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint64ValueSlice converts a slice of uint64 pointers into a slice of
|
||||
// uint64 values
|
||||
func Uint64ValueSlice(src []*uint64) []uint64 {
|
||||
dst := make([]uint64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint64Map converts a string map of uint64 values into a string
|
||||
// map of uint64 pointers
|
||||
func Uint64Map(src map[string]uint64) map[string]*uint64 {
|
||||
dst := make(map[string]*uint64)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint64ValueMap converts a string map of uint64 pointers into a string
|
||||
// map of uint64 values
|
||||
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
|
||||
dst := make(map[string]uint64)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float32 returns a pointer to of the float32 value passed in.
|
||||
func Float32(v float32) *float32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float32Value returns the value of the float32 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Float32Value(v *float32) float32 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Float32Slice converts a slice of float32 values into a slice of
|
||||
// float32 pointers
|
||||
func Float32Slice(src []float32) []*float32 {
|
||||
dst := make([]*float32, len(src))
|
||||
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float32ValueSlice converts a slice of float32 pointers into a slice of
|
||||
// float32 values
|
||||
func Float32ValueSlice(src []*float32) []float32 {
|
||||
dst := make([]float32, len(src))
|
||||
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float32Map converts a string map of float32 values into a string
|
||||
// map of float32 pointers
|
||||
func Float32Map(src map[string]float32) map[string]*float32 {
|
||||
dst := make(map[string]*float32)
|
||||
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float32ValueMap converts a string map of float32 pointers into a string
|
||||
// map of float32 values
|
||||
func Float32ValueMap(src map[string]*float32) map[string]float32 {
|
||||
dst := make(map[string]float32)
|
||||
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64 returns a pointer to of the float64 value passed in.
|
||||
func Float64(v float64) *float64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float64Value returns the value of the float64 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Float64Value(v *float64) float64 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Float64Slice converts a slice of float64 values into a slice of
|
||||
// float64 pointers
|
||||
func Float64Slice(src []float64) []*float64 {
|
||||
dst := make([]*float64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64ValueSlice converts a slice of float64 pointers into a slice of
|
||||
// float64 values
|
||||
func Float64ValueSlice(src []*float64) []float64 {
|
||||
dst := make([]float64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64Map converts a string map of float64 values into a string
|
||||
// map of float64 pointers
|
||||
func Float64Map(src map[string]float64) map[string]*float64 {
|
||||
dst := make(map[string]*float64)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64ValueMap converts a string map of float64 pointers into a string
|
||||
// map of float64 values
|
||||
func Float64ValueMap(src map[string]*float64) map[string]float64 {
|
||||
dst := make(map[string]float64)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Time returns a pointer to of the time.Time value passed in.
|
||||
func Time(v time.Time) *time.Time {
|
||||
return &v
|
||||
}
|
||||
|
||||
// TimeValue returns the value of the time.Time pointer passed in or
|
||||
// time.Time{} if the pointer is nil.
|
||||
func TimeValue(v *time.Time) time.Time {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
// TimeSlice converts a slice of time.Time values into a slice of
|
||||
// time.Time pointers
|
||||
func TimeSlice(src []time.Time) []*time.Time {
|
||||
dst := make([]*time.Time, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeValueSlice converts a slice of time.Time pointers into a slice of
|
||||
// time.Time values
|
||||
func TimeValueSlice(src []*time.Time) []time.Time {
|
||||
dst := make([]time.Time, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeMap converts a string map of time.Time values into a string
|
||||
// map of time.Time pointers
|
||||
func TimeMap(src map[string]time.Time) map[string]*time.Time {
|
||||
dst := make(map[string]*time.Time)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeValueMap converts a string map of time.Time pointers into a string
|
||||
// map of time.Time values
|
||||
func TimeValueMap(src map[string]*time.Time) map[string]time.Time {
|
||||
dst := make(map[string]time.Time)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
+43
-16
@@ -12,20 +12,47 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
Package swag contains a bunch of helper functions for go-openapi and go-swagger projects.
|
||||
|
||||
You may also use it standalone for your projects.
|
||||
|
||||
- convert between value and pointers for builtin types
|
||||
- convert from string to builtin types (wraps strconv)
|
||||
- fast json concatenation
|
||||
- search in path
|
||||
- load from file or http
|
||||
- name mangling
|
||||
|
||||
This repo has only few dependencies outside of the standard library:
|
||||
|
||||
- YAML utilities depend on gopkg.in/yaml.v2
|
||||
*/
|
||||
// Package swag contains a bunch of helper functions for go-openapi and go-swagger projects.
|
||||
//
|
||||
// You may also use it standalone for your projects.
|
||||
//
|
||||
// NOTE: all features that used to be exposed as package-level members (constants, variables,
|
||||
// functions and types) are now deprecated and are superseded by equivalent features in
|
||||
// more specialized sub-packages.
|
||||
// Moving forward, no additional feature will be added to the [swag] API directly at the root package level,
|
||||
// which remains there for backward-compatibility purposes.
|
||||
//
|
||||
// Child modules will continue to evolve or some new ones may be added in the future.
|
||||
//
|
||||
// # Modules
|
||||
//
|
||||
// - [cmdutils] utilities to work with CLIs
|
||||
//
|
||||
// - [conv] type conversion utilities
|
||||
//
|
||||
// - [fileutils] file utilities
|
||||
//
|
||||
// - [jsonname] JSON utilities
|
||||
//
|
||||
// - [jsonutils] JSON utilities
|
||||
//
|
||||
// - [loading] file loading
|
||||
//
|
||||
// - [mangling] safe name generation
|
||||
//
|
||||
// - [netutils] networking utilities
|
||||
//
|
||||
// - [stringutils] `string` utilities
|
||||
//
|
||||
// - [typeutils] `go` types utilities
|
||||
//
|
||||
// - [yamlutils] YAML utilities
|
||||
//
|
||||
// # Dependencies
|
||||
//
|
||||
// This repo has a few dependencies outside of the standard library:
|
||||
//
|
||||
// - YAML utilities depend on [go.yaml.in/yaml/v3]
|
||||
package swag
|
||||
|
||||
//go:generate mockery
|
||||
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package fileutils exposes utilities to deal with files and paths.
|
||||
//
|
||||
// Currently, there is:
|
||||
// - [File] to represent an abstraction of an uploaded file.
|
||||
// For instance, this is used by [github.com/go-openapi/runtime.File].
|
||||
// - path search utilities (e.g. finding packages in the GO search path)
|
||||
package fileutils
|
||||
Generated
Vendored
+1
-1
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
package fileutils
|
||||
|
||||
import "mime/multipart"
|
||||
|
||||
Generated
Vendored
+9
-5
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
package fileutils
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -21,10 +21,8 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// GOPATHKey represents the env key for gopath
|
||||
GOPATHKey = "GOPATH"
|
||||
)
|
||||
// GOPATHKey represents the env key for gopath
|
||||
const GOPATHKey = "GOPATH"
|
||||
|
||||
// FindInSearchPath finds a package in a provided lists of paths
|
||||
func FindInSearchPath(searchPath, pkg string) string {
|
||||
@@ -40,11 +38,17 @@ func FindInSearchPath(searchPath, pkg string) string {
|
||||
}
|
||||
|
||||
// FindInGoSearchPath finds a package in the $GOPATH:$GOROOT
|
||||
//
|
||||
// Deprecated: this function is no longer relevant with modern go.
|
||||
// It uses [runtime.GOROOT] under the hood, which is deprecated as of go1.24.
|
||||
func FindInGoSearchPath(pkg string) string {
|
||||
return FindInSearchPath(FullGoSearchPath(), pkg)
|
||||
}
|
||||
|
||||
// FullGoSearchPath gets the search paths for finding packages
|
||||
//
|
||||
// Deprecated: this function is no longer relevant with modern go.
|
||||
// It uses [runtime.GOROOT] under the hood, which is deprecated as of go1.24.
|
||||
func FullGoSearchPath() string {
|
||||
allPaths := os.Getenv(GOPATHKey)
|
||||
if allPaths == "" {
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import "github.com/go-openapi/swag/fileutils"
|
||||
|
||||
// GOPATHKey represents the env key for gopath
|
||||
//
|
||||
// Deprecated: use [fileutils.GOPATHKey] instead.
|
||||
const GOPATHKey = fileutils.GOPATHKey
|
||||
|
||||
// File represents an uploaded file.
|
||||
//
|
||||
// Deprecated: use [fileutils.File] instead.
|
||||
type File = fileutils.File
|
||||
|
||||
// FindInSearchPath finds a package in a provided lists of paths.
|
||||
//
|
||||
// Deprecated: use [fileutils.FindInSearchPath] instead.
|
||||
func FindInSearchPath(searchPath, pkg string) string {
|
||||
return fileutils.FindInSearchPath(searchPath, pkg)
|
||||
}
|
||||
|
||||
// FindInGoSearchPath finds a package in the $GOPATH:$GOROOT
|
||||
//
|
||||
// Deprecated: use [fileutils.FindInGoSearchPath] instead.
|
||||
func FindInGoSearchPath(pkg string) string { return fileutils.FindInGoSearchPath(pkg) }
|
||||
|
||||
// FullGoSearchPath gets the search paths for finding packages
|
||||
//
|
||||
// Deprecated: use [fileutils.FullGoSearchPath] instead.
|
||||
func FullGoSearchPath() string { return fileutils.FullGoSearchPath() }
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use (
|
||||
.
|
||||
./cmdutils
|
||||
./conv
|
||||
./fileutils
|
||||
./jsonname
|
||||
./jsonutils
|
||||
./jsonutils/adapters/easyjson
|
||||
./jsonutils/adapters/testintegration
|
||||
./jsonutils/adapters/testintegration/benchmarks
|
||||
./jsonutils/fixtures_test
|
||||
./loading
|
||||
./mangling
|
||||
./netutils
|
||||
./stringutils
|
||||
./typeutils
|
||||
./yamlutils
|
||||
)
|
||||
|
||||
go 1.24.0
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
-202
@@ -1,202 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// commonInitialisms are common acronyms that are kept as whole uppercased words.
|
||||
commonInitialisms *indexOfInitialisms
|
||||
|
||||
// initialisms is a slice of sorted initialisms
|
||||
initialisms []string
|
||||
|
||||
// a copy of initialisms pre-baked as []rune
|
||||
initialismsRunes [][]rune
|
||||
initialismsUpperCased [][]rune
|
||||
|
||||
isInitialism func(string) bool
|
||||
|
||||
maxAllocMatches int
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
|
||||
configuredInitialisms := map[string]bool{
|
||||
"ACL": true,
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
"CPU": true,
|
||||
"CSS": true,
|
||||
"DNS": true,
|
||||
"EOF": true,
|
||||
"GUID": true,
|
||||
"HTML": true,
|
||||
"HTTPS": true,
|
||||
"HTTP": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"IPv4": true,
|
||||
"IPv6": true,
|
||||
"JSON": true,
|
||||
"LHS": true,
|
||||
"OAI": true,
|
||||
"QPS": true,
|
||||
"RAM": true,
|
||||
"RHS": true,
|
||||
"RPC": true,
|
||||
"SLA": true,
|
||||
"SMTP": true,
|
||||
"SQL": true,
|
||||
"SSH": true,
|
||||
"TCP": true,
|
||||
"TLS": true,
|
||||
"TTL": true,
|
||||
"UDP": true,
|
||||
"UI": true,
|
||||
"UID": true,
|
||||
"UUID": true,
|
||||
"URI": true,
|
||||
"URL": true,
|
||||
"UTF8": true,
|
||||
"VM": true,
|
||||
"XML": true,
|
||||
"XMPP": true,
|
||||
"XSRF": true,
|
||||
"XSS": true,
|
||||
}
|
||||
|
||||
// a thread-safe index of initialisms
|
||||
commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
|
||||
initialisms = commonInitialisms.sorted()
|
||||
initialismsRunes = asRunes(initialisms)
|
||||
initialismsUpperCased = asUpperCased(initialisms)
|
||||
maxAllocMatches = maxAllocHeuristic(initialismsRunes)
|
||||
|
||||
// a test function
|
||||
isInitialism = commonInitialisms.isInitialism
|
||||
}
|
||||
|
||||
func asRunes(in []string) [][]rune {
|
||||
out := make([][]rune, len(in))
|
||||
for i, initialism := range in {
|
||||
out[i] = []rune(initialism)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func asUpperCased(in []string) [][]rune {
|
||||
out := make([][]rune, len(in))
|
||||
|
||||
for i, initialism := range in {
|
||||
out[i] = []rune(upper(trim(initialism)))
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func maxAllocHeuristic(in [][]rune) int {
|
||||
heuristic := make(map[rune]int)
|
||||
for _, initialism := range in {
|
||||
heuristic[initialism[0]]++
|
||||
}
|
||||
|
||||
var maxAlloc int
|
||||
for _, val := range heuristic {
|
||||
if val > maxAlloc {
|
||||
maxAlloc = val
|
||||
}
|
||||
}
|
||||
|
||||
return maxAlloc
|
||||
}
|
||||
|
||||
// AddInitialisms add additional initialisms
|
||||
func AddInitialisms(words ...string) {
|
||||
for _, word := range words {
|
||||
// commonInitialisms[upper(word)] = true
|
||||
commonInitialisms.add(upper(word))
|
||||
}
|
||||
// sort again
|
||||
initialisms = commonInitialisms.sorted()
|
||||
initialismsRunes = asRunes(initialisms)
|
||||
initialismsUpperCased = asUpperCased(initialisms)
|
||||
}
|
||||
|
||||
// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
|
||||
// Since go1.9, this may be implemented with sync.Map.
|
||||
type indexOfInitialisms struct {
|
||||
sortMutex *sync.Mutex
|
||||
index *sync.Map
|
||||
}
|
||||
|
||||
func newIndexOfInitialisms() *indexOfInitialisms {
|
||||
return &indexOfInitialisms{
|
||||
sortMutex: new(sync.Mutex),
|
||||
index: new(sync.Map),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
|
||||
m.sortMutex.Lock()
|
||||
defer m.sortMutex.Unlock()
|
||||
for k, v := range initial {
|
||||
m.index.Store(k, v)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) isInitialism(key string) bool {
|
||||
_, ok := m.index.Load(key)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
|
||||
m.index.Store(key, true)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) sorted() (result []string) {
|
||||
m.sortMutex.Lock()
|
||||
defer m.sortMutex.Unlock()
|
||||
m.index.Range(func(key, _ interface{}) bool {
|
||||
k := key.(string)
|
||||
result = append(result, k)
|
||||
return true
|
||||
})
|
||||
sort.Sort(sort.Reverse(byInitialism(result)))
|
||||
return
|
||||
}
|
||||
|
||||
type byInitialism []string
|
||||
|
||||
func (s byInitialism) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
func (s byInitialism) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
func (s byInitialism) Less(i, j int) bool {
|
||||
if len(s[i]) != len(s[j]) {
|
||||
return len(s[i]) < len(s[j])
|
||||
}
|
||||
|
||||
return strings.Compare(s[i], s[j]) > 0
|
||||
}
|
||||
-312
@@ -1,312 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// nullJSON represents a JSON object with null type
|
||||
var nullJSON = []byte("null")
|
||||
|
||||
// DefaultJSONNameProvider the default cache for types
|
||||
var DefaultJSONNameProvider = NewNameProvider()
|
||||
|
||||
const comma = byte(',')
|
||||
|
||||
var closers map[byte]byte
|
||||
|
||||
func init() {
|
||||
closers = map[byte]byte{
|
||||
'{': '}',
|
||||
'[': ']',
|
||||
}
|
||||
}
|
||||
|
||||
type ejMarshaler interface {
|
||||
MarshalEasyJSON(w *jwriter.Writer)
|
||||
}
|
||||
|
||||
type ejUnmarshaler interface {
|
||||
UnmarshalEasyJSON(w *jlexer.Lexer)
|
||||
}
|
||||
|
||||
// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaler
|
||||
// so it takes the fastest option available.
|
||||
func WriteJSON(data interface{}) ([]byte, error) {
|
||||
if d, ok := data.(ejMarshaler); ok {
|
||||
jw := new(jwriter.Writer)
|
||||
d.MarshalEasyJSON(jw)
|
||||
return jw.BuildBytes()
|
||||
}
|
||||
if d, ok := data.(json.Marshaler); ok {
|
||||
return d.MarshalJSON()
|
||||
}
|
||||
return json.Marshal(data)
|
||||
}
|
||||
|
||||
// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaler
|
||||
// so it takes the fastest option available
|
||||
func ReadJSON(data []byte, value interface{}) error {
|
||||
trimmedData := bytes.Trim(data, "\x00")
|
||||
if d, ok := value.(ejUnmarshaler); ok {
|
||||
jl := &jlexer.Lexer{Data: trimmedData}
|
||||
d.UnmarshalEasyJSON(jl)
|
||||
return jl.Error()
|
||||
}
|
||||
if d, ok := value.(json.Unmarshaler); ok {
|
||||
return d.UnmarshalJSON(trimmedData)
|
||||
}
|
||||
return json.Unmarshal(trimmedData, value)
|
||||
}
|
||||
|
||||
// DynamicJSONToStruct converts an untyped json structure into a struct
|
||||
func DynamicJSONToStruct(data interface{}, target interface{}) error {
|
||||
// TODO: convert straight to a json typed map (mergo + iterate?)
|
||||
b, err := WriteJSON(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ReadJSON(b, target)
|
||||
}
|
||||
|
||||
// ConcatJSON concatenates multiple json objects efficiently
|
||||
func ConcatJSON(blobs ...[]byte) []byte {
|
||||
if len(blobs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
last := len(blobs) - 1
|
||||
for blobs[last] == nil || bytes.Equal(blobs[last], nullJSON) {
|
||||
// strips trailing null objects
|
||||
last--
|
||||
if last < 0 {
|
||||
// there was nothing but "null"s or nil...
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if last == 0 {
|
||||
return blobs[0]
|
||||
}
|
||||
|
||||
var opening, closing byte
|
||||
var idx, a int
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
for i, b := range blobs[:last+1] {
|
||||
if b == nil || bytes.Equal(b, nullJSON) {
|
||||
// a null object is in the list: skip it
|
||||
continue
|
||||
}
|
||||
if len(b) > 0 && opening == 0 { // is this an array or an object?
|
||||
opening, closing = b[0], closers[b[0]]
|
||||
}
|
||||
|
||||
if opening != '{' && opening != '[' {
|
||||
continue // don't know how to concatenate non container objects
|
||||
}
|
||||
|
||||
if len(b) < 3 { // yep empty but also the last one, so closing this thing
|
||||
if i == last && a > 0 {
|
||||
if err := buf.WriteByte(closing); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
idx = 0
|
||||
if a > 0 { // we need to join with a comma for everything beyond the first non-empty item
|
||||
if err := buf.WriteByte(comma); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
idx = 1 // this is not the first or the last so we want to drop the leading bracket
|
||||
}
|
||||
|
||||
if i != last { // not the last one, strip brackets
|
||||
if _, err := buf.Write(b[idx : len(b)-1]); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
} else { // last one, strip only the leading bracket
|
||||
if _, err := buf.Write(b[idx:]); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
a++
|
||||
}
|
||||
// somehow it ended up being empty, so provide a default value
|
||||
if buf.Len() == 0 {
|
||||
if err := buf.WriteByte(opening); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if err := buf.WriteByte(closing); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// ToDynamicJSON turns an object into a properly JSON typed structure
|
||||
func ToDynamicJSON(data interface{}) interface{} {
|
||||
// TODO: convert straight to a json typed map (mergo + iterate?)
|
||||
b, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
var res interface{}
|
||||
if err := json.Unmarshal(b, &res); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// FromDynamicJSON turns an object into a properly JSON typed structure
|
||||
func FromDynamicJSON(data, target interface{}) error {
|
||||
b, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return json.Unmarshal(b, target)
|
||||
}
|
||||
|
||||
// NameProvider represents an object capable of translating from go property names
|
||||
// to json property names
|
||||
// This type is thread-safe.
|
||||
type NameProvider struct {
|
||||
lock *sync.Mutex
|
||||
index map[reflect.Type]nameIndex
|
||||
}
|
||||
|
||||
type nameIndex struct {
|
||||
jsonNames map[string]string
|
||||
goNames map[string]string
|
||||
}
|
||||
|
||||
// NewNameProvider creates a new name provider
|
||||
func NewNameProvider() *NameProvider {
|
||||
return &NameProvider{
|
||||
lock: &sync.Mutex{},
|
||||
index: make(map[reflect.Type]nameIndex),
|
||||
}
|
||||
}
|
||||
|
||||
func buildnameIndex(tpe reflect.Type, idx, reverseIdx map[string]string) {
|
||||
for i := 0; i < tpe.NumField(); i++ {
|
||||
targetDes := tpe.Field(i)
|
||||
|
||||
if targetDes.PkgPath != "" { // unexported
|
||||
continue
|
||||
}
|
||||
|
||||
if targetDes.Anonymous { // walk embedded structures tree down first
|
||||
buildnameIndex(targetDes.Type, idx, reverseIdx)
|
||||
continue
|
||||
}
|
||||
|
||||
if tag := targetDes.Tag.Get("json"); tag != "" {
|
||||
|
||||
parts := strings.Split(tag, ",")
|
||||
if len(parts) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
nm := parts[0]
|
||||
if nm == "-" {
|
||||
continue
|
||||
}
|
||||
if nm == "" { // empty string means we want to use the Go name
|
||||
nm = targetDes.Name
|
||||
}
|
||||
|
||||
idx[nm] = targetDes.Name
|
||||
reverseIdx[targetDes.Name] = nm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newNameIndex(tpe reflect.Type) nameIndex {
|
||||
var idx = make(map[string]string, tpe.NumField())
|
||||
var reverseIdx = make(map[string]string, tpe.NumField())
|
||||
|
||||
buildnameIndex(tpe, idx, reverseIdx)
|
||||
return nameIndex{jsonNames: idx, goNames: reverseIdx}
|
||||
}
|
||||
|
||||
// GetJSONNames gets all the json property names for a type
|
||||
func (n *NameProvider) GetJSONNames(subject interface{}) []string {
|
||||
n.lock.Lock()
|
||||
defer n.lock.Unlock()
|
||||
tpe := reflect.Indirect(reflect.ValueOf(subject)).Type()
|
||||
names, ok := n.index[tpe]
|
||||
if !ok {
|
||||
names = n.makeNameIndex(tpe)
|
||||
}
|
||||
|
||||
res := make([]string, 0, len(names.jsonNames))
|
||||
for k := range names.jsonNames {
|
||||
res = append(res, k)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// GetJSONName gets the json name for a go property name
|
||||
func (n *NameProvider) GetJSONName(subject interface{}, name string) (string, bool) {
|
||||
tpe := reflect.Indirect(reflect.ValueOf(subject)).Type()
|
||||
return n.GetJSONNameForType(tpe, name)
|
||||
}
|
||||
|
||||
// GetJSONNameForType gets the json name for a go property name on a given type
|
||||
func (n *NameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) {
|
||||
n.lock.Lock()
|
||||
defer n.lock.Unlock()
|
||||
names, ok := n.index[tpe]
|
||||
if !ok {
|
||||
names = n.makeNameIndex(tpe)
|
||||
}
|
||||
nme, ok := names.goNames[name]
|
||||
return nme, ok
|
||||
}
|
||||
|
||||
func (n *NameProvider) makeNameIndex(tpe reflect.Type) nameIndex {
|
||||
names := newNameIndex(tpe)
|
||||
n.index[tpe] = names
|
||||
return names
|
||||
}
|
||||
|
||||
// GetGoName gets the go name for a json property name
|
||||
func (n *NameProvider) GetGoName(subject interface{}, name string) (string, bool) {
|
||||
tpe := reflect.Indirect(reflect.ValueOf(subject)).Type()
|
||||
return n.GetGoNameForType(tpe, name)
|
||||
}
|
||||
|
||||
// GetGoNameForType gets the go name for a given type for a json property name
|
||||
func (n *NameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) {
|
||||
n.lock.Lock()
|
||||
defer n.lock.Unlock()
|
||||
names, ok := n.index[tpe]
|
||||
if !ok {
|
||||
names = n.makeNameIndex(tpe)
|
||||
}
|
||||
nme, ok := names.jsonNames[name]
|
||||
return nme, ok
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package jsonname is a provider of json property names from go properties.
|
||||
package jsonname
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user