github.com/alimy/mir/v4@v4.1.0/internal/naming/snake_ns.go (about) 1 // Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved. 2 // Use of this source code is governed by Apache License 2.0 that 3 // can be found in the LICENSE file. 4 5 package naming 6 7 import ( 8 "bytes" 9 "strings" 10 ) 11 12 // snakeNamingStrategy snake naming strategy implement 13 // This implement is inspiration from https://github.com/jingzhu/gorm's naming logic. 14 type snakeNamingStrategy struct { 15 initialismsReplacer *strings.Replacer 16 } 17 18 func (s *snakeNamingStrategy) Naming(name string) string { 19 if name == "" { 20 return "" 21 } 22 23 var lastCase, currCase, nextCase, nextNumber bool 24 value := s.initialismsReplacer.Replace(name) 25 buf := bytes.NewBufferString("") 26 lower, upper := false, true 27 for i, v := range value[:len(value)-1] { 28 nextCase = value[i+1] >= 'A' && value[i+1] <= 'Z' 29 nextNumber = value[i+1] >= '0' && value[i+1] <= '9' 30 if i > 0 { 31 if currCase == upper { 32 if lastCase == upper && (nextCase == upper || nextNumber == upper) { 33 buf.WriteRune(v) 34 } else { 35 if value[i-1] != '_' && value[i+1] != '_' { 36 buf.WriteRune('_') 37 } 38 buf.WriteRune(v) 39 } 40 } else { 41 buf.WriteRune(v) 42 if i == len(value)-2 && (nextCase == upper && nextNumber == lower) { 43 buf.WriteRune('_') 44 } 45 } 46 } else { 47 currCase = upper 48 buf.WriteRune(v) 49 } 50 lastCase, currCase = currCase, nextCase 51 } 52 53 buf.WriteByte(value[len(value)-1]) 54 res := strings.ToLower(buf.String()) 55 return res 56 } 57 58 // NewSnakeNamingStrategy return snake naming strategy instance 59 func NewSnakeNamingStrategy() NamingStrategy { 60 // Copied from golint 61 initialisms := []string{ 62 "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", 63 "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", 64 "SMTP", "SSH", "TLS", "TTL", "UID", "UI", "UUID", "URI", "URL", "UTF8", 65 "VM", "XML", "XSRF", "XSS"} 66 67 var oldnews []string 68 for _, initialism := range initialisms { 69 oldnews = append(oldnews, initialism, strings.Title(strings.ToLower(initialism))) 70 } 71 replacer := strings.NewReplacer(oldnews...) 72 73 return &snakeNamingStrategy{ 74 initialismsReplacer: replacer, 75 } 76 }