gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

output.go (1634B)


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