Skip to content

Commit b00838b

Browse files
committed
Merge branch 'docsReDesign' into develop
2 parents 45bad60 + 4552e68 commit b00838b

File tree

3 files changed

+146
-110
lines changed

3 files changed

+146
-110
lines changed

README.md

Lines changed: 146 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,190 @@
1-
# StringFormatter
2-
3-
* A set of a ***high performance string tools*** that helps to build strings from templates and process text faster than with `fmt`!!!.
4-
* Allows to **format code in appropriate style** (`Snake`, `Kebab`, `Camel`) and case.
5-
* Slice printing is **50% faster with 8 items** slice and **250% with 20 items** slice
6-
1+
# Wissance/StringFormatter
72
![GitHub go.mod Go version (subdirectory of monorepo)](https://img.shields.io/github/go-mod/go-version/wissance/stringFormatter?style=plastic)
83
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/wissance/stringFormatter?style=plastic)
94
![GitHub issues](https://img.shields.io/github/issues/wissance/stringFormatter?style=plastic)
105
![GitHub Release Date](https://img.shields.io/github/release-date/wissance/stringFormatter)
11-
![GitHub release (latest by date)](https://img.shields.io/github/downloads/wissance/stringFormatter/v1.6.1/total?style=plastic)
6+
[![Wissance.WebApiToolkit CI](https://github.com/Wissance/stringFormatter/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/Wissance/stringFormatter/actions/workflows/ci.yml)
127

13-
![String Formatter: a convenient string formatting tool](img/sf_cover.png)
8+
![String Formatter: a convenient string formatting tool](img/sf_logo_sm.png)
149

15-
## 1. Features
10+
`StringFormatter` is a ***high-performance*** Go library for string (text) formatting. It offers a syntax *familiar* to `C#`, `Java` and `Python` developers (via template arguments - `{0}` (positional), `{name}` (named)), extensive argument formatting options (numbers, lists, code style), and a set of text utilities — all while being significantly fast as the standard `fmt` package and even more! Typical usage of `sf` are:
11+
1. Create `e-mails`, `Messages` (`SMS`, `Telegram`, other `Notifications`) or other complicated text **based on templates**
12+
2. Create a complicated log text with specific argument formatting
13+
3. Use for **template-based src code generator**
14+
4. Other text proccessing
1615

17-
1. Text formatting with template using traditional for `C#, Python programmers style` - `{0}`, `{name}` that faster then `fmt` does:
18-
![String Formatter: a convenient string formatting tool](img/benchmarks_adv.png)
19-
2. Additional text utilities:
20-
- convert ***map to string*** using one of predefined formats (see `text_utils.go`)
21-
3. Code Style formatting utilities
22-
- convert `snake`/`kebab`/`camel` programming code to each other and vice versa (see `stringstyle_formatter.go`).
23-
4. `StringFormatter` aka `sf` **is safe** (`SAST` and tests were running automatically on push)
16+
## ✨ 1 Features
2417

25-
### 1. Text formatting from templates
18+
🔤 Flexible Syntax: Supports both indexed / positional (`{0}`) and named (`{user}`) *placeholders* in templates.
2619

27-
#### 1.1 Description
20+
🎨 Advanced Formatting: Built-in directives for numbers (`HEX`, `BIN`), `floats`, `lists`, and code styles (camelCase, SNAKE_CASE).
2821

29-
This is a GO module for ***template text formatting in syntax like in C# or/and Python*** using:
30-
- `{n}` , n here is a number to notes order of argument list to use i.e. `{0}`, `{1}`
31-
- `{name}` to notes arguments by name i.e. `{name}`, `{last_name}`, `{address}` and so on ...
22+
🚀 Performance: Template formatting and slice conversion are even faster then `fmt`.
3223

33-
#### 1.2 Examples
24+
🛠 Utilities: Functions to convert `maps` and `slices` into strings with custom separators and formats.
3425

35-
##### 1.2.1 Format by arg order
26+
:man_technologist: Safe : `StringFormatter` aka `sf` **is safe** (`SAST` and tests are running automatically on push)
3627

37-
i.e. you have following template: `"Hello {0}, we are greeting you here: {1}!"`
28+
## 📦 2 Installation
29+
30+
```bash
31+
go get github.com/Wissance/stringFormatter
32+
```
3833

39-
if you call Format with args "manager" and "salesApp" :
34+
## 🚀 3 Usage
35+
36+
### 3.1 Template Formatting
37+
38+
#### 3.1.1 By Argument Order (Format)
39+
The Format function replaces `{n}` placeholders with the corresponding argument in the provided order.
4040

4141
```go
42-
formattedStr := stringFormatter.Format("Hello {0}, we are greeting you here: {1}!", "manager", "salesApp")
43-
```
42+
package main
4443

45-
you get string `"Hello manager, we are greeting you here: salesApp!"`
44+
import (
45+
"fmt"
46+
sf "github.com/Wissance/stringFormatter"
47+
)
4648

47-
##### 1.2.2 Format by arg key
49+
func main() {
50+
template := "Hello, {0}! Your balance is {1} USD."
51+
result := sf.Format(template, "Alex", 2500)
52+
fmt.Println(result)
53+
// Output: Hello, Alex! Your balance is 2500 USD.
54+
}
55+
```
4856

49-
i.e. you have following template: `"Hello {user} what are you doing here {app} ?"`
57+
#### 3.1.2 By Argument Name (FormatComplex)
58+
The FormatComplex function uses a `map[string]any` to replace named placeholders like `{key}`.
5059

51-
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"})`
60+
```go
61+
package main
5262

53-
you get string `"Hello vpupkin what are you doing here mn_console ?"`
63+
import (
64+
"fmt"
65+
sf "github.com/Wissance/stringFormatter"
66+
)
5467

55-
another example is:
68+
func main() {
69+
template := "User {user} (ID: {id}) logged into {app}."
70+
args := map[string]any{
71+
"user": "john_doe",
72+
"id": 12345,
73+
"app": "dashboard",
74+
}
75+
result := sf.FormatComplex(template, args)
76+
fmt.Println(result)
77+
// Output: User john_doe (ID: 12345) logged into dashboard.
78+
}
79+
```
80+
81+
### 3.2 Advanced Argument Formatting
82+
You can control how arguments are displayed by adding a colon (:) and a format specifier to the placeholder.
83+
84+
| Type | Specifier | Description | Example Template | Example Value | Output |
85+
| :--- | :--- | :--- | :--- | :--- | :--- |
86+
| **Numbers** | `:B` | Binary (without padding) | `"{0:B}"` | `15` | `1111` |
87+
| | `:B8` | Binary with 8-digit padding | `"{0:B8}"` | `15` | `00001111` |
88+
| | `:X` | Hexadecimal (lowercase) | `"{0:X}"` | `250` | `fa` |
89+
| | `:X4` | Hexadecimal with 4-digit padding | `"{0:X4}"` | `250` | `00fa` |
90+
| | `:o` | Octal | `"{0:o}"` | `11` | `14` |
91+
| **Floating Point** | `:F` | Default float format | `"{0:F}"` | `10.4567890` | `10.456789` |
92+
| | `:F2` | Float with 2 decimal places | `"{0:F2}"` | `10.4567890` | `10.46` |
93+
| | `:F4` | Float with 4 decimal places | `"{0:F4}"` | `10.4567890` | `10.4568` |
94+
| | `:F8` | Float with 8 decimal places | `"{0:F8}"` | `10.4567890` | `10.45678900` |
95+
| | `:E2` | Scientific notation | `"{0:E2}"` | `191.0478` | `1.91e+02` |
96+
| **Percentage** | `:P100` | Percentage (multiply by 100) | `"{0:P100}"` | `12` | `12%` |
97+
| **Lists (Slices)** | `:L-` | Join with hyphen | `"{0:L-}"` | `[1 2 3]` | `1-2-3` |
98+
| | `:L, ` | Join with comma and space | `"{0:L, }"` | `[1 2 3]` | `1, 2, 3` |
99+
| **Code Styles** | `:c:snake` | Convert to snake_case | `"{0:c:snake}"` | `myFunc` | `my_func` |
100+
| | `:c:Snake` | Convert to Snake_Case (PascalSnake) | `"{0:c:Snake}"` | `myFunc` | `My_Func` |
101+
| | `:c:SNAKE` | Convert to SNAKE_CASE (upper) | `"{0:c:SNAKE}"` | `read-timeout` | `READ_TIMEOUT` |
102+
| | `:c:camel` | Convert to camelCase | `"{0:c:camel}"` | `my_variable` | `myVariable` |
103+
| | `:c:Camel` | Convert to CamelCase (PascalCase) | `"{0:c:Camel}"` | `my_variable` | `MyVariable` |
104+
| | `:c:kebab` | Convert to kebab-case | `"{0:c:kebab}"` | `myVariable` | `my-variable` |
105+
| | `:c:Kebab` | Convert to Kebab-Case (PascalKebab) | `"{0:c:Kebab}"` | `myVariable` | `My-Variable` |
106+
| | `:c:KEBAB` | Convert to KEBAB-CASE (upper) | `"{0:c:KEBAB}"` | `myVariable` | `MY-VARIABLE` |
56107

57108
```go
58-
strFormatResult = stringFormatter.FormatComplex(
59-
"Current app settings are: ipAddr: {ipaddr}, port: {port}, use ssl: {ssl}.",
60-
map[string]any{"ipaddr":"127.0.0.1", "port":5432, "ssl":false},
109+
package main
110+
111+
import (
112+
"fmt"
113+
sf "github.com/Wissance/stringFormatter"
61114
)
115+
116+
func main() {
117+
template := "Status 0x{0:X4} (binary: {0:B8}), temp: {1:F1}°C, items: {2:L, }."
118+
result := sf.Format(template, 475, 23.876, []int{1, 2, 3})
119+
fmt.Println(result)
120+
// Output: Status 0x01DB (binary: 00011101), temp: 23.9°C, items: 1, 2, 3.
121+
}
62122
```
63-
a result will be: `"Current app settings are: ipAddr: 127.0.0.1, port: 5432, use ssl: false."``
64-
65-
##### 1.2.3 Advanced arguments formatting
66-
67-
For more convenient lines formatting we should choose how arguments are representing in output text,
68-
`stringFormatter` supports following format options:
69-
1. Bin number formatting
70-
- `{0:B}, 15 outputs -> 1111`
71-
- `{0:B8}, 15 outputs -> 00001111`
72-
2. Hex number formatting
73-
- `{0:X}, 250 outputs -> fa`
74-
- `{0:X4}, 250 outputs -> 00fa`
75-
3. Oct number formatting
76-
- `{0:o}, 11 outputs -> 14`
77-
4. Float point number formatting
78-
- `{0:E2}, 191.0478 outputs -> 1.91e+02`
79-
- `{0:F}, 10.4567890 outputs -> 10.456789`
80-
- `{0:F4}, 10.4567890 outputs -> 10.4568`
81-
- `{0:F8}, 10.4567890 outputs -> 10.45678900`
82-
5. Percentage output
83-
- `{0:P100}, 12 outputs -> 12%`
84-
6. Lists
85-
- `{0:L-}, [1,2,3] outputs -> 1-2-3`
86-
- `{0:L, }, [1,2,3] outputs -> 1, 2, 3`
87-
7. Code
88-
- `{0:c:snake}, myFunc outputs -> my_func`
89-
- `{0:c:Snake}, myFunc outputs -> My_func`
90-
- `{0:c:SNAKE}, read-timeout outputs -> READ_TIMEOUT`
91-
- `{0:c:camel}, my_variable outputs -> myVariable`
92-
- `{0:c:Camel}, my_variable outputs -> MyVariable`
93-
94-
##### 1.2.4 Benchmarks of the Format and FormatComplex functions
95-
96-
benchmark could be running using following commands from command line:
97-
* to see `Format` result - `go test -bench=Format -benchmem -cpu 1`
98-
* to see `fmt` result - `go test -bench=Fmt -benchmem -cpu 1`
99-
100-
### 2. Text utilities
101-
102-
#### 2.1 Map to string utility
103-
104-
`MapToString` function allows to convert map with primitive key to string using format, including key and value, e.g.:
105-
* `{key} => {value}`
106-
* `{key} : {value}`
107-
* `{value}`
108-
109-
For example:
123+
124+
## 🛠 4 Text Utilities
125+
126+
### 4.1 Map to String (MapToString)
127+
Converts a map with primitive keys to a formatted string.
110128
```go
111129
options := map[string]any{
112-
"connectTimeout": 1000,
113-
"useSsl": true,
114-
"login": "sa",
115-
"password": "sa",
130+
"host": "localhost",
131+
"port": 8080,
132+
"ssl": true,
116133
}
117134

118-
str := stringFormatter.MapToString(&options, "{key} : {value}", ", ")
119-
// NOTE: order of key-value pairs is not guranteed though
120-
// str will be something like:
121-
"connectTimeout : 1000, useSsl : true, login : sa, password : sa"
135+
str := sf.MapToString(&options, "{key} = {value}", "\n")
136+
// Possible output (key order is not guaranteed):
137+
// host = localhost
138+
// port = 8080
139+
// ssl = true
122140
```
123141

124-
#### 2.2 Benchmarks of the MapToString function
142+
### 4.2 Slice to String (SliceToString, SliceSameTypeToString)
143+
Converts slices to a string using a specified separator.
125144

126-
* to see `MapToStr` result - `go test -bench=MapToStr -benchmem -cpu 1`
145+
```go
146+
// For a slice of any type
147+
mixedSlice := []any{100, "text", 3.14}
148+
separator := " | "
149+
result1 := sf.SliceToString(&mixedSlice, &separator)
150+
// result1: "100 | text | 3.14"
151+
152+
// For a typed slice
153+
numSlice := []int{10, 20, 30}
154+
result2 := sf.SliceSameTypeToString(&numSlice, &separator)
155+
// result2: "10 | 20 | 30"
156+
```
127157

128-
![MapToStr benchmarks](/img/map2str_benchmarks.png)
158+
## 📊 5 Benchmarks
159+
The library is optimized for high-load scenarios. Key benchmarks show significant performance gains (performance could be differ due to 1. different CPU architectures 2. statistics):
129160

130-
#### 2.3 Slice to string utility
161+
Formatting (Format) vs fmt.Sprintf: 3-5x faster for complex templates.
162+
Slices (SliceToString) vs manual fmt-based joining: from `2.5` faster up to 20 items.
131163

132-
`SliceToString` - function that converts slice with passed separation between items to string.
133-
```go
134-
slice := []any{100, "200", 300, "400", 500, 600, "700", 800, 1.09, "hello"}
135-
separator := ","
136-
result := stringFormatter.SliceToString(&slice, &separator)
164+
Run the benchmarks yourself:
165+
```bash
166+
go test -bench=Format -benchmem -cpu 1
167+
go test -bench=Fmt -benchmem -cpu 1
168+
go test -bench=MapToStr -benchmem -cpu 1
137169
```
170+
Some benchmark screenshots:
138171

139-
`SliceSameTypeToString` - function that converts typed slice to line with separator
140-
```go
141-
separator := ":"
142-
numericSlice := []int{100, 200, 400, 800}
143-
result := stringFormatter.SliceSameTypeToString(&numericSlice, &separator)
144-
```
172+
1. `Format` and `FormatComplex`:
173+
![Format](img/benchmarks2.png)
174+
175+
2. `MapToStr`:
176+
![MapToStr benchmarks](img/map2str_benchmarks.png)
177+
178+
3. `SliceToStr`:
179+
![SliceToStr benchmarks](img/slice2str_benchmarks.png)
145180

146-
#### 2.4 Benchmarks of the SliceToString function
181+
## 📄 6 License
182+
This project is licensed under the MIT License - see the LICENSE file for details.
147183

148-
`sf` is rather fast then `fmt` 2.5 times (250%) faster on slice with 20 items, see benchmark:
149-
![SliceToStr benchmarks](/img/slice2str_benchmarks.png)
184+
## 🤝 7 Contributing
185+
Contributions are welcome! If you find a bug or have a feature suggestion, please open an issue or submit a pull request.
150186

151-
### 3. Contributors
187+
**Contributors:**
152188

153189
<a href="https://github.com/Wissance/stringFormatter/graphs/contributors">
154190
<img src="https://contrib.rocks/image?repo=Wissance/stringFormatter" />

img/sf_logo.png

2.41 MB
Loading

img/sf_logo_sm.png

267 KB
Loading

0 commit comments

Comments
 (0)