Documentation ¶
Index ¶
- func MergeTo(target *Data, data ...Data)
- type Data
- func (d Data) Clone() Data
- func (d Data) Get(fields ...string) interface{}
- func (d Data) JSON(pretty bool) string
- func (d Data) Len() int
- func (d Data) MarshalJSON() ([]byte, error)
- func (d Data) PrettyString() string
- func (d Data) Query(query string) interface{}
- func (d Data) String() string
- func (d *Data) UnmarshalJSON(src []byte) error
- type Decoder
- type Encoder
- type FieldTag
- type Patch
- type PatchAction
- type RawData
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Data ¶
type Data struct {
// contains filtered or unexported fields
}
Data 是一种通用的数据存储结构,可以用于表达各种以 JSON、TOML、YAML 等为介质的数据, 也可以用于序列化/反序列化 Go struct。
Data 里面的数据不允许随意修改,只能通过 `MergeTo`、`Patch#ApplyTo` 等方法修改。
func Make ¶
Make 将一个普通 m 转化成 Data。 虽然 m 和 Data 类型一样,但是要成为 Data 必须得过滤掉不合法的数据, 也需要将 struct 转化成 Data 格式。
Make 适合用于将 JSON、YAML 等反序列化工具获得的 map[string]interface{} 数据转化成 Data, 假设需要将任意数据转化成 Data,应该使用 Encoder。
func Merge ¶
Merge 将多个 data 从左至右合并到 d 里面,如果有同名的 key 会进行深度遍历进行合并。 返回的 d 是一个全新的 Data,修改 d 的内容不会影响参数中任何的 data。
具体的合并规则是:
- 对于 Data 类型的数值,将相同的 key 进行深度合并;
- 如果出现同名 key 且 value 类型相同,都是 Data 或者 slice,深度合并 value 值;
- 如果出现同名 key 且 value 类型不同,后面出现的 value 覆盖前面的 value。
- 对于 slice 类型的数值,如果两个 slice 类型相同,后面出现的 slice 的值会被 append 进去。
func Parse ¶
Parse 从 str 中解析 Data,这个 str 应该是符合 Data 序列化格式的字符串。 如果 str 格式不合法,返回错误。
Data 序列化格式定义如下:
'<' type '>' raw
当前 type 仅支持 JSON,值为 `json`,对应的 raw 是 JSON 字符串。 例如:
<json>{"hello":"world!"}
func ParseJSON ¶
ParseJSON 解析 JSON 字符串并且生成 Data,如果解析过程出现任何错误则返回错误。 由于 Data 是一个 map,所以 JSON 必须是一个 object,如果不是则返回错误。
func (Data) Get ¶
Get 通过 fields 找到对应的值并且返回,如果找不到则返回 nil。
其中,field 是一个数组,例如 []string{"a", "b", "c"} 代表访问 d["a"]["b"]["c"]。 如果希望访问数组元素,可以直接写数组下标数字,比如 []string{"a", "0", "c"} 代表访问 d["a"][0]["c"]。
func (Data) Query ¶
Query 解析 query 找到对应的值并且返回,如果找不到则返回 nil。
其中,query 的格式是以“.”分隔的字段,例如 a.b.c 代表访问 d["a"]["b"]["c"]。 如果希望访问数组元素,可以直接写数组下标数字,比如 a.0.c 代表访问 d["a"][0]["c"]。
func (*Data) UnmarshalJSON ¶
UnmarshalJSON 解析 JSON 字符串并设置 d 的值。 这里不直接使用 `json.Unmarshal` 来反序列化的原因是,`Data` 内部要求统一所有的数据类型, 但 `json.Marshal` 无法满足这个要求。
type Decoder ¶
type Decoder struct {
TagName string // 在解析 struct 时候使用的 field tag,默认是 data。
}
Decoder 用来将 Data 设置到指定值里面去。
func (*Decoder) DecodeField ¶
DecodeField 通过 field 找到对应的值并且解析到 v 中。 其中,field 的格式详见 `Data#Get` 文档。
type Encoder ¶
type Encoder struct { TagName string // 在解析 struct 时候使用的 field tag,默认是 data。 OmitEmpty bool // 如果为 true,则默认所有字段都会忽略空值。 }
Encoder 用来将数据转化成 Data。
type FieldTag ¶
type FieldTag struct { Alias string // 字段别名。 Skipped bool // 字段别名为“-”时,跳过这个字段。 OmitEmpty bool // 忽略空值。 Squash bool // 是否展开。 }
FieldTag 是一个解析完成的字段 tag。
格式是:
data:"alias,opt1,opt2,..."
当前支持以下选项:
- omitempty:忽略空值
- squash:将一个字段的内容展开到当前 struct
当 alias 为“-”时,当前字段会被跳过。
func ParseFieldTag ¶
ParseFieldTag 解析 field tag 的 alias 和选项。 详细的格式见 FieldTag 文档。
type Patch ¶
type Patch struct {
// contains filtered or unexported fields
}
Patch 代表一系列的对 Data 的修改操作。
Example ¶
patch := NewPatch() // 删除 d["v2"]、d["v3"][1]、d["v4"]["v4-4"]。 patch.Add([]string{"v2", "v3.1", "v4.v4-1"}, nil) // 添加数据。 patch.Add(nil, map[string]Data{ // 在根添加数据。 "": Make(RawData{ "v1": []int{2, 3}, "v2": 456, }), // 在 d["v4"] 里添加数据。 "v4": Make(RawData{ "v4-1": "new", }), }) // 同时删除并添加数据。 patch.Add([]string{"v4.v4-2"}, map[string]Data{ "v4": Make(RawData{ "v4-2": RawData{ "new": true, }, }), }) d := Make(RawData{ "v1": []int{1}, "v2": 123, "v3": []string{"first", "second", "third"}, "v4": RawData{ "v4-1": "old", "v4-2": RawData{ "old": true, }, }, }) patch.ApplyTo(&d) fmt.Println(d)
Output: <json>{"v1":[1,2,3],"v2":456,"v3":["first","third"],"v4":{"v4-1":"new","v4-2":{"new":true}}}
func (*Patch) Add ¶
Add 增加一个新的 patch 操作。 每个 patch 操作都由 deletes 和 updates 组成,实际 apply 的时候 会先删除所有 deletes 字段,然后再使用 updates 进行更新。 updates 的 key 是 Data 的 query,apply 时候会按照字典顺序从小到大排序之后合并更新到 Data。
需要注意,`Patch#Apply`/`Patch#ApplyTo` 使用 `Merge`/`MergeTo` 来更新 Data, merge 系列函数会深度遍历 map/slice,这导致新值无法简单覆盖老值。 如果希望新值覆盖老值,而不是合并,那么得先用 deletes 删除老值再合并。
type PatchAction ¶
type PatchAction struct { Deletes []string `data:"deletes"` Updates map[string]Data `data:"updates"` }
PatchAction 代表一个 patch 操作。
func (*PatchAction) ApplyTo ¶
func (action *PatchAction) ApplyTo(target *Data) error
ApplyTo 将一个 action 应用到 target。
type RawData ¶
type RawData map[string]interface{}
RawData 是一种未经加工的 map[string]interface{}。