Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于嵌套结构体成员实现了自定义序列化函数无法如预期调用的问题 #17

Open
keet3r opened this issue Dec 31, 2024 · 1 comment

Comments

@keet3r
Copy link

keet3r commented Dec 31, 2024

想请教一下,json-filter在序列化某个含有其他实现了自定义序列化函数的结构体时候,无法调用到这个函数的自定义序列化函数,比如下列定义

type a struct{
	Field StringArray `json: "field,select(test)"`
}
type StringArray struct{
	V []string
}
func (n *StringArray) MarshalJSON() ([]byte, error) {
	return json.Marshal(n.V)
}

理想状态下,对结构体a进行序列化验证代码如下:

package main

import (
	"encoding/json"
	"fmt"
	"github.com/liu-cn/json-filter/filter"
)

type A struct {
	Field *StringArray `json:"field,select(dump)"`
}

type StringArray struct {
	V []string
}

func NewStringArray() *StringArray {
	return &StringArray{V: make([]string, 0)}
}
func (n *StringArray) MarshalJSON() ([]byte, error) {
	return json.Marshal(n.V)
}
func main() {
	sa := NewStringArray()
	result, _ := json.Marshal(sa)
	fmt.Println(string(result))
	a := A{Field: sa}
	result, _ = json.Marshal(a)
	fmt.Println("原始序列化结果:", string(result))
	fmt.Println("go-filter序列化结果:", filter.Select("dump", a))
}

其执行结果如下
image
通过func()选择器来进行字段序列化,以及将select的传参改为指针传递可以取得跟预期一致的结果,代码如下

package main

import (
	"encoding/json"
	"fmt"
	"github.com/liu-cn/json-filter/filter"
)

type A struct {
	Field *StringArray `json:"field,select(dump),func(MarshalSA)"`
}

func (a *A) MarshalSA() []string {
	return a.Field.V
}

type StringArray struct {
	V []string
}

func NewStringArray() *StringArray {
	return &StringArray{V: make([]string, 0)}
}
func (n *StringArray) MarshalJSON() ([]byte, error) {
	return json.Marshal(n.V)
}
func main() {
	sa := NewStringArray()
	result, _ := json.Marshal(sa)
	fmt.Println(string(result))
	a := A{Field: sa}
	result, _ = json.Marshal(a)
	fmt.Println("原始序列化结果:", string(result))
	fmt.Println("go-filter序列化结果:", filter.Select("dump", &a))
}

执行结果如下
image

但是在开发中为每个嵌套使用了StringArray结构体的结构体都加上这么一个函数会非常繁琐,更别说有可能一个结构体嵌套使用了多个类似的实现了自定义序列化函数的结构体。
因此我想对json库进行一定程度上的修改,使得他可以判断结构体是否实现了自定义的MarshalJson以进行调用,也能更好的跟go官方库、simplejson等一系列库的序列化使用进行兼容,不知道应该要从哪里入手进行修改?

@liu-cn
Copy link
Owner

liu-cn commented Dec 31, 2024

https://github.com/liu-cn/json-filter/blob/main/filter/parser.go#L286 在这里,你可以在下面断言一下是否实现该接口,实现的话就调用这个接口方法获取到值,把值通过下面代码传下去,tree.parseAny(tag.UseFieldName, scene, value, isSelect)

	if t.IsAnonymous {
		t.AnonymousAddChild(tree)
	} else {
		t.AddChild(tree)
	}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants