blob: a3de1cf32411ace47a98f4dd15c6db0fc98cba83 [file] [log] [blame]
Scott Baker105df152020-04-13 15:55:14 -07001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package mapsort provides sorted access to maps.
6package mapsort
7
8import (
9 "sort"
10
11 "google.golang.org/protobuf/reflect/protoreflect"
12)
13
14// Range iterates over every map entry in sorted key order,
15// calling f for each key and value encountered.
16func Range(mapv protoreflect.Map, keyKind protoreflect.Kind, f func(protoreflect.MapKey, protoreflect.Value) bool) {
17 var keys []protoreflect.MapKey
18 mapv.Range(func(key protoreflect.MapKey, _ protoreflect.Value) bool {
19 keys = append(keys, key)
20 return true
21 })
22 sort.Slice(keys, func(i, j int) bool {
23 switch keyKind {
24 case protoreflect.BoolKind:
25 return !keys[i].Bool() && keys[j].Bool()
26 case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind,
27 protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
28 return keys[i].Int() < keys[j].Int()
29 case protoreflect.Uint32Kind, protoreflect.Fixed32Kind,
30 protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
31 return keys[i].Uint() < keys[j].Uint()
32 case protoreflect.StringKind:
33 return keys[i].String() < keys[j].String()
34 default:
35 panic("invalid kind: " + keyKind.String())
36 }
37 })
38 for _, key := range keys {
39 if !f(key, mapv.Get(key)) {
40 break
41 }
42 }
43}