// Copyright (c) 2017, A. Stoewer // All rights reserved. package strcase import ( "strings" ) // SnakeCase converts a string into snake case. func SnakeCase(s string) string { return delimiterCase(s, '_', false) } // UpperSnakeCase converts a string into snake case with capital letters. func UpperSnakeCase(s string) string { return delimiterCase(s, '_', true) } // delimiterCase converts a string into snake_case or kebab-case depending on the delimiter passed // as second argument. When upperCase is true the result will be UPPER_SNAKE_CASE or UPPER-KEBAB-CASE. func delimiterCase(s string, delimiter rune, upperCase bool) string { s = strings.TrimSpace(s) buffer := make([]rune, 0, len(s)+3) adjustCase := toLower if upperCase { adjustCase = toUpper } var prev rune var curr rune for _, next := range s { if isDelimiter(curr) { if !isDelimiter(prev) { buffer = append(buffer, delimiter) } } else if isUpper(curr) { if isLower(prev) || (isUpper(prev) && isLower(next)) { buffer = append(buffer, delimiter) } buffer = append(buffer, adjustCase(curr)) } else if curr != 0 { buffer = append(buffer, adjustCase(curr)) } prev = curr curr = next } if len(s) > 0 { if isUpper(curr) && isLower(prev) && prev != 0 { buffer = append(buffer, delimiter) } buffer = append(buffer, adjustCase(curr)) } return string(buffer) }