aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2026-05-03 20:41:58 +0200
committerStefan Majewsky <majewsky@gmx.net>2026-05-03 20:41:58 +0200
commitc808a35d7b56319d8fa4b21516b328a0513f5949 (patch)
tree66eaca8be93821e874cadc353ff84926dc71fcfb
parent80e08e6aee59ef32355fe5a376f295f1fd7dec1c (diff)
downloadgo-gg-c808a35d7b56319d8fa4b21516b328a0513f5949.tar.gz
adjust docstrings to use link syntax where possible, add refs to new YAML library module path
-rw-r--r--assetembed/assetembed.go6
-rw-r--r--jsonmatch/interface.go43
-rw-r--r--option/option.go23
3 files changed, 41 insertions, 31 deletions
diff --git a/assetembed/assetembed.go b/assetembed/assetembed.go
index f8dcaf8..fc25f11 100644
--- a/assetembed/assetembed.go
+++ b/assetembed/assetembed.go
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// Package assetembed provides a HTTP handler for serving asset files embedded in a Go binary through the embed.FS type.
-// It is similar in purpose to http.FileServerFS() from the standard library,
+// It is similar in purpose to [http.FileServerFS] from the standard library,
// but instead of serving files directly with their names as found in the filesystem,
// it inserts a cryptographic digest of the file contents into the filename that the handler serves.
//
@@ -34,7 +34,7 @@ type Handler struct {
contents map[string][]byte // e.g. "res/app-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css" -> [contents of res/app.css]
}
-// NewHandler builds a new Handler instance.
+// NewHandler builds a new [Handler] instance.
// This will read all files in assetFS and store a copy of their contents inside the Handler instance.
//
// For filesystems backed by actual disk or network storage, this can be a very expensive operation.
@@ -120,7 +120,7 @@ var cacheControlHeader = fmt.Sprintf(
int64((14 * 24 * time.Hour).Seconds()), // max-age = 2 weeks
)
-// ServeHTTP implements the http.Handler interface.
+// ServeHTTP implements the [http.Handler] interface.
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
buf, exists := h.contents[strings.TrimPrefix(r.URL.Path, "/")]
if !exists {
diff --git a/jsonmatch/interface.go b/jsonmatch/interface.go
index 69319cb..d7b6b5b 100644
--- a/jsonmatch/interface.go
+++ b/jsonmatch/interface.go
@@ -96,12 +96,12 @@
// In this example, we have made a mistake in the implementation.
// The field "name" has been misspelled, so it will be marshalled as "naem" instead.
// Because the test unmarshals into the same type as the implementation, it will not be able to uncover this error.
-// This example might be a bit contrived, but keeping test logic separate from implementation logic is especially important for types using advanced marshalling logic through custom implementations of the json.Marshaler and json.Unmarshaler interfaces.
+// This example might be a bit contrived, but keeping test logic separate from implementation logic is especially important for types using advanced marshalling logic through custom implementations of the [json.Marshaler] and [json.Unmarshaler] interfaces.
//
// # Capturing nondeterministic data
//
// Sometimes, JSON payloads may contain randomly-generated fields like UUIDs or non-deterministic data like timestamps that cannot be predicted when writing the test code.
-// For these situations, package jsonmatch provides the CaptureField function.
+// For these situations, package jsonmatch provides the [CaptureField] function.
// The example below shows a test exercising a PUT endpoint to create an object, capturing the object's ID while asserting on the rest of the response, and then using that ID to exercise a GET endpoint that displays the created object.
//
// req1 := httptest.NewRequest(http.MethodPut, "/v1/things/new", strings.NewReader(`{"name":"hello"}`)
@@ -136,7 +136,7 @@ import (
"fmt"
)
-// Diffable is the common interface of types Object, Array, Scalar and Null from this package.
+// Diffable is the common interface of types [Object], [Array], [Scalar] and [Null] from this package.
// The DiffAgainst function compares the value contained in the Diffable against an encoded JSON payload.
//
// The implementation will try to generate diffs as granularly as possible.
@@ -174,7 +174,7 @@ var (
// Please refer to the package documentation for how to use this type.
type Array []any
-// DiffAgainst implements the Diffable interface.
+// DiffAgainst implements the [Diffable] interface.
func (a Array) DiffAgainst(buf []byte) []Diff {
return diffAgainst([]any(a), buf)
}
@@ -183,21 +183,21 @@ func (a Array) DiffAgainst(buf []byte) []Diff {
// Please refer to the package documentation for how to use this type.
type Object map[string]any
-// DiffAgainst implements the Diffable interface.
+// DiffAgainst implements the [Diffable] interface.
func (o Object) DiffAgainst(buf []byte) []Diff {
return diffAgainst(map[string]any(o), buf)
}
// Null implements diffing against an encoded JSON payload that is expected just the value `null`.
// This type is only used on the top level of the JSON payload.
-// Within type Object or type Array, put a `nil` directly.
+// Within type [Object] or type [Array], put a `nil` directly.
func Null() Diffable {
return scalar{nil}
}
// Scalar implements diffing against an encoded JSON payload that is expected to contain just a scalar value (a number, string or boolean).
// This type is only used on the top level of the JSON payload.
-// Within type Object or type Array, put the value directly.
+// Within type [Object] or type [Array,] put the value directly.
func Scalar[S ScalarValue](value S) Diffable {
return scalar{value}
}
@@ -206,12 +206,12 @@ type scalar struct {
Value any
}
-// DiffAgainst implements the Diffable interface.
+// DiffAgainst implements the [Diffable] interface.
func (s scalar) DiffAgainst(buf []byte) []Diff {
return diffAgainst(s.Value, buf)
}
-// ScalarValue is an interface containing every type that can be given to func Scalar.
+// ScalarValue is an interface containing every type that can be given to func [Scalar].
type ScalarValue interface {
~bool |
~int | ~int8 | ~int16 | ~int32 | ~int64 |
@@ -221,7 +221,7 @@ type ScalarValue interface {
}
// Diff is a difference between the actual encoded JSON payload given to a DiffAgainst() call, and the expectation encoded in the object that DiffAgainst() was called on.
-// See type Diffable for details on how diffing works.
+// See type [Diffable] for details on how diffing works.
type Diff struct {
// Kind explains the type of difference.
// No stability guarantee is given for the values that can occur in this field.
@@ -246,16 +246,16 @@ func (d Diff) String() string {
}
// Pointer is a JSON pointer (RFC 6901) that references a particular JSON value relative to the root of the encoded JSON payload that was given to DiffAgainst().
-// It appears in type Diff.
+// It appears in type [Diff].
//
// This type is intended to become synonymous with encoding/json/jsontext.Pointer once that type is stabilized.
type Pointer string
-// CaptureField returns a capture slot that can be placed in a jsonmatch.Object or jsonmatch.Array instance to capture individual non-deterministic values during an assertion.
+// CaptureField returns a capture slot that can be placed in an [Object] or [Array] instance to capture individual non-deterministic values during an assertion.
// Please refer to the package documentation for details and usage examples.
//
// Capture slots only work inside data structures that DiffAgainst() knows how to recurse into.
-// Please refer to the documentation on type Diffable for details.
+// Please refer to the documentation on type [Diffable] for details.
func CaptureField[T any](target *T) any {
// NOTE: The public interface is using generics because that allows enforcing
// that `target` is passed as pointer. But the internal representation holds
@@ -268,7 +268,7 @@ type capturedField struct {
PointerToTarget any
}
-// MarshalJSON implements the json.Marshaler interface by transparently marshaling the contained value.
+// MarshalJSON implements the [json.Marshaler] interface by transparently marshaling the contained value.
//
// This implementation ensures that `capturedField` looks like its payload
// when serialized for a "type mismatch" or "value mismatch" error message.
@@ -276,7 +276,7 @@ func (f capturedField) MarshalJSON() ([]byte, error) {
return json.Marshal(f.PointerToTarget)
}
-// UnmarshalJSON implements the json.Unmarshaler interface by always throwing an error.
+// UnmarshalJSON implements the [json.Unmarshaler] interface by always throwing an error.
//
// This implementation ensures that `capturedField` is not placed into a
// container that DiffAgainst() does not know how to recurse into.
@@ -286,19 +286,26 @@ func (f capturedField) UnmarshalJSON(buf []byte) error {
type irrelevant struct{}
-// Irrelevant returns a slot that can be placed in a jsonmatch.Object or jsonmatch.Array instance
+// Irrelevant returns a slot that can be placed in an [Object] or [Array] instance
// to ignore the contents of certain fields or array elements during an assertion.
//
// Irrelevant() slots only work inside data structures that DiffAgainst() knows how to recurse into.
-// Please refer to the documentation on type Diffable for details.
+// Please refer to the documentation on type [Diffable] for details.
func Irrelevant() any {
return irrelevant{}
}
-// MarshalJSON implements the json.Marshaler interface.
+// MarshalJSON implements the [json.Marshaler] interface.
//
// This implementation ensures that `irrelevant` renders in a readable way
// when a larger value containing it is serialized for a "type mismatch" or "value mismatch" error message.
func (irrelevant) MarshalJSON() ([]byte, error) {
return []byte(`"<irrelevant>"`), nil
}
+
+var (
+ // static assertion that the documented interfaces are indeed implemented
+ _ json.Marshaler = capturedField{}
+ _ json.Unmarshaler = capturedField{}
+ _ json.Marshaler = irrelevant{}
+)
diff --git a/option/option.go b/option/option.go
index 8bd614c..c41dd61 100644
--- a/option/option.go
+++ b/option/option.go
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2025 Stefan Majewsky <majewsky@gmx.net>
// SPDX-License-Identifier: Apache-2.0
-// Package optional provides an Option type for Go.
+// Package option provides an [Option] type for Go.
// A value of the Option type will be in one of two states: "Some" (containing a value) or "None" (containing no value).
//
// The purpose of the Option type is to more clearly distinguish the two situations that standard Go uses pointer types for:
@@ -306,7 +306,7 @@ var (
_ json.Unmarshaler = &Option[bool]{}
)
-// Format implements the fmt.Formatter interface.
+// Format implements the [fmt.Formatter] interface.
//
// If there is a contained value, it will be formatted as if it was given directly.
// Otherwise, the string "<none>" will be formatted according to the specified width and flags.
@@ -318,7 +318,7 @@ func (o Option[T]) Format(f fmt.State, verb rune) {
}
}
-// IsZero implements the IsZeroer interface as understood by encoding/json and github.com/go-yaml/yaml.
+// IsZero implements the IsZeroer interface as understood by encoding/json, github.com/go-yaml/yaml and github.com/yaml/go-yaml.
// It is an alias of IsNone().
func (o Option[T]) IsZero() bool {
return !o.isSome
@@ -328,7 +328,7 @@ type yamlMarshaler interface {
MarshalYAML() (any, error)
}
-// Scan implements the database/sql.Scanner interface.
+// Scan implements the [sql.Scanner] interface.
func (o *Option[T]) Scan(src any) error {
var data sql.Null[T]
err := data.Scan(src)
@@ -344,7 +344,7 @@ func (o *Option[T]) Scan(src any) error {
return nil
}
-// Value implements the database/sql/driver.Valuer interface.
+// Value implements the [driver.Valuer] interface.
func (o Option[T]) Value() (driver.Value, error) {
if o.isSome {
return driver.DefaultParameterConverter.ConvertValue(o.value)
@@ -353,7 +353,7 @@ func (o Option[T]) Value() (driver.Value, error) {
}
}
-// MarshalJSON implements the encoding/json.Marshaler interface.
+// MarshalJSON implements the [json.Marshaler] interface.
func (o Option[T]) MarshalJSON() ([]byte, error) {
if o.isSome {
return json.Marshal(o.value)
@@ -362,7 +362,7 @@ func (o Option[T]) MarshalJSON() ([]byte, error) {
}
}
-// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
+// UnmarshalJSON implements the [json.Unmarshaler] interface.
func (o *Option[T]) UnmarshalJSON(buf []byte) error {
var data *T
err := json.Unmarshal(buf, &data)
@@ -373,7 +373,7 @@ func (o *Option[T]) UnmarshalJSON(buf []byte) error {
return nil
}
-// MarshalYAML implements the yaml.Marshaler interface from gopkg.in/yaml.v2 and v3.
+// MarshalYAML implements the yaml.Marshaler interface from gopkg.in/yaml.v2 and v3 as well as go.yaml.in/yaml/v3.
func (o Option[T]) MarshalYAML() (any, error) {
if o.isSome {
// If we just return o.value directly here, MarshalYAML will not be called
@@ -391,8 +391,11 @@ func (o Option[T]) MarshalYAML() (any, error) {
// UnmarshalYAML implements the yaml.Unmarshaler interface from gopkg.in/yaml.v2.
//
-// gopkg.in/yaml.v3 supports this interface via backwards-compatibility,
-// so we intentionally do not use the v3-only signature that refers to the yaml.Node type.
+// gopkg.in/yaml.v3 and go.yaml.in/yaml/v3 support this interface via backwards-compatibility.
+// We cannot use the v3-only signature that refers to the yaml.Node type,
+// because that would require us to choose only one of either v3 libraries to support.
+//
+// Ref: https://github.com/yaml/go-yaml/issues/56
func (o *Option[T]) UnmarshalYAML(unmarshal func(any) error) error {
var data *T
err := unmarshal(&data)