Pull request 2319: websvc-patch
Merge in DNS/adguard-home from websvc-patch to master
Squashed commit of the following:
commit b2a10faf12b16f13f617b3ed3ef3e81cb0479ff8
Merge: 38f749106 8f53f6505
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date: Wed Dec 11 17:33:15 2024 +0300
Merge branch 'master' into websvc-patch
commit 38f7491069d90d4080e7ad98b09bf9ce19138195
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date: Tue Dec 10 19:57:54 2024 +0300
next: add json merge patch utils
This commit is contained in:
43
internal/next/jsonpatch/jsonpatch.go
Normal file
43
internal/next/jsonpatch/jsonpatch.go
Normal file
@@ -0,0 +1,43 @@
|
||||
// Package jsonpatch contains utilities for JSON Merge Patch APIs.
|
||||
//
|
||||
// See https://www.rfc-editor.org/rfc/rfc7396.
|
||||
package jsonpatch
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
)
|
||||
|
||||
// NonRemovable is a type that prevents JSON null from being used to try and
|
||||
// remove a value.
|
||||
type NonRemovable[T any] struct {
|
||||
Value T
|
||||
IsSet bool
|
||||
}
|
||||
|
||||
// type check
|
||||
var _ json.Unmarshaler = (*NonRemovable[struct{}])(nil)
|
||||
|
||||
// UnmarshalJSON implements the [json.Unmarshaler] interface for *NonRemovable.
|
||||
func (v *NonRemovable[T]) UnmarshalJSON(b []byte) (err error) {
|
||||
if v == nil {
|
||||
return errors.Error("jsonpatch.NonRemovable is nil")
|
||||
}
|
||||
|
||||
if bytes.Equal(b, []byte("null")) {
|
||||
return errors.Error("property cannot be removed")
|
||||
}
|
||||
|
||||
v.IsSet = true
|
||||
|
||||
return json.Unmarshal(b, &v.Value)
|
||||
}
|
||||
|
||||
// Set sets ptr if the value has been provided.
|
||||
func (v NonRemovable[T]) Set(ptr *T) {
|
||||
if v.IsSet {
|
||||
*ptr = v.Value
|
||||
}
|
||||
}
|
||||
29
internal/next/jsonpatch/jsonpatch_test.go
Normal file
29
internal/next/jsonpatch/jsonpatch_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package jsonpatch_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/next/jsonpatch"
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNonRemovable(t *testing.T) {
|
||||
type T struct {
|
||||
Value jsonpatch.NonRemovable[int] `json:"value"`
|
||||
}
|
||||
|
||||
var v T
|
||||
|
||||
err := json.Unmarshal([]byte(`{"value":null}`), &v)
|
||||
testutil.AssertErrorMsg(t, "property cannot be removed", err)
|
||||
|
||||
err = json.Unmarshal([]byte(`{"value":42}`), &v)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var got int
|
||||
v.Value.Set(&got)
|
||||
|
||||
assert.Equal(t, 42, got)
|
||||
}
|
||||
Reference in New Issue
Block a user