forked from ohler55/ojg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalt.go
136 lines (119 loc) · 3.97 KB
/
alt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright (c) 2021, Peter Ohler, All rights reserved.
package alt
import (
"reflect"
"github.com/ohler55/ojg"
)
// Options is an alias for ojg.Options
type Options = ojg.Options
// Converter is an alias for ojg.Converter
type Converter = ojg.Converter
var (
// DefaultOptions are the default options for the this package.
DefaultOptions = ojg.DefaultOptions
// BrightOptions are the bright color options.
BrightOptions = ojg.BrightOptions
// GoOptions are the options that match the go json.Marshal behavior.
GoOptions = ojg.GoOptions
// HTMLOptions are the options that can be used to encode as HTML JSON.
HTMLOptions = ojg.HTMLOptions
// TimeRFC3339Converter converts RFC3339 string into time.Time when
// parsing.
TimeRFC3339Converter = ojg.TimeRFC3339Converter
// TimeNanoConverter converts integer values to time.Time assuming the
// integer are nonoseconds,
TimeNanoConverter = ojg.TimeNanoConverter
// MongoConverter converts mongodb decorations into the correct times.
MongoConverter = ojg.MongoConverter
)
func init() {
// Use different defaults for decompose except the Go defaults. Set
// OmitNil and provide a CreateKey for all.
DefaultOptions.OmitNil = true
DefaultOptions.CreateKey = "type"
BrightOptions.OmitNil = true
BrightOptions.CreateKey = "type"
HTMLOptions.OmitNil = true
HTMLOptions.CreateKey = "type"
}
// Dup is an alias for Decompose.
func Dup(v interface{}, options ...*ojg.Options) interface{} {
return Decompose(v, options...)
}
// Decompose creates a simple type converting non simple to simple types using
// either the Simplify() interface or reflection. Unlike Alter() a deep copy
// is returned leaving the original data unchanged.
func Decompose(v interface{}, options ...*ojg.Options) interface{} {
opt := &DefaultOptions
if 0 < len(options) {
opt = options[0]
}
if opt.Converter != nil {
v = opt.Converter.Convert(v)
}
return decompose(v, opt)
}
// Alter the data into all simple types converting non simple to simple types
// using either the Simplify() interface or reflection. Unlike Decompose() map
// and slice members are modified if necessary to assure all elements are
// simple types.
func Alter(v interface{}, options ...*ojg.Options) interface{} {
opt := &DefaultOptions
if 0 < len(options) {
opt = options[0]
}
if opt.Converter != nil {
v = opt.Converter.Convert(v)
}
return alter(v, opt)
}
// Recompose simple data into more complex go types.
func Recompose(v interface{}, tv ...interface{}) (out interface{}, err error) {
return DefaultRecomposer.Recompose(v, tv...)
}
// MustRecompose simple data into more complex go types and panics on error.
func MustRecompose(v interface{}, tv ...interface{}) (out interface{}) {
return DefaultRecomposer.MustRecompose(v, tv...)
}
// NewRecomposer creates a new instance. The composers are a map of objects
// expected and functions to recompose them. If no function is provided then
// reflection is used instead.
func NewRecomposer(
createKey string,
composers map[interface{}]RecomposeFunc,
anyComposers ...map[interface{}]RecomposeAnyFunc) (rec *Recomposer, err error) {
defer func() {
if r := recover(); r != nil {
err = ojg.NewError(r)
}
}()
rec = MustNewRecomposer(createKey, composers, anyComposers...)
return
}
// MustNewRecomposer creates a new instance. The composers are a map of objects
// expected and functions to recompose them. If no function is provided then
// reflection is used instead. Panics on error.
func MustNewRecomposer(
createKey string,
composers map[interface{}]RecomposeFunc,
anyComposers ...map[interface{}]RecomposeAnyFunc) *Recomposer {
r := Recomposer{
CreateKey: createKey,
composers: map[string]*composer{},
}
for v, fun := range composers {
rt := reflect.TypeOf(v)
if _, err := r.registerComposer(rt, fun); err != nil {
panic(err)
}
}
if 0 < len(anyComposers) {
for v, fun := range anyComposers[0] {
rt := reflect.TypeOf(v)
if _, err := r.registerAnyComposer(rt, fun); err != nil {
panic(err)
}
}
}
return &r
}