|
@@ -0,0 +1,135 @@
|
|
|
|
+package rest
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "fmt"
|
|
|
|
+ "reflect"
|
|
|
|
+
|
|
|
|
+ "git.ali33.ru/fcg-xvii/go-tools/json"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+type OrderType byte
|
|
|
|
+
|
|
|
|
+func parseOrder(order json.Map, parent string) (IOrderObject, error) {
|
|
|
|
+ parentName := func(name string) string {
|
|
|
|
+ if len(parent) > 0 {
|
|
|
|
+ return fmt.Sprintf("%s.%s", parent, name)
|
|
|
|
+ }
|
|
|
|
+ return name
|
|
|
|
+ }
|
|
|
|
+ obj := &_orderObject{
|
|
|
|
+ orders: make(map[string]IOrder),
|
|
|
|
+ }
|
|
|
|
+ for k, v := range order {
|
|
|
|
+ rv := reflect.ValueOf(v)
|
|
|
|
+ switch rv.Kind() {
|
|
|
|
+ case reflect.Bool:
|
|
|
|
+ obj.orders[k] = &_orderField{
|
|
|
|
+ fieldName: k,
|
|
|
|
+ isAsc: v.(bool),
|
|
|
|
+ }
|
|
|
|
+ case reflect.Map:
|
|
|
|
+ t := reflect.TypeOf(order)
|
|
|
|
+ if rv.CanConvert(t) {
|
|
|
|
+ childRV := rv.Convert(t)
|
|
|
|
+ child, err := parseOrder(childRV.Interface().(json.Map), parentName(k))
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+ obj.orders[k] = child
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ return nil, fmt.Errorf("unexpected type in [%v]", parentName(k))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return obj, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const (
|
|
|
|
+ OrderField OrderType = iota
|
|
|
|
+ OrderObject
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+type IOrder interface {
|
|
|
|
+ Type() OrderType
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type IOrderField interface {
|
|
|
|
+ IOrder
|
|
|
|
+ FieldName() string
|
|
|
|
+ IsAsc() bool
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type IOrderObject interface {
|
|
|
|
+ IOrder
|
|
|
|
+ MapOrder() map[string]IOrder
|
|
|
|
+ MapFields() map[string]IOrderField
|
|
|
|
+ MapObjects() map[string]IOrderObject
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+type _orderField struct {
|
|
|
|
+ fieldName string
|
|
|
|
+ isAsc bool
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderField) FieldName() string {
|
|
|
|
+ return s.fieldName
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderField) IsAsc() bool {
|
|
|
|
+ return s.isAsc
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderField) Type() OrderType {
|
|
|
|
+ return OrderField
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderField) String() string {
|
|
|
|
+ return fmt.Sprintf("%v: %v\n", s.fieldName, s.isAsc)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+type _orderObject struct {
|
|
|
|
+ orders map[string]IOrder
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderObject) Type() OrderType {
|
|
|
|
+ return OrderObject
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderObject) MapOrder() map[string]IOrder {
|
|
|
|
+ return s.orders
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderObject) MapFields() map[string]IOrderField {
|
|
|
|
+ res := make(map[string]IOrderField)
|
|
|
|
+ for k, v := range s.orders {
|
|
|
|
+ if v.Type() == OrderField {
|
|
|
|
+ res[k] = v.(IOrderField)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return res
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderObject) MapObjects() map[string]IOrderObject {
|
|
|
|
+ res := make(map[string]IOrderObject)
|
|
|
|
+ for k, v := range s.orders {
|
|
|
|
+ if v.Type() == OrderObject {
|
|
|
|
+ res[k] = v.(IOrderObject)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return res
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *_orderObject) String() string {
|
|
|
|
+ res := "{\n"
|
|
|
|
+ for k, v := range s.orders {
|
|
|
|
+ res += fmt.Sprintf("\t%s: %v", k, v)
|
|
|
|
+ }
|
|
|
|
+ res += "}\n"
|
|
|
|
+ return res
|
|
|
|
+}
|