podman
91 строка · 2.4 Кб
1package spec
2
3import (
4"bytes"
5"encoding/json"
6"reflect"
7"sort"
8)
9
10// OrderSchemaItem holds a named schema (e.g. from a property of an object)
11type OrderSchemaItem struct {
12Name string
13Schema
14}
15
16// OrderSchemaItems is a sortable slice of named schemas.
17// The ordering is defined by the x-order schema extension.
18type OrderSchemaItems []OrderSchemaItem
19
20// MarshalJSON produces a json object with keys defined by the name schemas
21// of the OrderSchemaItems slice, keeping the original order of the slice.
22func (items OrderSchemaItems) MarshalJSON() ([]byte, error) {
23buf := bytes.NewBuffer(nil)
24buf.WriteString("{")
25for i := range items {
26if i > 0 {
27buf.WriteString(",")
28}
29buf.WriteString("\"")
30buf.WriteString(items[i].Name)
31buf.WriteString("\":")
32bs, err := json.Marshal(&items[i].Schema)
33if err != nil {
34return nil, err
35}
36buf.Write(bs)
37}
38buf.WriteString("}")
39return buf.Bytes(), nil
40}
41
42func (items OrderSchemaItems) Len() int { return len(items) }
43func (items OrderSchemaItems) Swap(i, j int) { items[i], items[j] = items[j], items[i] }
44func (items OrderSchemaItems) Less(i, j int) (ret bool) {
45ii, oki := items[i].Extensions.GetInt("x-order")
46ij, okj := items[j].Extensions.GetInt("x-order")
47if oki {
48if okj {
49defer func() {
50if err := recover(); err != nil {
51defer func() {
52if err = recover(); err != nil {
53ret = items[i].Name < items[j].Name
54}
55}()
56ret = reflect.ValueOf(ii).String() < reflect.ValueOf(ij).String()
57}
58}()
59return ii < ij
60}
61return true
62} else if okj {
63return false
64}
65return items[i].Name < items[j].Name
66}
67
68// SchemaProperties is a map representing the properties of a Schema object.
69// It knows how to transform its keys into an ordered slice.
70type SchemaProperties map[string]Schema
71
72// ToOrderedSchemaItems transforms the map of properties into a sortable slice
73func (properties SchemaProperties) ToOrderedSchemaItems() OrderSchemaItems {
74items := make(OrderSchemaItems, 0, len(properties))
75for k, v := range properties {
76items = append(items, OrderSchemaItem{
77Name: k,
78Schema: v,
79})
80}
81sort.Sort(items)
82return items
83}
84
85// MarshalJSON produces properties as json, keeping their order.
86func (properties SchemaProperties) MarshalJSON() ([]byte, error) {
87if properties == nil {
88return []byte("null"), nil
89}
90return json.Marshal(properties.ToOrderedSchemaItems())
91}
92