package transport import ( "cmp" "errors" "fmt" "net/http" "slices" ) var ErrUnsupportedRequest = errors.New("unsupported request") type Properties uint8 const ( // PropertiesFree indicates that the transport is free. // This means that requests made with this transport don't cost any money. PropertiesFree Properties = 1 << iota // PropertiesReliable indicates that the transport is reliable. // This means that requests made with this transport are guaranteed to be // successful if the server is reachable. PropertiesReliable ) func (p Properties) IsReliable() bool { return p&PropertiesReliable != 0 } func (p Properties) IsFree() bool { return p&PropertiesFree != 0 } type Transport interface { fmt.Stringer Do(req *http.Request) (*http.Response, error) Properties() Properties } // SortTransports sorts the transports by their properties. // // The transports are sorted in the following order: // 1. Free transports // 2. Reliable transports func SortTransports(transports []Transport) { priorities := map[Properties]int{ PropertiesFree | PropertiesReliable: 0, PropertiesFree: 1, PropertiesReliable: 2, } slices.SortStableFunc(transports, func(a, b Transport) int { iPriority := priorities[a.Properties()] jPriority := priorities[b.Properties()] return cmp.Compare(iPriority, jPriority) }) } func FilterTransports(transport []Transport, props Properties) []Transport { var filtered []Transport for _, tp := range transport { if tp.Properties()&props == props { filtered = append(filtered, tp) } } return filtered }