github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/base/params/orderby.go (about)

     1  package params
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  )
     8  
     9  var (
    10  	// OrderASC defines the ascending order keyword
    11  	OrderASC = "+"
    12  	// OrderDESC defines the descending order keyword
    13  	OrderDESC = "-"
    14  )
    15  
    16  // OrderBy represents ordering information
    17  type OrderBy []*Order
    18  
    19  // OrderByFromRequest extracts orderBy params from an http request
    20  func OrderByFromRequest(r *http.Request) OrderBy {
    21  	orderBy := r.FormValue("orderBy")
    22  	return NewOrderByFromString(orderBy)
    23  }
    24  
    25  // NewOrderByFromString converts a comma delimited string to an OrderBy struct
    26  // eg: `+name,-updated,username`
    27  // OrderBy {
    28  //	{ Key: "name", Direction: OrderASC },
    29  //  { Key: "updated", Direction: OrderDESC },
    30  //  { Key: "username", Direction: OrderASC },
    31  // }
    32  func NewOrderByFromString(orderBy string) OrderBy {
    33  	orders := strings.Split(orderBy, ",")
    34  	res := []*Order{}
    35  	for _, orderStr := range orders {
    36  		order := NewOrderFromString(orderStr)
    37  		if order != nil {
    38  			res = append(res, order)
    39  		}
    40  	}
    41  	return res
    42  }
    43  
    44  // String implements the stringer interface for OrderBy
    45  func (o OrderBy) String() string {
    46  	var b strings.Builder
    47  	for i, oi := range o {
    48  		if i > 0 {
    49  			b.WriteString(",")
    50  		}
    51  		b.WriteString(oi.String())
    52  	}
    53  	return b.String()
    54  }
    55  
    56  // Order represents ordering information for a single key
    57  // Default direction is OrderASC
    58  type Order struct {
    59  	Key       string
    60  	Direction string
    61  }
    62  
    63  // NewOrder constructs a basic order struct
    64  func NewOrder(key, orderDirection string) *Order {
    65  	if key == "" {
    66  		return nil
    67  	}
    68  	if orderDirection != OrderASC && orderDirection != OrderDESC {
    69  		orderDirection = OrderASC
    70  	}
    71  	return &Order{
    72  		Key:       key,
    73  		Direction: orderDirection,
    74  	}
    75  }
    76  
    77  // NewOrderFromString constructs an order using a string
    78  // Default direction is ascending
    79  func NewOrderFromString(orderStr string) *Order {
    80  	if orderStr == "" {
    81  		return nil
    82  	}
    83  	key := orderStr
    84  	orderDirection := ""
    85  	if orderStr[0:1] == OrderDESC || orderStr[0:1] == OrderASC {
    86  		orderDirection = orderStr[0:1]
    87  		key = orderStr[1:]
    88  	}
    89  	return NewOrder(key, orderDirection)
    90  }
    91  
    92  // String implements the stringer interface for Order
    93  func (o *Order) String() string {
    94  	return fmt.Sprintf("%s%s", o.Direction, o.Key)
    95  }