Skip to content

Commit

Permalink
abstracted case format to individual package
Browse files Browse the repository at this point in the history
  • Loading branch information
adranwit committed Jul 27, 2021
1 parent b7093d3 commit 8c7e564
Show file tree
Hide file tree
Showing 7 changed files with 587 additions and 83 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -422,11 +422,13 @@ This API has been deprecated, please consider using [Abstract Storage](https://g
<a name="tet"></a>
### Text utilities

**ToCaseFormat**

```go
formatted := toolbox.ToCaseFormat(text, toolbox.CaseLowerUnderscore, toolbox.CaseLowerCamel)
**Text Case Format**

You can format with [format.Case](format/case.go).Format(text, destCase)

```go
formatted := format.CaseLowerUnderscore.Format(text, format.CaseLowerCamel)
```


Expand Down
138 changes: 138 additions & 0 deletions format/case.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package format

import (
"fmt"
"strings"
"unicode"
)

type Case int

const (
//CaseUpper represents case format
CaseUpper = Case(iota)
CaseLower
CaseUpperCamel
CaseLowerCamel
CaseUpperUnderscore
CaseLowerUnderscore
)

//NewCase create a new case for supplied name or error, supported in case insensitive form "upperCase", "upper", "u"
func NewCase(name string) (Case, error) {
switch strings.ToLower(name) {
case "upper", "u":
return CaseUpper, nil
case "lower", "l":
return CaseLower, nil
case "lowercamel", "lc":
return CaseLowerCamel, nil
case "uppercamel", "uc":
return CaseUpperCamel, nil
case "lowerunderscore", "lu":
return CaseLowerUnderscore, nil
case "upperunderscore", "uu":
return CaseUpperUnderscore, nil
}
return -1, fmt.Errorf("unsupported case format: %s", name)
}

//String return case format name
func (from Case) String() string {
switch from {
case CaseUpper:
return "Upper"
case CaseLower:
return "Lower"
case CaseUpperCamel:
return "UpperCamel"
case CaseLowerCamel:
return "UpperCamel"
case CaseUpperUnderscore:
return "UpperUnderscore"
case CaseLowerUnderscore:
return "LowerUnderscore"
}
return "UnsupportedCase"
}


//Format converts supplied text from Case to
func (from Case) Format(text string, to Case) string {
toUpper := false
toLower := false
toCamel := false
toUnserscore := false
fromCamel := false
fromUnserscore := false

switch to {
case CaseUpper, CaseUpperUnderscore:
toUpper = true
case CaseLower, CaseLowerUnderscore:
toLower = true
case CaseUpperCamel, CaseLowerCamel:
toCamel = true
}
switch to {
case CaseUpperUnderscore, CaseLowerUnderscore:
toUnserscore = true
}
switch from {
case CaseUpperCamel, CaseLowerCamel:
fromCamel = true
case CaseUpperUnderscore, CaseLowerUnderscore:
fromUnserscore = true
}
underscore := rune('_')
var result = make([]rune, 0)
makeLower := false
makeUpper := false
hasUnderscore := false
for i, r := range text {
first := i == 0
if toUpper {
makeUpper = true
} else if toLower {
makeLower = true
}
if first {
if to == CaseLowerCamel {
r = unicode.ToLower(r)
} else if to == CaseUpperCamel {
r = unicode.ToUpper(r)
}
} else {
if fromUnserscore {
if toCamel {
if r == underscore {
hasUnderscore = true
continue
}
if hasUnderscore {
makeUpper = true
hasUnderscore = false
} else {
makeLower = true
}
}
}
if unicode.IsUpper(r) && fromCamel {
if toUnserscore {
result = append(result, underscore)
}
}
}

if makeLower {
r = unicode.ToLower(r)
} else if makeUpper {
r = unicode.ToUpper(r)
}
result = append(result, r)
makeUpper = false
makeLower = false
}

return string(result)
}
67 changes: 67 additions & 0 deletions format/case_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package format

import (
"github.com/stretchr/testify/assert"
"testing"
)

func TestCase_To(t *testing.T) {
var useCases = []struct {
description string
caseFrom Case
caseTo Case
input string
expect string
}{
{
description: "camel to uppercase",
input: "thisIsMyTest",
caseFrom: CaseLowerCamel,
caseTo: CaseUpper,
expect: "THISISMYTEST",
},
{
description: "camel to lower underscore",
input: "thisIsMyTest",
caseFrom: CaseLowerCamel,
caseTo: CaseLowerUnderscore,
expect: "this_is_my_test",
},
{
description: "camel to upper underscore",
input: "thisIsMyTest",
caseFrom: CaseLowerCamel,
caseTo: CaseUpperUnderscore,
expect: "THIS_IS_MY_TEST",
},
{
description: "lower underscore to upper camel",
input: "this_is_my_test",
caseFrom: CaseLowerUnderscore,
caseTo: CaseUpperCamel,
expect: "ThisIsMyTest",
},
{
description: "upper underscore to lower camel",
input: "THIS_IS_MY_TEST",
caseFrom: CaseUpperUnderscore,
caseTo: CaseLowerCamel,
expect: "thisIsMyTest",
},

{
description: "upper camel to lower camel",
input: "ThisIsMyTest",
caseFrom: CaseUpperCamel,
caseTo: CaseLowerCamel,
expect: "thisIsMyTest",
},
}

for _, useCase := range useCases {
actual := useCase.caseFrom.Format(useCase.input, useCase.caseTo)
assert.Equal(t, useCase.expect, actual, useCase.description)
}

}

4 changes: 0 additions & 4 deletions service_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,6 @@ func WriteServiceRoutingResponse(response http.ResponseWriter, request *http.Req
return fmt.Errorf("failed to encode response %v, due to %v", response, err)
}
return nil
if err != nil {
return fmt.Errorf("failed to write response response %v, due to %v", result, err)
}
return nil
}

//WriteResponse writes response to response writer, it used encoder factory to encode passed in response to the writer, it sets back request contenttype to response.
Expand Down
79 changes: 3 additions & 76 deletions text.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package toolbox

import (
"bufio"
"github.com/viant/toolbox/format"
"io"
"unicode"
)
Expand Down Expand Up @@ -104,81 +105,7 @@ const (
)

//ToCaseFormat format text, from, to are const: CaseLower, CaseUpperCamel, CaseLowerCamel, CaseUpperUnderscore, CaseLowerUnderscore,
// Deprecated: please use format.Case instead
func ToCaseFormat(text string, from, to int) string {
toUpper := false
toLower := false
toCamel := false
toUnserscore := false
fromCamel := false
fromUnserscore := false

switch to {
case CaseUpper, CaseUpperUnderscore:
toUpper = true
case CaseLower, CaseLowerUnderscore:
toLower = true
case CaseUpperCamel, CaseLowerCamel:
toCamel = true
}
switch to {
case CaseUpperUnderscore, CaseLowerUnderscore:
toUnserscore = true
}
switch from {
case CaseUpperCamel, CaseLowerCamel:
fromCamel = true
case CaseUpperUnderscore, CaseLowerUnderscore:
fromUnserscore = true
}
underscore := rune('_')
var result = make([]rune, 0)
makeLower := false
makeUpper := false
hasUnderscore := false
for i, r := range text {
first := i == 0
if toUpper {
makeUpper = true
} else if toLower {
makeLower = true
}
if first {
if to == CaseLowerCamel {
r = unicode.ToLower(r)
} else if to == CaseUpperCamel {
r = unicode.ToUpper(r)
}
} else {
if fromUnserscore {
if toCamel {
if r == underscore {
hasUnderscore = true
continue
}
if hasUnderscore {
makeUpper = true
hasUnderscore = false
} else {
makeLower = true
}
}
}
if unicode.IsUpper(r) && fromCamel {
if toUnserscore {
result = append(result, underscore)
}
}
}

if makeLower {
r = unicode.ToLower(r)
} else if makeUpper {
r = unicode.ToUpper(r)
}
result = append(result, r)
makeUpper = false
makeLower = false
}

return string(result)
return format.Case(from).Format(text, format.Case(to))
}
Loading

0 comments on commit 8c7e564

Please sign in to comment.