Skip to content

Commit 5f32565

Browse files
authored
Merge pull request #13 from rprtr258/dev
simplify code
2 parents 509201d + 6b86181 commit 5f32565

9 files changed

Lines changed: 436 additions & 368 deletions

README.md

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ i.e. you have following template: `"Hello {0}, we are greeting you here: {1}!"`
3535
if you call Format with args "manager" and "salesApp" :
3636

3737
```go
38-
formattedStr := Format("Hello {0}, we are greeting you here: {1}!", "manager", "salesApp")
38+
formattedStr := stringFormatter.Format("Hello {0}, we are greeting you here: {1}!", "manager", "salesApp")
3939
```
4040

4141
you get string `"Hello manager, we are greeting you here: salesApp!"`
@@ -44,15 +44,17 @@ you get string `"Hello manager, we are greeting you here: salesApp!"`
4444

4545
i.e. you have following template: `"Hello {user} what are you doing here {app} ?"`
4646

47-
if you call `FormatComplex` with args `"vpupkin"` and `"mn_console"` `FormatComplex("Hello {user} what are you doing here {app} ?", map[string]interface{}{"user":"vpupkin", "app":"mn_console"})`
47+
if you call `FormatComplex` with args `"vpupkin"` and `"mn_console"` `FormatComplex("Hello {user} what are you doing here {app} ?", map[string]any{"user":"vpupkin", "app":"mn_console"})`
4848

4949
you get string `"Hello vpupkin what are you doing here mn_console ?"`
5050

5151
another example is:
5252

5353
```go
54-
strFormatResult = FormatComplex("Current app settings are: ipAddr: {ipaddr}, port: {port}, use ssl: {ssl}.",
55-
map[string]interface{}{"ipaddr":"127.0.0.1", "port":5432, "ssl":false})
54+
strFormatResult = stringFormatter.FormatComplex(
55+
"Current app settings are: ipAddr: {ipaddr}, port: {port}, use ssl: {ssl}.",
56+
map[string]any{"ipaddr":"127.0.0.1", "port":5432, "ssl":false},
57+
)
5658
```
5759
a result will be: `"Current app settings are: ipAddr: 127.0.0.1, port: 5432, use ssl: false."``
5860

@@ -66,23 +68,24 @@ benchmark could be running using following commands from command line:
6668

6769
#### 2.1 Map to string utility
6870

69-
Map to string function allow to convert map to string using one of predefined line format:
70-
* `key => value`
71-
* `key : value`
72-
* `value`
71+
`MapToString` function allows to convert map with primitive key to string using format, including key and value, e.g.:
72+
* `{key} => {value}`
73+
* `{key} : {value}`
74+
* `{value}`
7375

74-
For example see code from test (`text_utils_test.go`):
76+
For example:
7577
```go
76-
options := map[string]interface{}{
77-
"connectTimeout": 1000,
78-
"useSsl": true,
79-
"login": "sa",
80-
"password": "sa",
81-
}
82-
83-
str := MapToString(&options, KeyValueWithSemicolonSepFormat, ", ")
84-
assert.True(t, len(str) > 0)
85-
assert.Equal(t, "connectTimeout : 1000, useSsl : true, login : sa, password : sa", str)
78+
options := map[string]any{
79+
"connectTimeout": 1000,
80+
"useSsl": true,
81+
"login": "sa",
82+
"password": "sa",
83+
}
84+
85+
str := stringFormatter.MapToString(&options, "{key} : {value}", ", ")
86+
// NOTE: order of key-value pairs is not guranteed though
87+
// str will be something like:
88+
"connectTimeout : 1000, useSsl : true, login : sa, password : sa"
8689
```
8790

8891
#### 2.2 Benchmarks of the MapToStr function

formatter.go

Lines changed: 107 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -21,80 +21,81 @@ import (
2121
* - args - values that are using for formatting with template
2222
* Returns formatted string
2323
*/
24-
func Format(template string, args ...interface{}) string {
24+
func Format(template string, args ...any) string {
2525
if args == nil {
2626
return template
2727
}
2828

29-
templateLen := len(template)
30-
var formattedStr = &strings.Builder{}
31-
formattedStr.Grow(templateLen + 22*len(args))
32-
j := -1
3329
start := strings.Index(template, "{")
3430
if start < 0 {
3531
return template
3632
}
3733

34+
templateLen := len(template)
35+
formattedStr := &strings.Builder{}
36+
formattedStr.Grow(templateLen + 22*len(args))
37+
j := -1 //nolint:ineffassign
38+
3839
formattedStr.WriteString(template[:start])
3940
for i := start; i < templateLen; i++ {
40-
4141
if template[i] == '{' {
4242
// possibly it is a template placeholder
4343
if i == templateLen-1 {
4444
break
4545
}
46+
4647
if template[i+1] == '{' { // todo: umv: this not considering {{0}}
4748
formattedStr.WriteByte('{')
4849
continue
49-
} else {
50-
// find end of placeholder
51-
j = i + 2
52-
for {
53-
if j >= templateLen {
54-
break
55-
}
56-
if template[j] == '{' {
57-
// multiple nested curly brackets ...
58-
formattedStr.WriteString(template[i:j])
59-
i = j
60-
}
61-
if template[j] == '}' {
62-
break
63-
}
64-
j++
50+
}
51+
// find end of placeholder
52+
j = i + 2
53+
for {
54+
if j >= templateLen {
55+
break
6556
}
66-
// double curly brackets processed here, convert {{N}} -> {N}
67-
// so we catch here {{N}
68-
if j+1 < templateLen && template[j+1] == '}' && template[i-1] == '{' {
6957

70-
formattedStr.WriteString(template[i+1 : j+1])
71-
i = j + 1
72-
} else {
73-
argNumberStr := template[i+1 : j]
74-
var argNumber int
75-
var err error
76-
if len(argNumberStr) == 1 {
77-
// this makes work a little faster then AtoI
78-
argNumber = int(argNumberStr[0] - '0')
79-
} else {
80-
argNumber, err = strconv.Atoi(argNumberStr)
81-
}
82-
//argNumber, err := strconv.Atoi(argNumberStr)
83-
if err == nil && len(args) > argNumber {
84-
// get number from placeholder
85-
strVal := getItemAsStr(&args[argNumber])
86-
formattedStr.WriteString(strVal)
87-
} else {
88-
formattedStr.WriteByte('{')
89-
formattedStr.WriteString(argNumberStr)
90-
formattedStr.WriteByte('}')
91-
}
58+
if template[j] == '{' {
59+
// multiple nested curly brackets ...
60+
formattedStr.WriteString(template[i:j])
9261
i = j
9362
}
94-
}
9563

64+
if template[j] == '}' {
65+
break
66+
}
67+
68+
j++
69+
}
70+
// double curly brackets processed here, convert {{N}} -> {N}
71+
// so we catch here {{N}
72+
if j+1 < templateLen && template[j+1] == '}' && template[i-1] == '{' {
73+
formattedStr.WriteString(template[i+1 : j+1])
74+
i = j + 1
75+
} else {
76+
argNumberStr := template[i+1 : j]
77+
var argNumber int
78+
var err error
79+
if len(argNumberStr) == 1 {
80+
// this makes work a little faster than AtoI
81+
argNumber = int(argNumberStr[0] - '0')
82+
} else {
83+
argNumber, err = strconv.Atoi(argNumberStr)
84+
}
85+
//argNumber, err := strconv.Atoi(argNumberStr)
86+
if err == nil && len(args) > argNumber {
87+
// get number from placeholder
88+
strVal := getItemAsStr(&args[argNumber])
89+
formattedStr.WriteString(strVal)
90+
} else {
91+
formattedStr.WriteByte('{')
92+
formattedStr.WriteString(argNumberStr)
93+
formattedStr.WriteByte('}')
94+
}
95+
i = j
96+
}
9697
} else {
97-
j = i
98+
j = i //nolint:ineffassign
9899
formattedStr.WriteByte(template[i])
99100
}
100101
}
@@ -109,72 +110,70 @@ func Format(template string, args ...interface{}) string {
109110
* - args - values (dictionary: string key - any value) that are using for formatting with template
110111
* Returns formatted string
111112
*/
112-
func FormatComplex(template string, args map[string]interface{}) string {
113+
func FormatComplex(template string, args map[string]any) string {
113114
if args == nil {
114115
return template
115116
}
116117

117-
templateLen := len(template)
118-
var formattedStr = &strings.Builder{}
119-
formattedStr.Grow(templateLen + 22*len(args))
120-
j := -1
121118
start := strings.Index(template, "{")
122119
if start < 0 {
123120
return template
124121
}
125122

123+
templateLen := len(template)
124+
formattedStr := &strings.Builder{}
125+
formattedStr.Grow(templateLen + 22*len(args))
126+
j := -1 //nolint:ineffassign
126127
formattedStr.WriteString(template[:start])
127128
for i := start; i < templateLen; i++ {
128-
129129
if template[i] == '{' {
130130
// possibly it is a template placeholder
131131
if i == templateLen-1 {
132132
break
133133
}
134+
134135
if template[i+1] == '{' { // todo: umv: this not considering {{0}}
135136
formattedStr.WriteByte('{')
136137
continue
137-
} else {
138-
// find end of placeholder
139-
j = i + 2
140-
for {
141-
if j >= templateLen {
142-
break
143-
}
144-
if template[j] == '{' {
145-
// multiple nested curly brackets ...
146-
formattedStr.WriteString(template[i:j])
147-
i = j
148-
}
149-
if template[j] == '}' {
150-
break
151-
}
152-
j++
153-
}
154-
// double curly brackets processed here, convert {{N}} -> {N}
155-
// so we catch here {{N}
156-
if j+1 < templateLen && template[j+1] == '}' {
138+
}
157139

158-
formattedStr.WriteString(template[i+1 : j+1])
159-
i = j + 1
160-
} else {
161-
argNumberStr := template[i+1 : j]
162-
arg, ok := args[argNumberStr]
163-
if ok {
164-
// get number from placeholder
165-
strVal := getItemAsStr(&arg)
166-
formattedStr.WriteString(strVal)
167-
} else {
168-
formattedStr.WriteByte('{')
169-
formattedStr.WriteString(argNumberStr)
170-
formattedStr.WriteByte('}')
171-
}
140+
// find end of placeholder
141+
j = i + 2
142+
for {
143+
if j >= templateLen {
144+
break
145+
}
146+
if template[j] == '{' {
147+
// multiple nested curly brackets ...
148+
formattedStr.WriteString(template[i:j])
172149
i = j
173150
}
151+
if template[j] == '}' {
152+
break
153+
}
154+
j++
155+
}
156+
// double curly brackets processed here, convert {{N}} -> {N}
157+
// so we catch here {{N}
158+
if j+1 < templateLen && template[j+1] == '}' {
159+
formattedStr.WriteString(template[i+1 : j+1])
160+
i = j + 1
161+
} else {
162+
argNumberStr := template[i+1 : j]
163+
arg, ok := args[argNumberStr]
164+
if ok {
165+
// get number from placeholder
166+
strVal := getItemAsStr(&arg)
167+
formattedStr.WriteString(strVal)
168+
} else {
169+
formattedStr.WriteByte('{')
170+
formattedStr.WriteString(argNumberStr)
171+
formattedStr.WriteByte('}')
172+
}
173+
i = j
174174
}
175-
176175
} else {
177-
j = i
176+
j = i //nolint:ineffassign
178177
formattedStr.WriteByte(template[i])
179178
}
180179
}
@@ -183,55 +182,37 @@ func FormatComplex(template string, args map[string]interface{}) string {
183182
}
184183

185184
// todo: umv: impl format passing as param
186-
func getItemAsStr(item *interface{}) string {
187-
var strVal string
188-
//var err error
189-
switch (*item).(type) {
185+
func getItemAsStr(item *any) string {
186+
switch v := (*item).(type) {
190187
case string:
191-
strVal = (*item).(string)
192-
break
188+
return v
193189
case int8:
194-
strVal = strconv.FormatInt(int64((*item).(int8)), 10)
195-
break
190+
return strconv.FormatInt(int64(v), 10)
196191
case int16:
197-
strVal = strconv.FormatInt(int64((*item).(int16)), 10)
198-
break
192+
return strconv.FormatInt(int64(v), 10)
199193
case int32:
200-
strVal = strconv.FormatInt(int64((*item).(int32)), 10)
201-
break
194+
return strconv.FormatInt(int64(v), 10)
202195
case int64:
203-
strVal = strconv.FormatInt((*item).(int64), 10)
204-
break
196+
return strconv.FormatInt(v, 10)
205197
case int:
206-
strVal = strconv.FormatInt(int64((*item).(int)), 10)
207-
break
198+
return strconv.FormatInt(int64(v), 10)
208199
case uint8:
209-
strVal = strconv.FormatUint(uint64((*item).(uint8)), 10)
210-
break
200+
return strconv.FormatUint(uint64(v), 10)
211201
case uint16:
212-
strVal = strconv.FormatUint(uint64((*item).(uint16)), 10)
213-
break
202+
return strconv.FormatUint(uint64(v), 10)
214203
case uint32:
215-
strVal = strconv.FormatUint(uint64((*item).(uint32)), 10)
216-
break
204+
return strconv.FormatUint(uint64(v), 10)
217205
case uint64:
218-
strVal = strconv.FormatUint((*item).(uint64), 10)
219-
break
206+
return strconv.FormatUint(v, 10)
220207
case uint:
221-
strVal = strconv.FormatUint(uint64((*item).(uint)), 10)
222-
break
208+
return strconv.FormatUint(uint64(v), 10)
223209
case bool:
224-
strVal = strconv.FormatBool((*item).(bool))
225-
break
210+
return strconv.FormatBool(v)
226211
case float32:
227-
strVal = strconv.FormatFloat(float64((*item).(float32)), 'f', -1, 32)
228-
break
212+
return strconv.FormatFloat(float64(v), 'f', -1, 32)
229213
case float64:
230-
strVal = strconv.FormatFloat((*item).(float64), 'f', -1, 64)
231-
break
214+
return strconv.FormatFloat(v, 'f', -1, 64)
232215
default:
233-
strVal = fmt.Sprintf("%v", *item)
234-
break
216+
return fmt.Sprintf("%v", v)
235217
}
236-
return strVal
237218
}

0 commit comments

Comments
 (0)