Pull request: all: imp updater

Merge in DNS/adguard-home from imp-updater to master

Squashed commit of the following:

commit 6ed487359e56a35b36f13dcbf2efbf2a7a2d8734
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 9 16:29:35 2022 +0300

    all: imp logs, err handling

commit e930044cb619a43e5a44c230dadbe2228e9a93f5
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 9 15:53:35 2022 +0300

    all: imp updater
This commit is contained in:
Ainar Garipov
2022-06-09 17:47:05 +03:00
parent 302faca32f
commit e738508d7a
10 changed files with 124 additions and 125 deletions

View File

@@ -0,0 +1,59 @@
package aghalg
import (
"bytes"
"encoding/json"
"fmt"
)
// NullBool is a nullable boolean. Use these in JSON requests and responses
// instead of pointers to bool.
type NullBool uint8
// NullBool values
const (
NBNull NullBool = iota
NBTrue
NBFalse
)
// String implements the fmt.Stringer interface for NullBool.
func (nb NullBool) String() (s string) {
switch nb {
case NBNull:
return "null"
case NBTrue:
return "true"
case NBFalse:
return "false"
}
return fmt.Sprintf("!invalid NullBool %d", uint8(nb))
}
// BoolToNullBool converts a bool into a NullBool.
func BoolToNullBool(cond bool) (nb NullBool) {
if cond {
return NBTrue
}
return NBFalse
}
// type check
var _ json.Unmarshaler = (*NullBool)(nil)
// UnmarshalJSON implements the json.Unmarshaler interface for *NullBool.
func (nb *NullBool) UnmarshalJSON(b []byte) (err error) {
if len(b) == 0 || bytes.Equal(b, []byte("null")) {
*nb = NBNull
} else if bytes.Equal(b, []byte("true")) {
*nb = NBTrue
} else if bytes.Equal(b, []byte("false")) {
*nb = NBFalse
} else {
return fmt.Errorf("unmarshalling json data into aghalg.NullBool: bad value %q", b)
}
return nil
}

View File

@@ -0,0 +1,67 @@
package aghalg_test
import (
"encoding/json"
"testing"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNullBool_UnmarshalJSON(t *testing.T) {
testCases := []struct {
name string
wantErrMsg string
data []byte
want aghalg.NullBool
}{{
name: "empty",
wantErrMsg: "",
data: []byte{},
want: aghalg.NBNull,
}, {
name: "null",
wantErrMsg: "",
data: []byte("null"),
want: aghalg.NBNull,
}, {
name: "true",
wantErrMsg: "",
data: []byte("true"),
want: aghalg.NBTrue,
}, {
name: "false",
wantErrMsg: "",
data: []byte("false"),
want: aghalg.NBFalse,
}, {
name: "invalid",
wantErrMsg: `unmarshalling json data into aghalg.NullBool: bad value "invalid"`,
data: []byte("invalid"),
want: aghalg.NBNull,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var got aghalg.NullBool
err := got.UnmarshalJSON(tc.data)
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
assert.Equal(t, tc.want, got)
})
}
t.Run("json", func(t *testing.T) {
want := aghalg.NBTrue
var got struct {
A aghalg.NullBool
}
err := json.Unmarshal([]byte(`{"A":true}`), &got)
require.NoError(t, err)
assert.Equal(t, want, got.A)
})
}