Skip to content

Commit 57c3ea3

Browse files
committed
[+] feat: Add ExtractAll function
1 parent 1dd5628 commit 57c3ea3

File tree

4 files changed

+89
-6
lines changed

4 files changed

+89
-6
lines changed

any_ltgo17.go

-3
This file was deleted.

import_export.go

+55-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,59 @@ func Import(src any, opts ...Option) (*V, error) {
3939
return res, nil
4040
}
4141

42-
// parserFunc 处理对应 reflect.Value 的函数
42+
// ExtractAll firstly does Import, then checks all string-typed value. Once they
43+
// could be successfully unmarshal again, they will be unmarshaled again until
44+
// no sub-value could be unmarshaled any more.
45+
//
46+
// ExtractAll 首先执行 Import 操作, 然后再迭代检查所有 string 类型的值, 如果能够再成功执行
47+
// unmarshal 操作, 则继续将这些值 unmarshal 掉。如此以往直至所有值均无法再反序列化。
48+
func ExtractAll(src any, opts ...Option) (*V, error) {
49+
v, err := Import(src, opts...)
50+
if err != nil {
51+
return v, err
52+
}
53+
return extractValue(v), nil
54+
}
55+
56+
func extractValue(v *V) *V {
57+
switch v.valueType {
58+
case String:
59+
return extractStringValue(v)
60+
case Object:
61+
return extractObjectValue(v)
62+
case Array:
63+
return extractArrayValue(v)
64+
default:
65+
return v
66+
}
67+
}
68+
69+
func extractStringValue(v *V) *V {
70+
newV, err := UnmarshalString(v.valueStr)
71+
if err != nil {
72+
return v
73+
}
74+
return extractValue(newV)
75+
}
76+
77+
func extractObjectValue(v *V) *V {
78+
for key, subV := range v.children.object {
79+
v.children.object[key] = childWithProperty{
80+
id: subV.id,
81+
v: extractValue(subV.v),
82+
}
83+
}
84+
return v
85+
}
86+
87+
func extractArrayValue(v *V) *V {
88+
for i, subV := range v.children.arr {
89+
v.children.arr[i] = extractValue(subV)
90+
}
91+
return v
92+
}
93+
94+
// parserFunc handle functions operating various reflect.Value types
4395
type parserFunc func(v reflect.Value, ex ext) (*V, error)
4496

4597
type ext struct {
@@ -61,7 +113,7 @@ func (e ext) shouldOmitEmpty() bool {
61113
return e.omitempty || e.private
62114
}
63115

64-
// validateValAndReturnParser 检查入参合法性并返回相应的处理函数
116+
// validateValAndReturnParser checks incoming parameter and return corresponding handler
65117
func validateValAndReturnParser(v reflect.Value, ex ext) (out reflect.Value, fu parserFunc, err error) {
66118
out = v
67119

@@ -138,7 +190,7 @@ func validateValAndReturnParser(v reflect.Value, ex ext) (out reflect.Value, fu
138190
return
139191
}
140192

141-
// Hit marshaler if fu is not nil.
193+
// Get marshaler if fu is not nil.
142194
func checkAndParseMarshaler(v reflect.Value) (out reflect.Value, fu parserFunc) {
143195
out = v
144196
if !v.IsValid() {

import_export_test.go

+32
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ func testImportExport(t *testing.T) {
2525
cv("test Issue 22", func() { testImportBugIssue22(t) })
2626

2727
cv("test miscellaneous anonymous situations", func() { testImportMiscAnonymous(t) })
28+
29+
cv("test ExtractAll", func() { testExtractAll(t) })
2830
}
2931

3032
func testExportString(*testing.T) {
@@ -1381,3 +1383,33 @@ type refTextMarshaler struct {
13811383
func (r *refTextMarshaler) MarshalText() ([]byte, error) {
13821384
return []byte(r.s), nil
13831385
}
1386+
1387+
func testExtractAll(t *testing.T) {
1388+
cv("general situation", func() {
1389+
v := NewObject()
1390+
v.At("string").Set("hello, world")
1391+
v.At("int").Set("12345")
1392+
v.At("bool").Set(true)
1393+
t.Log(v.MustMarshalString())
1394+
1395+
v = New(map[string]any{"embeded": v.MustMarshalString()})
1396+
v = New(map[string]any{"embeded_again": v.MustMarshalString()})
1397+
t.Log(v.MustMarshalString()) // should contains "\\\""
1398+
_, err := v.Get("embeded_again", "embeded", "string")
1399+
so(err, isErr)
1400+
1401+
v, err = ExtractAll(v)
1402+
t.Log(v.MustMarshalString())
1403+
so(err, isNil)
1404+
1405+
subV, err := v.Get("embeded_again", "embeded", "string")
1406+
so(err, isNil)
1407+
so(subV.ValueType(), eq, String)
1408+
so(subV.String(), eq, "hello, world")
1409+
1410+
subV, err = v.Get("embeded_again", "embeded", "int")
1411+
so(err, isNil)
1412+
so(subV.ValueType(), eq, Number)
1413+
so(subV.Int(), eq, 12345)
1414+
})
1415+
}

jsonvalue.go

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ const (
7070
Unknown
7171
)
7272

73+
type any = interface{}
74+
7375
var typeStr = [Unknown + 1]string{
7476
"illegal",
7577
"string",

0 commit comments

Comments
 (0)