| package entutils |
|
|
| import ( |
| "errors" |
| "fmt" |
|
|
| "github.com/samber/lo" |
|
|
| "github.com/openmeterio/openmeter/pkg/models" |
| ) |
|
|
| type InIDOrderAccessor interface { |
| IDMixinGetter |
| NamespaceMixinGetter |
| } |
|
|
| var ( |
| ErrNamespaceRequired = errors.New("namespace is required") |
| ErrIDRequired = errors.New("id is required") |
| ErrDuplicateID = errors.New("duplicate id") |
| ErrNotFound = errors.New("not found") |
| ) |
|
|
| func InIDOrder[T InIDOrderAccessor](namespace string, targetOrderIDs []string, results []T) ([]T, error) { |
| |
| if namespace == "" { |
| return nil, ErrNamespaceRequired |
| } |
|
|
| for _, id := range targetOrderIDs { |
| if id == "" { |
| return nil, ErrIDRequired |
| } |
| } |
|
|
| for _, result := range results { |
| namespacedID := models.NamespacedID{ |
| Namespace: result.GetNamespace(), |
| ID: result.GetID(), |
| } |
| if err := namespacedID.Validate(); err != nil { |
| return nil, err |
| } |
| } |
|
|
| |
| if len(targetOrderIDs) == 0 && len(results) == 0 { |
| return results, nil |
| } |
|
|
| entitiesByID := lo.GroupBy(results, func(result T) models.NamespacedID { |
| return models.NamespacedID{ |
| Namespace: result.GetNamespace(), |
| ID: result.GetID(), |
| } |
| }) |
|
|
| |
| for id, entities := range entitiesByID { |
| if len(entities) > 1 { |
| return nil, fmt.Errorf("%w [id=%s, count=%d]", ErrDuplicateID, id, len(entities)) |
| } |
| } |
|
|
| |
| |
| var errs []error |
| out := make([]T, 0, len(targetOrderIDs)) |
| for _, id := range targetOrderIDs { |
| entities, ok := entitiesByID[models.NamespacedID{Namespace: namespace, ID: id}] |
| if !ok { |
| errs = append(errs, fmt.Errorf("%w [id=%s]", ErrNotFound, id)) |
| continue |
| } |
|
|
| out = append(out, entities...) |
| } |
|
|
| if len(errs) > 0 { |
| return nil, models.NewGenericNotFoundError(errors.Join(errs...)) |
| } |
|
|
| return out, nil |
| } |
|
|