github.com/aristanetworks/gomap@v0.0.0-20240103001659-f6b0e31fb1a7/funcs.go (about) 1 // Modifications copyright (c) Arista Networks, Inc. 2022 2 // Underlying 3 // Copyright 2014 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package gomap 8 9 import ( 10 "fmt" 11 "strings" 12 13 "golang.org/x/exp/slices" 14 ) 15 16 // String converts m to a string representation using K's and E's 17 // String functions. 18 func String[K fmt.Stringer, E fmt.Stringer](m *Map[K, E]) string { 19 return StringFunc(m, 20 func(key K) string { return key.String() }, 21 func(elem E) string { return elem.String() }, 22 ) 23 } 24 25 type strKE struct { 26 k string 27 e string 28 } 29 30 // StringFunc converts m to a string representation with the help of 31 // strK and strE functions to stringify m's keys and elems. 32 func StringFunc[K any, E any](m *Map[K, E], 33 strK func(key K) string, 34 strE func(elem E) string) string { 35 if m == nil || m.Len() == 0 { 36 return "gomap.Map[]" 37 } 38 strs := make([]strKE, m.Len()) 39 s := 0 40 i := 0 41 for it := m.Iter(); it.Next(); { 42 ke := &strs[i] 43 ke.k = strK(it.Key()) 44 ke.e = strE(it.Elem()) 45 s += len(ke.k) + len(ke.e) 46 i++ 47 } 48 slices.SortFunc(strs, func(a, b strKE) int { 49 if a.k < b.k { 50 return -1 51 } 52 if a.k > b.k { 53 return +1 54 } 55 return 0 56 }) 57 58 var b strings.Builder 59 b.Grow(len("gomap.Map[]") + // space for header and footer 60 len(strs)*2 - 1 + // space for delimiters 61 s) // space for keys and elems 62 b.WriteString("gomap.Map[") 63 for i, ke := range strs { 64 if i != 0 { 65 b.WriteByte(' ') 66 } 67 b.WriteString(ke.k) 68 b.WriteByte(':') 69 b.WriteString(ke.e) 70 } 71 b.WriteByte(']') 72 return b.String() 73 } 74 75 // Equal returns true if the same set of keys and elems are in m1 and 76 // m2. Elements are compared using ==. 77 func Equal[K any, E comparable](m1, m2 *Map[K, E]) bool { 78 if m1.Len() != m2.Len() { 79 return false 80 } 81 for it := m1.Iter(); it.Next(); { 82 e2, ok := m2.Get(it.Key()) 83 if !ok || it.Elem() != e2 { 84 return false 85 } 86 } 87 return true 88 } 89 90 // Equal returns true if the same set of keys and elems are in m1 and 91 // m2. Elements are compared using eq. 92 func EqualFunc[K, E any](m1, m2 *Map[K, E], eq func(E, E) bool) bool { 93 if m1.Len() != m2.Len() { 94 return false 95 } 96 for it := m1.Iter(); it.Next(); { 97 e2, ok := m2.Get(it.Key()) 98 if !ok || !eq(it.Elem(), e2) { 99 return false 100 } 101 } 102 return true 103 }