// +build go1.18 /* * Copyright 2021 ByteDance Inc. * * 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 generic_test import ( `testing` `reflect` `github.com/bytedance/sonic` `github.com/bytedance/sonic/option` `github.com/bytedance/sonic/ast` ) type Str interface { string } type Bytes interface { []byte } type Any interface { any } type SliceAny interface { []any } func unmarshalAny[S Str, B Bytes, T Any](data S, val T) error { return sonic.Unmarshal(B(data), val) } func marshalAny[B Bytes, T Any](val T) (B, error) { return sonic.Marshal(val) } func getAny[S Str, B Bytes, T SliceAny](src S, path T) (ast.Node, error) { return sonic.Get(B(src), path...) } func pretouchAny[T Any](v T, opts ...option.CompileOption) error { rt := reflect.TypeOf(v) return sonic.Pretouch(rt, opts...) } type Basic interface { ~*int|~*float64|~float64|~*string } func unmarshalBasic[S Str, B Bytes, T Basic](data S, val T) error { return sonic.Unmarshal(B(data), val) } func marshalBasic[B Bytes, T Basic](val T) (B, error) { return sonic.Marshal(val) } func pretouchBasic[T Basic](v T, opts ...option.CompileOption) error { rt := reflect.TypeOf(v) return sonic.Pretouch(rt, opts...) } type Float64 float64 func TestGenericAPI(t *testing.T) { var x interface{} if err := unmarshalAny(`{"a":[true,0.5,"hello world"]}`, &x); err != nil { t.Fatal(t) } out, err := marshalAny(x) if err != nil { t.Fatal(err) } t.Logf("%s", out) var x0 = struct{ A []Any `json:"a"` }{} if err := pretouchAny(x0); err != nil { t.Fatal(err) } if err := unmarshalAny(`{"a":[true,0.5,"hello world"]}`, &x0); err != nil { t.Fatal(t) } out0, err := marshalAny(x0) if err != nil { t.Fatal(err) } t.Logf("%s", out0) var x1 int if err := unmarshalBasic(`1`, &x1); err != nil { t.Fatal(t) } out1, err := marshalBasic(&x1) if err != nil { t.Fatal(err) } t.Logf("%s", out1) var x2 Float64 = 1 // if err := unmarshalBasic(`1`, &x2); err != nil { // t.Fatal(t) // } out2, err := marshalBasic(x2) if err != nil { t.Fatal(err) } t.Logf("%s", out2) var x3 string if err := unmarshalBasic(`"1"`, &x3); err != nil { t.Fatal(t) } out3, err := marshalBasic(&x3) if err != nil { t.Fatal(err) } t.Logf("%s", out3) var x4 Float64 = 1 if err := pretouchBasic(x4); err != nil { t.Fatal(err) } // if err := unmarshalBasic(`0.5`, &x4); err != nil { // t.Fatal(t) // } out4, err := marshalBasic(x4) if err != nil { t.Fatal(err) } t.Logf("%s", out4) root, err := getAny(`{"a":[true,1,"hello world"]}`, []interface{}{"a", 1}) if err != nil { t.Fatal(err) } f, err := root.Float64() if err != nil { t.Fatal(err) } t.Log(f) }