12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package spec
- import (
- "bytes"
- "encoding/json"
- "reflect"
- "sort"
- )
- // OrderSchemaItem holds a named schema (e.g. from a property of an object)
- type OrderSchemaItem struct {
- Name string
- Schema
- }
- // OrderSchemaItems is a sortable slice of named schemas.
- // The ordering is defined by the x-order schema extension.
- type OrderSchemaItems []OrderSchemaItem
- // MarshalJSON produces a json object with keys defined by the name schemas
- // of the OrderSchemaItems slice, keeping the original order of the slice.
- func (items OrderSchemaItems) MarshalJSON() ([]byte, error) {
- buf := bytes.NewBuffer(nil)
- buf.WriteString("{")
- for i := range items {
- if i > 0 {
- buf.WriteString(",")
- }
- buf.WriteString("\"")
- buf.WriteString(items[i].Name)
- buf.WriteString("\":")
- bs, err := json.Marshal(&items[i].Schema)
- if err != nil {
- return nil, err
- }
- buf.Write(bs)
- }
- buf.WriteString("}")
- return buf.Bytes(), nil
- }
- func (items OrderSchemaItems) Len() int { return len(items) }
- func (items OrderSchemaItems) Swap(i, j int) { items[i], items[j] = items[j], items[i] }
- func (items OrderSchemaItems) Less(i, j int) (ret bool) {
- ii, oki := items[i].Extensions.GetString("x-order")
- ij, okj := items[j].Extensions.GetString("x-order")
- if oki {
- if okj {
- defer func() {
- if err := recover(); err != nil {
- defer func() {
- if err = recover(); err != nil {
- ret = items[i].Name < items[j].Name
- }
- }()
- ret = reflect.ValueOf(ii).String() < reflect.ValueOf(ij).String()
- }
- }()
- return reflect.ValueOf(ii).Int() < reflect.ValueOf(ij).Int()
- }
- return true
- } else if okj {
- return false
- }
- return items[i].Name < items[j].Name
- }
- // SchemaProperties is a map representing the properties of a Schema object.
- // It knows how to transform its keys into an ordered slice.
- type SchemaProperties map[string]Schema
- // ToOrderedSchemaItems transforms the map of properties into a sortable slice
- func (properties SchemaProperties) ToOrderedSchemaItems() OrderSchemaItems {
- items := make(OrderSchemaItems, 0, len(properties))
- for k, v := range properties {
- items = append(items, OrderSchemaItem{
- Name: k,
- Schema: v,
- })
- }
- sort.Sort(items)
- return items
- }
- // MarshalJSON produces properties as json, keeping their order.
- func (properties SchemaProperties) MarshalJSON() ([]byte, error) {
- if properties == nil {
- return []byte("null"), nil
- }
- return json.Marshal(properties.ToOrderedSchemaItems())
- }
|