...

Source file src/github.com/go-openapi/spec/properties.go

Documentation: github.com/go-openapi/spec

     1  package spec
     2  
     3  import (
     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)
    11  type OrderSchemaItem struct {
    12  	Name string
    13  	Schema
    14  }
    15  
    16  // OrderSchemaItems is a sortable slice of named schemas.
    17  // The ordering is defined by the x-order schema extension.
    18  type 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.
    22  func (items OrderSchemaItems) MarshalJSON() ([]byte, error) {
    23  	buf := bytes.NewBuffer(nil)
    24  	buf.WriteString("{")
    25  	for i := range items {
    26  		if i > 0 {
    27  			buf.WriteString(",")
    28  		}
    29  		buf.WriteString("\"")
    30  		buf.WriteString(items[i].Name)
    31  		buf.WriteString("\":")
    32  		bs, err := json.Marshal(&items[i].Schema)
    33  		if err != nil {
    34  			return nil, err
    35  		}
    36  		buf.Write(bs)
    37  	}
    38  	buf.WriteString("}")
    39  	return buf.Bytes(), nil
    40  }
    41  
    42  func (items OrderSchemaItems) Len() int      { return len(items) }
    43  func (items OrderSchemaItems) Swap(i, j int) { items[i], items[j] = items[j], items[i] }
    44  func (items OrderSchemaItems) Less(i, j int) (ret bool) {
    45  	ii, oki := items[i].Extensions.GetInt("x-order")
    46  	ij, okj := items[j].Extensions.GetInt("x-order")
    47  	if oki {
    48  		if okj {
    49  			defer func() {
    50  				if err := recover(); err != nil {
    51  					defer func() {
    52  						if err = recover(); err != nil {
    53  							ret = items[i].Name < items[j].Name
    54  						}
    55  					}()
    56  					ret = reflect.ValueOf(ii).String() < reflect.ValueOf(ij).String()
    57  				}
    58  			}()
    59  			return ii < ij
    60  		}
    61  		return true
    62  	} else if okj {
    63  		return false
    64  	}
    65  	return 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.
    70  type SchemaProperties map[string]Schema
    71  
    72  // ToOrderedSchemaItems transforms the map of properties into a sortable slice
    73  func (properties SchemaProperties) ToOrderedSchemaItems() OrderSchemaItems {
    74  	items := make(OrderSchemaItems, 0, len(properties))
    75  	for k, v := range properties {
    76  		items = append(items, OrderSchemaItem{
    77  			Name:   k,
    78  			Schema: v,
    79  		})
    80  	}
    81  	sort.Sort(items)
    82  	return items
    83  }
    84  
    85  // MarshalJSON produces properties as json, keeping their order.
    86  func (properties SchemaProperties) MarshalJSON() ([]byte, error) {
    87  	if properties == nil {
    88  		return []byte("null"), nil
    89  	}
    90  	return json.Marshal(properties.ToOrderedSchemaItems())
    91  }
    92  

View as plain text