File size: 1,402 Bytes
1f10f31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package request

import (
	"errors"
	"strings"

	"github.com/openmeterio/openmeter/pkg/sortx"
)

type SortOrder string

const (
	SortOrderAsc  SortOrder = "asc"
	SortOrderDesc SortOrder = "desc"
)

var (
	ErrSortByInvalid     = errors.New("invalid sort by")
	ErrSortFieldRequired = errors.New("sort field is required")
	ErrSortOrderInvalid  = errors.New("sort order must be either asc or desc")
	defaultOrder         = SortOrderAsc
)

func (s SortOrder) Validate() error {
	if s != SortOrderAsc && s != SortOrderDesc {
		return ErrSortOrderInvalid
	}

	return nil
}

type SortBy struct {
	Field string
	Order SortOrder
}

func ParseSortBy(sort string) (*SortBy, error) {
	var s SortBy
	err := s.UnmarshalText([]byte(sort))
	if err != nil {
		return nil, err
	}

	return &s, nil
}

func (s SortBy) Validate() error {
	if s.Field == "" {
		return ErrSortFieldRequired
	}

	if err := s.Order.Validate(); err != nil {
		return err
	}

	return nil
}

func (s *SortBy) UnmarshalText(text []byte) error {
	parts := strings.Fields(string(text))
	if len(parts) == 0 {
		return ErrSortByInvalid
	}
	if len(parts) > 2 {
		return ErrSortByInvalid
	}

	s.Field = parts[0]
	if len(parts) == 2 {
		s.Order = SortOrder(parts[1])
	} else {
		s.Order = defaultOrder
	}

	return s.Validate()
}

func (s SortOrder) ToSortxOrder() sortx.Order {
	if s == SortOrderAsc {
		return sortx.OrderAsc
	}

	return sortx.OrderDesc
}