mirror of
https://github.com/agent-substrate/substrate.git
synced 2026-11-12 10:35:06 +08:00
This mostly eliminates the need to hand-write validation code. This PR is a long series of commits which add DV for most of Actor and all of Atespace. Here is a map to the commits: * The first few take a dep on a new Kubernetes tag, import the code into third_party, and apply a single patch. Because we have different Go modules for tools, I had to do it twice. When that patch lands, we can revert these commits, but that won't be until the 1.38 cycle in a few months. * The next commits slowly add DV support, so a human can review each of them in a reasonable amount of time. The emphasis is on great test cases. * I made a bad choice early on as to where to generate the code into, so I moved it. Rebasing on that was exceedingly hard, so I left it as a move. * This required changing update/go-generate -> update/codegen -- we need to get the ordering of tools right, which `go generate` does not guarantee. * Then I added a "middle" layer called "ServiceImpl" between the RPC and storage layers. This allows things like workflow to call the same business logic as the RPC layer, including validation. Lots of test fixes. * Then I finished the Create() and Update() paths for Actor. Those represent the "right" (or closest to) way to implement resources, and tests for validation. I strongly encourage reviewers to read it commit-by-commit. Rebasing this is VERY tedious, so the sooner it lands or dies completely, the better. Then we can start converting the rest. `./hack/run-tool.sh validation-gen --docs` will produce some docs on the tool and the available tags. @laoj2 @juli4n @EItanya @HavenXia @lalitc375 @yongruilin @jpbetz FYI
86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package jsonpointer
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/go-openapi/jsonpointer/jsonname"
|
|
)
|
|
|
|
// Option to tune the behavior of a JSON [Pointer].
|
|
type Option func(*options)
|
|
|
|
var (
|
|
//nolint:gochecknoglobals // package level defaults are provided as a convenient, backward-compatible way to adopt options.
|
|
defaultOptions = options{
|
|
provider: jsonname.DefaultJSONNameProvider,
|
|
}
|
|
//nolint:gochecknoglobals // guards defaultOptions against concurrent SetDefaultNameProvider / read races (testing)
|
|
defaultOptionsMu sync.RWMutex
|
|
)
|
|
|
|
// SetDefaultNameProvider sets the [NameProvider] as a package-level default.
|
|
//
|
|
// By default, the default provider is [jsonname.DefaultJSONNameProvider].
|
|
//
|
|
// It is safe to call concurrently with [Pointer.Get], [Pointer.Set], [GetForToken] and
|
|
// [SetForToken].
|
|
// The typical usage is to call it once at initialization time.
|
|
//
|
|
// A nil provider is ignored.
|
|
func SetDefaultNameProvider(provider NameProvider) {
|
|
if provider == nil {
|
|
return
|
|
}
|
|
|
|
defaultOptionsMu.Lock()
|
|
defer defaultOptionsMu.Unlock()
|
|
|
|
defaultOptions.provider = provider
|
|
}
|
|
|
|
// UseGoNameProvider sets the [NameProvider] as a package-level default to the alternative provider
|
|
// [jsonname.GoNameProvider], that covers a few areas not supported by the default name provider.
|
|
//
|
|
// This implementation supports untagged exported fields and embedded types in go struct.
|
|
// It follows strictly the behavior of the JSON standard library regarding field naming conventions.
|
|
//
|
|
// It is safe to call concurrently with [Pointer.Get], [Pointer.Set], [GetForToken] and
|
|
// [SetForToken].
|
|
// The typical usage is to call it once at initialization time.
|
|
func UseGoNameProvider() {
|
|
SetDefaultNameProvider(jsonname.NewGoNameProvider())
|
|
}
|
|
|
|
// DefaultNameProvider returns the current package-level [NameProvider].
|
|
func DefaultNameProvider() NameProvider { //nolint:ireturn // returning the interface is the point — callers pick their own implementation.
|
|
defaultOptionsMu.RLock()
|
|
defer defaultOptionsMu.RUnlock()
|
|
|
|
return defaultOptions.provider
|
|
}
|
|
|
|
// WithNameProvider injects a custom [NameProvider] to resolve json names from go struct types.
|
|
func WithNameProvider(provider NameProvider) Option {
|
|
return func(o *options) {
|
|
o.provider = provider
|
|
}
|
|
}
|
|
|
|
type options struct {
|
|
provider NameProvider
|
|
}
|
|
|
|
func optionsWithDefaults(opts []Option) options {
|
|
var o options
|
|
o.provider = DefaultNameProvider()
|
|
|
|
for _, apply := range opts {
|
|
apply(&o)
|
|
}
|
|
|
|
return o
|
|
}
|