Skip to content

Commit

Permalink
Add renders utility, fix tests & bench
Browse files Browse the repository at this point in the history
  • Loading branch information
Vic Shóstak committed May 26, 2023
1 parent 57d3bfa commit b9ce07c
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 27 deletions.
41 changes: 30 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,23 @@ size := 8

s, err := gosl.RandomString(size)
if err != nil {
log.Fatal(err)
log.Fatal(err)
}
```

### RenderStyled

Renders a styled string with a given `lipgloss.Style` template:

```go
t := lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Margin(1)

s := gosl.RenderStyled("This is a styled text", t)
```

This function is a more comfortable wrapper for the
[charmbracelet/lipgloss][charmbracelet_lipgloss_url] library.

### ToString

Convert byte slice `b` to string or error:
Expand Down Expand Up @@ -233,28 +246,30 @@ And this is my results for all functions on test stand (Apple Macbook
Air M1, 16 Gb RAM, macOS 13.3.1):

```bash
BenchmarkConcat_String2-8 58663996 20.06 ns/op 32 B/op 1 allocs/op
BenchmarkConcat_String8-8 26829356 44.16 ns/op 128 B/op 1 allocs/op
BenchmarkConcat_String32-8 9321133 127.8 ns/op 448 B/op 1 allocs/op
BenchmarkConcat_String2-8 59083364 19.91 ns/op 32 B/op 1 allocs/op
BenchmarkConcat_String8-8 27004447 44.21 ns/op 128 B/op 1 allocs/op
BenchmarkConcat_String32-8 9373778 127.4 ns/op 448 B/op 1 allocs/op

BenchmarkToString_HelloWorld-8 100000000 10.56 ns/op 16 B/op 1 allocs/op

BenchmarkToBytes_HelloWorld-8 1000000000 0.6288 ns/op 0 B/op 0 allocs/op

BenchmarkRandomString_Size1-8 3488678 344.6 ns/op 6 B/op 3 allocs/op
BenchmarkRandomString_Size8-8 3394548 353.3 ns/op 24 B/op 3 allocs/op
BenchmarkRandomString_Size1-8 3649489 328.4 ns/op 6 B/op 3 allocs/op
BenchmarkRandomString_Size8-8 3397297 351.8 ns/op 24 B/op 3 allocs/op
BenchmarkRandomString_Size64-8 2313856 517.9 ns/op 160 B/op 3 allocs/op
BenchmarkRandomString_Size512-8 1423572 838.9 ns/op 1280 B/op 3 allocs/op
BenchmarkRandomString_Size4096-8 185337 6350 ns/op 10240 B/op 3 allocs/op
BenchmarkRandomString_Size512-8 1425562 837.8 ns/op 1280 B/op 3 allocs/op
BenchmarkRandomString_Size4096-8 186254 6331 ns/op 10240 B/op 3 allocs/op

BenchmarkMarshal_StructField_4-8 8584442 139.9 ns/op 48 B/op 3 allocs/op
BenchmarkMarshal_StructField_16-8 2838062 420.8 ns/op 192 B/op 3 allocs/op
BenchmarkMarshal_StructField_16-8 2879486 416.6 ns/op 192 B/op 3 allocs/op

BenchmarkUnmarshal_StructField_4-8 6960462 169.3 ns/op 32 B/op 3 allocs/op
BenchmarkUnmarshal_StructField_16-8 764182 1553 ns/op 864 B/op 45 allocs/op
BenchmarkUnmarshal_StructField_16-8 774032 1534 ns/op 864 B/op 45 allocs/op

BenchmarkRenderStyled-8 1459971 821.5 ns/op 440 B/op 12 allocs/op

BenchmarkContainsCaseInsensitive_HelloWorld-8 24856041 48.46 ns/op 16 B/op 1 allocs/op
BenchmarkContainsCaseInsensitive_LoremIpsum-8 1797150 695.9 ns/op 448 B/op 1 allocs/op
BenchmarkContainsCaseInsensitive_LoremIpsum-8 1827114 656.4 ns/op 448 B/op 1 allocs/op

BenchmarkContainsInSlice-8 122999034 9.758 ns/op 0 B/op 0 allocs/op

Expand All @@ -274,7 +289,11 @@ and robots by [Vic Shóstak][author].
[license_img]: https://img.shields.io/badge/license-Apache_2.0-red?style=for-the-badge&logo=none
[license_url]: https://github.com/koddr/gosl/blob/main/LICENSE
[gosl_go_dev_url]: https://pkg.go.dev/github.com/koddr/gosl

[encoding_json_url]: https://pkg.go.dev/encoding/json

[charmbracelet_lipgloss_url]: https://github.com/charmbracelet/lipgloss

[benchmarks]: https://github.com/koddr/gosl/tree/main#%EF%B8%8F-benchmarks
[gosl_url]: https://github.com/koddr/gosl
[author]: https://github.com/koddr
2 changes: 2 additions & 0 deletions concatenators.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import "unsafe"
// Concat concatenate strings using the built-in copy and "unsafe" package with
// unsafe.String function.
//
// If s has no elements returns zero-value for a string.
//
// Example:
//
// package main
Expand Down
8 changes: 8 additions & 0 deletions concatenators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,12 @@ func TestConcat(t *testing.T) {
assert.EqualValues(t, s, "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "should be equal")
assert.NotEqual(t, s, "wrong", "should not be equal")

g := Utility{} // tests for method

s = g.Concat()
assert.EqualValues(t, s, "", "should be equal")

s = g.Concat("Lorem ipsum ", "dolor ", "sit amet, ", "consectetur ", "adipiscing elit")
assert.EqualValues(t, s, "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "should be equal")
assert.NotEqual(t, s, "wrong", "should not be equal")
}
4 changes: 2 additions & 2 deletions converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
// ToBytes converts string to byte slice using the built-in "unsafe" package
// with unsafe.Slice function.
//
// If err != nil returns nil value for a byte slice and error.
// If err != nil returns zero-value for a byte slice and error.
//
// Example:
//
Expand Down Expand Up @@ -42,7 +42,7 @@ func ToBytes(s string) ([]byte, error) {
// ToString converts byte slice to string using the built-in "unsafe" package
// with unsafe.String function.
//
// If err != nil returns "" (empty) value for a string and error.
// If err != nil returns zero-value for a string and error.
//
// Example:
//
Expand Down
2 changes: 1 addition & 1 deletion generators.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// RandomString generates a random string with a given size using built-in
// "crypto/rand" and "encoding/hex" packages.
//
// If err != nil returns "" (empty) value for a string and error.
// If err != nil returns zero-value for a string and error.
//
// Example:
//
Expand Down
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,23 @@ module github.com/koddr/gosl
go 1.20

require (
github.com/charmbracelet/lipgloss v0.7.1
github.com/json-iterator/go v1.1.12
github.com/stretchr/testify v1.8.3
)

require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
21 changes: 21 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs=
github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
28 changes: 20 additions & 8 deletions gosl.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// efficient performance.
package gosl

import "github.com/charmbracelet/lipgloss"

// Utility represents struct for a regular function.
type Utility struct{}

Expand All @@ -12,6 +14,8 @@ type GenericUtility[T any, K comparable] struct{}

// Concat concatenate strings using the built-in copy and "unsafe" package with
// unsafe.String function.
//
// If s has no elements returns zero-value for a string.
func (u *Utility) Concat(s ...string) string {
return Concat(s...)
}
Expand All @@ -20,45 +24,53 @@ func (u *Utility) Concat(s ...string) string {
// "strings" package with strings.Contains. Case-insensitive for input values by
// default.
//
// If s and/or substr have a zero-value returns false value for a bool.
// If s and/or substr have an "" (empty) value returns false for a bool.
func (u *Utility) ContainsCaseInsensitive(s, substr string) bool {
return ContainsCaseInsensitive(s, substr)
}

// RandomString generates a random string with a given size using built-in
// "crypto/rand" and "encoding/hex" packages.
//
// If err != nil returns "" (empty) value for a string and error.
// If err != nil returns zero-value for a string and error.
func (u *Utility) RandomString(size int) (string, error) {
return RandomString(size)
}

// RenderStyled render a styled string with a given lipgloss.Style template
// using "charmbracelet/lipgloss" package.
//
// If s have an "" (empty) value returns zero-value for a string.
func (u *Utility) RenderStyled(s string, template lipgloss.Style) string {
return RenderStyled(s, template)
}

// ToBytes converts string to byte slice using the built-in "unsafe" package
// with unsafe.Slice function.
//
// If err != nil returns nil value for a byte slice and error.
// If err != nil returns zero-value for a byte slice and error.
func (u *Utility) ToBytes(s string) ([]byte, error) {
return ToBytes(s)
}

// ToString converts byte slice to string using the built-in "unsafe" package
// with unsafe.String function.
//
// If err != nil returns "" (empty) value for a string and error.
// If err != nil returns zero-value for a string and error.
func (u *Utility) ToString(b []byte) (string, error) {
return ToString(b)
}

// ContainsInSlice reports if value T is within slice []T.
//
// If s have a zero value returns false value for a bool.
// If s have a zero-value returns false for a bool.
func (g *GenericUtility[T, K]) ContainsInSlice(s []K, value K) bool {
return ContainsInSlice(s, value)
}

// ContainsInMap reports if key T is within map[T]K.
//
// If m have a zero-value returns false value for a bool.
// If m have a zero-value returns false for a bool.
func (g *GenericUtility[T, K]) ContainsInMap(m map[K]T, key K) bool {
return ContainsInMap(m, key)
}
Expand All @@ -67,7 +79,7 @@ func (g *GenericUtility[T, K]) ContainsInMap(m map[K]T, key K) bool {
// with a default configuration. A 100% compatible drop-in replacement of
// "encoding/json" standard lib.
//
// If err != nil returns nil value for a byte slice and error.
// If err != nil returns zero-value for a byte slice and error.
func (g *GenericUtility[T, K]) Marshal(model *T) ([]byte, error) {
return Marshal(model)
}
Expand All @@ -76,7 +88,7 @@ func (g *GenericUtility[T, K]) Marshal(model *T) ([]byte, error) {
// jsoniter.Unmarshal with a default configuration. A 100% compatible drop-in
// replacement of "encoding/json" standard lib.
//
// If err != nil returns nil value for a struct and error.
// If err != nil returns zero-value for a struct and error.
func (g *GenericUtility[T, K]) Unmarshal(data []byte, model *T) (*T, error) {
return Unmarshal(data, model)
}
4 changes: 2 additions & 2 deletions json.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import jsoniter "github.com/json-iterator/go"
// with a default configuration. A 100% compatible drop-in replacement of
// "encoding/json" standard lib.
//
// If err != nil returns nil value for a byte slice and error.
// If err != nil returns zero-value for a byte slice and error.
//
// Example:
//
Expand Down Expand Up @@ -42,7 +42,7 @@ func Marshal[T any](model *T) ([]byte, error) {
// jsoniter.Unmarshal with a default configuration. A 100% compatible drop-in
// replacement of "encoding/json" standard lib.
//
// If err != nil returns nil value for a struct and error.
// If err != nil returns zero-value for a struct and error.
//
// Example:
//
Expand Down
31 changes: 31 additions & 0 deletions renders.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package gosl

import "github.com/charmbracelet/lipgloss"

// RenderStyled render a styled string with a given lipgloss.Style template
// using "charmbracelet/lipgloss" package.
//
// If s have an "" (empty) value returns zero-value for a string.
//
// Example:
//
// package main
//
// import (
// "fmt"
// "log"
//
// "github.com/charmbracelet/lipgloss"
// "github.com/koddr/gosl"
// )
//
// func main() {
// t := lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Margin(1)
//
// s := gosl.RenderStyled("This is a styled text", t)
//
// fmt.Println(s)
// }
func RenderStyled(str string, template lipgloss.Style) string {
return template.Render(str)
}
34 changes: 34 additions & 0 deletions renders_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package gosl

import (
"testing"

"github.com/charmbracelet/lipgloss"
"github.com/stretchr/testify/assert"
)

var resultPrinters string

func BenchmarkRenderStyled(b *testing.B) {
var r string
for i := 0; i < b.N; i++ {
r = RenderStyled("Hello, World!", lipgloss.NewStyle().Foreground(lipgloss.Color("42")))
}
resultGenerators = r
}

func TestRenderStyled(t *testing.T) {
r := RenderStyled("", lipgloss.Style{})
assert.EqualValues(t, "", r)

r = RenderStyled("Hello, World!", lipgloss.NewStyle().Foreground(lipgloss.Color("42")))
assert.EqualValues(t, "Hello, World!", r)

g := Utility{} // tests for method

r = g.RenderStyled("", lipgloss.Style{})
assert.EqualValues(t, "", r)

r = g.RenderStyled("Hello, World!", lipgloss.NewStyle().Foreground(lipgloss.Color("42")))
assert.EqualValues(t, "Hello, World!", r)
}
Loading

0 comments on commit b9ce07c

Please sign in to comment.