github.com/viant/toolbox@v0.34.5/format/case.go (about) 1 package format 2 3 import ( 4 "fmt" 5 "strings" 6 "unicode" 7 ) 8 9 type Case int 10 11 const ( 12 //CaseUpper represents case format 13 CaseUpper = Case(iota) 14 CaseLower 15 CaseUpperCamel 16 CaseLowerCamel 17 CaseUpperUnderscore 18 CaseLowerUnderscore 19 ) 20 21 //NewCase create a new case for supplied name or error, supported in case insensitive form "upperCase", "upper", "u" 22 func NewCase(name string) (Case, error) { 23 switch strings.ToLower(name) { 24 case "upper", "u": 25 return CaseUpper, nil 26 case "lower", "l": 27 return CaseLower, nil 28 case "lowercamel", "lc": 29 return CaseLowerCamel, nil 30 case "uppercamel", "uc": 31 return CaseUpperCamel, nil 32 case "lowerunderscore", "lu": 33 return CaseLowerUnderscore, nil 34 case "upperunderscore", "uu": 35 return CaseUpperUnderscore, nil 36 } 37 return -1, fmt.Errorf("unsupported case format: %s", name) 38 } 39 40 //String return case format name 41 func (from Case) String() string { 42 switch from { 43 case CaseUpper: 44 return "Upper" 45 case CaseLower: 46 return "Lower" 47 case CaseUpperCamel: 48 return "UpperCamel" 49 case CaseLowerCamel: 50 return "UpperCamel" 51 case CaseUpperUnderscore: 52 return "UpperUnderscore" 53 case CaseLowerUnderscore: 54 return "LowerUnderscore" 55 } 56 return "UnsupportedCase" 57 } 58 59 60 //Format converts supplied text from Case to 61 func (from Case) Format(text string, to Case) string { 62 toUpper := false 63 toLower := false 64 toCamel := false 65 toUnserscore := false 66 fromCamel := false 67 fromUnserscore := false 68 69 switch to { 70 case CaseUpper, CaseUpperUnderscore: 71 toUpper = true 72 case CaseLower, CaseLowerUnderscore: 73 toLower = true 74 case CaseUpperCamel, CaseLowerCamel: 75 toCamel = true 76 } 77 switch to { 78 case CaseUpperUnderscore, CaseLowerUnderscore: 79 toUnserscore = true 80 } 81 switch from { 82 case CaseUpperCamel, CaseLowerCamel: 83 fromCamel = true 84 case CaseUpperUnderscore, CaseLowerUnderscore: 85 fromUnserscore = true 86 } 87 underscore := rune('_') 88 var result = make([]rune, 0) 89 makeLower := false 90 makeUpper := false 91 hasUnderscore := false 92 for i, r := range text { 93 first := i == 0 94 if toUpper { 95 makeUpper = true 96 } else if toLower { 97 makeLower = true 98 } 99 if first { 100 if to == CaseLowerCamel { 101 r = unicode.ToLower(r) 102 } else if to == CaseUpperCamel { 103 r = unicode.ToUpper(r) 104 } 105 } else { 106 if fromUnserscore { 107 if toCamel { 108 if r == underscore { 109 hasUnderscore = true 110 continue 111 } 112 if hasUnderscore { 113 makeUpper = true 114 hasUnderscore = false 115 } else { 116 makeLower = true 117 } 118 } 119 } 120 if unicode.IsUpper(r) && fromCamel { 121 if toUnserscore { 122 result = append(result, underscore) 123 } 124 } 125 } 126 127 if makeLower { 128 r = unicode.ToLower(r) 129 } else if makeUpper { 130 r = unicode.ToUpper(r) 131 } 132 result = append(result, r) 133 makeUpper = false 134 makeLower = false 135 } 136 137 return string(result) 138 }