in pkg/sorter/sorter.go [251:335]
func isLess(valI, valJ reflect.Value, isDescending bool) (bool, error) {
switch valI.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
// if valJ is not an int (can occur if the other value is nil)
// then valI is less. This will bubble invalid values to the end
vaJKind := valJ.Kind()
if vaJKind != reflect.Int && vaJKind != reflect.Int8 && vaJKind != reflect.Int16 && vaJKind != reflect.Int32 && vaJKind != reflect.Int64 {
return true, nil
}
if isDescending {
return valI.Int() > valJ.Int(), nil
} else {
return valI.Int() <= valJ.Int(), nil
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
// if valJ is not a uint (can occur if the other value is nil)
// then valI is less. This will bubble invalid values to the end
vaJKind := valJ.Kind()
if vaJKind != reflect.Uint && vaJKind != reflect.Uint8 && vaJKind != reflect.Uint16 && vaJKind != reflect.Uint32 && vaJKind != reflect.Uint64 {
return true, nil
}
if isDescending {
return valI.Uint() > valJ.Uint(), nil
} else {
return valI.Uint() <= valJ.Uint(), nil
}
case reflect.Float32, reflect.Float64:
// if valJ is not a float (can occur if the other value is nil)
// then valI is less. This will bubble invalid values to the end
vaJKind := valJ.Kind()
if vaJKind != reflect.Float32 && vaJKind != reflect.Float64 {
return true, nil
}
if isDescending {
return valI.Float() > valJ.Float(), nil
} else {
return valI.Float() <= valJ.Float(), nil
}
case reflect.String:
// if valJ is not a string (can occur if the other value is nil)
// then valI is less. This will bubble invalid values to the end
if valJ.Kind() != reflect.String {
return true, nil
}
if isDescending {
return strings.Compare(valI.String(), valJ.String()) > 0, nil
} else {
return strings.Compare(valI.String(), valJ.String()) <= 0, nil
}
case reflect.Pointer:
// Handle nil values by making non nil values always less than the nil values. That way the
// nil values can be bubbled up to the end of the list.
if valI.IsNil() {
return false, nil
} else if valJ.Kind() != reflect.Pointer || valJ.IsNil() {
return true, nil
}
return isLess(valI.Elem(), valJ.Elem(), isDescending)
case reflect.Bool:
// if valJ is not a bool (can occur if the other value is nil)
// then valI is less. This will bubble invalid values to the end
if valJ.Kind() != reflect.Bool {
return true, nil
}
if isDescending {
return !valI.Bool(), nil
} else {
return valI.Bool(), nil
}
case reflect.Invalid:
// handle invalid values (like nil values) by making valid values
// always less than the invalid values. That way the invalid values
// always bubble up to the end of the list
return false, nil
default:
// unsortable value
return false, fmt.Errorf("unsortable value")
}
}