Skip to content

Commit

Permalink
add formatter.DecamelAndRmTryPrefix to support TryCopy -> copy: annot.
Browse files Browse the repository at this point in the history
  • Loading branch information
lainio committed Nov 10, 2024
1 parent 9d7a288 commit e023bd0
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 4 deletions.
20 changes: 18 additions & 2 deletions formatter/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,24 @@ type Formatter struct {
DoFmt
}

// Decamel is preimplemented and default formatter to produce human
// readable error strings from function names.
// DecamelAndRmTryPrefix is pre-implemented formatter to produce human readable
// error strings from function names. It's similar to [Decamel] but also removes
// try-prefixes from function names:
//
// func TryCopyFile(..) -> "copy file: file not exists"
// ^-------^ -> generated from 'func TryCopyFile'
//
// It's convenient helper for those who wants to write compact functions by
// following convention to always add 'Try' prefix to those functions that can
// throw errors thru panics. Fox example, if you're using helpers like
// [github.com/lainio/err2/assert.That] and [github.com/lainio/err2/try.To] but
// you don't want to handle errors in your current function, it's still good
// practice to use convention to mark that function to throw errors. However, we
// suggest that you don't do that in your packages public API functions.
var DecamelAndRmTryPrefix = &Formatter{DoFmt: str.DecamelRmTryPrefix}

// Decamel is pre-implemented and default formatter to produce human readable
// error strings from function names.
//
// func CopyFile(..) -> "copy file: file not exists"
// ^-------^ -> generated from 'func CopyFile'
Expand Down
4 changes: 4 additions & 0 deletions internal/str/str.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func DecamelRegexp(str string) string {
return str
}

func DecamelRmTryPrefix(s string) string {
return strings.ReplaceAll(Decamel(s), "try ", "")
}

// Decamel return the given string as space delimeted. It's optimized to split
// and decamel function names returned from Go call stacks. For more information
// see its test cases.
Expand Down
82 changes: 82 additions & 0 deletions internal/str/str_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ func BenchmarkDecamel(b *testing.B) {
}
}

func BenchmarkDecamelRmTryPrefix(b *testing.B) {
for n := 0; n < b.N; n++ {
_ = str.DecamelRmTryPrefix(camelStr)
}
}

func TestCamel(t *testing.T) {
t.Parallel()
type args struct {
Expand Down Expand Up @@ -104,3 +110,79 @@ func TestDecamel(t *testing.T) {
})
}
}

func TestDecamelRmTryPrefix(t *testing.T) {
t.Parallel()
type args struct {
s string
}
tests := []struct {
name string
args args
want string
}{
{"simple", args{"CamelString"}, "camel string"},
{"simple try", args{"TryCamelString"}, "camel string"},
{"underscore", args{"CamelString_error"}, "camel string error"},
{"underscore and try", args{"TryCamelString_error"}, "camel string error"},
{
"our contant",
args{camelStr},
"benchmark recursion with old error if check and defer",
},
{"number", args{"CamelString2Testing"}, "camel string2 testing"},
{"acronym", args{"ARMCamelString"}, "armcamel string"},
{"acronym and try at END so it left", args{"ARMCamelStringTry"}, "armcamel string try"},
{"acronym and try", args{"TryARMCamelString"}, "armcamel string"},
{"acronym at end", args{"archIsARM"}, "arch is arm"},
{
"simple method",
args{"(*DIDAgent).AssertWallet"},
"didagent assert wallet",
},
{
"package name and simple method",
args{"ssi.(*DIDAgent).CreateWallet"},
"ssi: didagent create wallet",
},
{
"package name and simple method and Function start try",
args{"ssi.(*DIDAgent).TryCreateWallet"},
"ssi: didagent create wallet",
},
{
"simple method and anonym",
args{"(*DIDAgent).AssertWallet.Func1"},
"didagent assert wallet: func1",
},
{
"complex method and anonym",
args{"(**DIDAgent).AssertWallet.Func1"},
"didagent assert wallet: func1",
},
{
"complex method and anonym AND try",
args{"(**DIDAgent).TryAssertWallet.Func1"},
"didagent assert wallet: func1",
},
{
"unnatural method and anonym",
args{"(**DIDAgent)...AssertWallet...Func1"},
"didagent assert wallet: func1",
},
{
"unnatural method and anonym AND try",
args{"(**DIDAgent)...TryAssertWallet...TryFunc1"},
"didagent assert wallet: func1",
},
{"from spf13 cobra", args{"bot.glob..func5"}, "bot: glob: func5"},
}
for _, ttv := range tests {
tt := ttv
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := str.DecamelRmTryPrefix(tt.args.s)
require.Equal(t, got, tt.want)
})
}
}
4 changes: 2 additions & 2 deletions samples/main-play.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ func doMain() (err error) {
}
} else {
// 2nd argument is empty to assert
//TryCopyFile("main.go", "")
try.To(CopyFile("main.go", ""))
TryCopyFile("main.go", "")
//try.To(CopyFile("main.go", ""))
}

fmt.Println("=== you cannot see this ===")
Expand Down
5 changes: 5 additions & 0 deletions samples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/lainio/err2"
"github.com/lainio/err2/assert"
"github.com/lainio/err2/formatter"
)

var (
Expand All @@ -24,6 +25,10 @@ func init() {
// highlight that this is before flag.Parse to allow it to work properly.
err2.SetLogTracer(os.Stderr) // for import
err2.SetLogTracer(nil)

// select which one you want to play with
err2.SetFormatter(formatter.DecamelAndRmTryPrefix)
// err2.SetFormatter(formatter.Decamel)
}

func main() {
Expand Down

0 comments on commit e023bd0

Please sign in to comment.