utilities.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package door
  2. import (
  3. "bytes"
  4. "strconv"
  5. "strings"
  6. "golang.org/x/text/width"
  7. )
  8. // https://siongui.github.io/2016/03/23/go-utf8-string-width/
  9. // Return width of Unicode rune.
  10. func UnicodeWidth(r rune) int {
  11. p := width.LookupRune(r)
  12. if p.Kind() == width.EastAsianWide {
  13. return 2
  14. }
  15. return 1
  16. }
  17. // Delete an item from an array, returning item and true on success.
  18. func ArrayDelete[T any](stack *[]T, pos int) (T, bool) {
  19. // log.Printf("Array %d, %d\n", len(*stack), cap(*stack))
  20. var result T
  21. /*
  22. https://stackoverflow.com/questions/33834742/remove-and-adding-elements-to-array-in-go-lang
  23. https://github.com/golang/go/wiki/SliceTricks
  24. */
  25. if pos < 0 || pos > len(*stack) {
  26. return result, false
  27. }
  28. result = (*stack)[pos]
  29. copy((*stack)[pos:], (*stack)[pos+1:])
  30. // var temp T
  31. // (*stack)[len(*stack)-1] = temp
  32. *stack = (*stack)[:len(*stack)-1]
  33. return result, true
  34. }
  35. // Pop items from head of array, return true on success.
  36. func ArrayPop[T any](stack *[]T, count int) bool {
  37. /*
  38. https://stackoverflow.com/questions/33834742/remove-and-adding-elements-to-array-in-go-lang
  39. https://github.com/golang/go/wiki/SliceTricks
  40. */
  41. if count < 0 || count > len(*stack) {
  42. return false
  43. }
  44. copy((*stack)[0:], (*stack)[count:])
  45. // var temp T
  46. // (*stack)[len(*stack)-1] = temp
  47. *stack = (*stack)[:len(*stack)-count]
  48. return true
  49. }
  50. // Split string on separator, returning []int
  51. func SplitToInt(input string, sep string) []int {
  52. var result []int
  53. for _, number := range strings.Split(input, sep) {
  54. v, err := strconv.Atoi(number)
  55. if err == nil {
  56. result = append(result, v)
  57. }
  58. }
  59. return result
  60. }
  61. // In unicode, a single character isn't always 1 char wide.
  62. // This finds the actual length.
  63. // Calculate the length of the given line, dealing with unicode.
  64. func StringLen(s []byte) int {
  65. if Unicode {
  66. var len int
  67. var ubuff *bytes.Buffer = bytes.NewBuffer(s)
  68. for {
  69. r, _, err := ubuff.ReadRune()
  70. if err != nil {
  71. break
  72. }
  73. len += UnicodeWidth(r)
  74. }
  75. return len
  76. } else {
  77. return len(s)
  78. }
  79. }