output.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package internal
  2. import (
  3. "bytes"
  4. "errors"
  5. "go/format"
  6. "go/scanner"
  7. "io"
  8. "strings"
  9. "unicode"
  10. )
  11. // Identifier turns a C style type or field name into an exportable Go equivalent.
  12. func Identifier(str string) string {
  13. prev := rune(-1)
  14. return strings.Map(func(r rune) rune {
  15. // See https://golang.org/ref/spec#Identifiers
  16. switch {
  17. case unicode.IsLetter(r):
  18. if prev == -1 {
  19. r = unicode.ToUpper(r)
  20. }
  21. case r == '_':
  22. switch {
  23. // The previous rune was deleted, or we are at the
  24. // beginning of the string.
  25. case prev == -1:
  26. fallthrough
  27. // The previous rune is a lower case letter or a digit.
  28. case unicode.IsDigit(prev) || (unicode.IsLetter(prev) && unicode.IsLower(prev)):
  29. // delete the current rune, and force the
  30. // next character to be uppercased.
  31. r = -1
  32. }
  33. case unicode.IsDigit(r):
  34. default:
  35. // Delete the current rune. prev is unchanged.
  36. return -1
  37. }
  38. prev = r
  39. return r
  40. }, str)
  41. }
  42. // WriteFormatted outputs a formatted src into out.
  43. //
  44. // If formatting fails it returns an informative error message.
  45. func WriteFormatted(src []byte, out io.Writer) error {
  46. formatted, err := format.Source(src)
  47. if err == nil {
  48. _, err = out.Write(formatted)
  49. return err
  50. }
  51. var el scanner.ErrorList
  52. if !errors.As(err, &el) {
  53. return err
  54. }
  55. var nel scanner.ErrorList
  56. for _, err := range el {
  57. if !err.Pos.IsValid() {
  58. nel = append(nel, err)
  59. continue
  60. }
  61. buf := src[err.Pos.Offset:]
  62. nl := bytes.IndexRune(buf, '\n')
  63. if nl == -1 {
  64. nel = append(nel, err)
  65. continue
  66. }
  67. err.Msg += ": " + string(buf[:nl])
  68. nel = append(nel, err)
  69. }
  70. return nel
  71. }