utilities.go 1.9 KB

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