...

Source file src/github.com/grpc-ecosystem/grpc-gateway/internal/casing/camel.go

Documentation: github.com/grpc-ecosystem/grpc-gateway/internal/casing

     1  package casing
     2  
     3  // Camel returns the CamelCased name.
     4  //
     5  // This was moved from the now deprecated github.com/golang/protobuf/protoc-gen-go/generator package
     6  //
     7  // If there is an interior underscore followed by a lower case letter,
     8  // drop the underscore and convert the letter to upper case.
     9  // There is a remote possibility of this rewrite causing a name collision,
    10  // but it's so remote we're prepared to pretend it's nonexistent - since the
    11  // C++ generator lowercases names, it's extremely unlikely to have two fields
    12  // with different capitalizations.
    13  // In short, _my_field_name_2 becomes XMyFieldName_2.
    14  func Camel(s string) string {
    15  	if s == "" {
    16  		return ""
    17  	}
    18  	t := make([]byte, 0, 32)
    19  	i := 0
    20  	if s[0] == '_' {
    21  		// Need a capital letter; drop the '_'.
    22  		t = append(t, 'X')
    23  		i++
    24  	}
    25  	// Invariant: if the next letter is lower case, it must be converted
    26  	// to upper case.
    27  	// That is, we process a word at a time, where words are marked by _ or
    28  	// upper case letter. Digits are treated as words.
    29  	for ; i < len(s); i++ {
    30  		c := s[i]
    31  		if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) {
    32  			continue // Skip the underscore in s.
    33  		}
    34  		if isASCIIDigit(c) {
    35  			t = append(t, c)
    36  			continue
    37  		}
    38  		// Assume we have a letter now - if not, it's a bogus identifier.
    39  		// The next word is a sequence of characters that must start upper case.
    40  		if isASCIILower(c) {
    41  			c ^= ' ' // Make it a capital letter.
    42  		}
    43  		t = append(t, c) // Guaranteed not lower case.
    44  		// Accept lower case sequence that follows.
    45  		for i+1 < len(s) && isASCIILower(s[i+1]) {
    46  			i++
    47  			t = append(t, s[i])
    48  		}
    49  	}
    50  	return string(t)
    51  }
    52  
    53  // And now lots of helper functions.
    54  
    55  // Is c an ASCII lower-case letter?
    56  func isASCIILower(c byte) bool {
    57  	return 'a' <= c && c <= 'z'
    58  }
    59  
    60  // Is c an ASCII digit?
    61  func isASCIIDigit(c byte) bool {
    62  	return '0' <= c && c <= '9'
    63  }
    64  

View as plain text