DEV Community

Cover image for ⚑️ Speed up development? The handy library of most used snippets for Go apps
Vic ShΓ³stak
Vic ShΓ³stak

Posted on • Edited on

⚑️ Speed up development? The handy library of most used snippets for Go apps

Introduction

Well, hello, my DEV friends! πŸ‘‹

It's been a long time since I had the time, and then the opportunity, to write this blog. But thank you, anyway, for staying with me and asking questions!

I really appreciate it. Love you people! 😘

Today I'm going to tell you about my personal little project, which I put out to the public quite recently. But it helped me all these years to write Go programs as fast as possible and in full compliance with the DRY (Don't Repeat Yourself) principle.

Intrigued? Then welcome, it will be interesting! πŸ‘‡

πŸ“ Table of contents

Motivation in library creation

As you already know from my previous articles, I take an approach to software development that makes the developer's life totally easy.

Why repeat the same snippet, for example, to translate a byte slice to a string, if you can add the most efficient solution to the library once and import it where you need it? Exactly right! It's an unnecessary cognitive load for those who will read your code in the future (and for you as well).

It is for these reasons that The Go Snippet Library (or gosl for a short) provides snippets collection for working with routine operations in your Go programs with a super user-friendly API and the most efficient performance.

↑ Table of contents

Basic use of the library

Yes, simply add gosl to your project:

go get github.com/koddr/gosl
Enter fullscreen mode Exit fullscreen mode

Add the needed snippet to your code, like this:

import (
   fmt
   log

   "github.com/koddr/gosl"
)

func main() {
    b := []byte("Hello, World!")

    s, err := gosl.ToString(b) // convert byte slice to string
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(s)
}
Enter fullscreen mode Exit fullscreen mode

Or like this to have access to snippets as embedded struct:

type App struct {
    // ...

    utils    *gosl.Utility                         // add regular snippets
    genUtils *gosl.GenericUtility[any, comparable] // add generic snippets
}

func (a *App) handleSomething(b []byte) error {
    // ...

    s, err := a.utils.ToString(b) // convert byte slice to string
    if err != nil {
        return err
    }

    // ...

    u, err := a.genUtils.Unmarshal(json, model) // unmarshal JSON data to struct
    if err != nil {
        return err
    }

    // ...
}
Enter fullscreen mode Exit fullscreen mode

And you are already saving your time and energy. Trust me ✌️

↑ Table of contents

gosl saving your time and energy

Regular snippets

The regular snippets of the gosl package are aimed at solving one single task with the smallest possible allocation of your machine's resources.

Concat

Concatenate strings s to the one string:

s1 := "this "
s2 := "is "
s3 := "my string"

s := gosl.Concat(s1, s2, s3)
Enter fullscreen mode Exit fullscreen mode

ContainsCaseInsensitive

Report if string substr is within string s (case-insensitive by default):

s := "Hello, WORLD!"
substr := "r"

b := gosl.ContainsCaseInsensitive(s, substr)
Enter fullscreen mode Exit fullscreen mode

RandomString

Generates a (really) random string with a given size:

size := 8

s, err := gosl.RandomString(size)
if err != nil {
    log.Fatal(err)
}
Enter fullscreen mode Exit fullscreen mode

ToString

Convert byte slice b to string or error:

b := []byte("Hello, World!")

s, err := gosl.ToString(b)
if err != nil {
    log.Fatal(err)
}
Enter fullscreen mode Exit fullscreen mode

ToBytes

Convert string s to byte slice or error:

s := "Hello, World!"

b, err := gosl.ToBytes(s)
if err != nil {
    log.Fatal(err)
}
Enter fullscreen mode Exit fullscreen mode

↑ Table of contents

Universal snippets

The universal (or generic) snippets of the gosl package are aimed at solving one particular task with the smallest possible allocation of your machine's resources, but can be applied to a huge number of user types.

ContainsInSlice

Report if value v is within slice s:

s := []string{"one", "two", "three"}
v := "two"

b := gosl.ContainsInSlice(s, v)
Enter fullscreen mode Exit fullscreen mode

ContainsInMap

Report if key k is within map m:

m := map[string]int{"one": 1, "two": 2, "three": 3}
k := "two"

b := gosl.ContainsInMap(m, k)
Enter fullscreen mode Exit fullscreen mode

Marshal

Marshal struct user to JSON data j (byte slice) or error:

type user struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

u := &user{}

j, err := gosl.Marshal(u)
if err != nil {
    log.Fatal(err)
}
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ This snippet is a 100% compatible drop-in replacement for the standard encoding/json library.

Unmarshal

Unmarshal JSON data j (byte slice) to struct user or error:

type user struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

j := []byte(`{"id":1,"name":"Viktor"}`)
m := &user{}

u, err := gosl.Unmarshal(j, m)
if err != nil {
    log.Fatal(err)
}
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ This snippet (also) is a 100% compatible drop-in replacement for the standard encoding/json library.

↑ Table of contents

Benchmarks

My results for all snippets in the library (the test stand is Apple MacBook Air M1, 16Β GB RAM, macOS 13.3.1):

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

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_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

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

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

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

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

BenchmarkContainsInMap-8                            19123504            62.61 ns/op        0 B/op          0 allocs/op
Enter fullscreen mode Exit fullscreen mode

↑ Table of contents

A win-win cooperation

I invite every user of Dev.to (and my lowly blog, certainly) to participate in this project! Let's work together to create the largest and most useful library of snippets for Go programs on the web today.

  • Ask questions and submit your features to the Issues section.
  • Send your snippets or improvements to the current to the Pull requests section.

Your PRs & issues are welcome! Thanks πŸ˜‰

↑ Table of contents

Photos and videos by

P.S.

If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻

❗️ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.

support me on Boosty

And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!

My main projects that need your help (and stars) πŸ‘‡

  • πŸ”₯ gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
  • ✨ create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.

Other my small projects: yatr, gosl, json2csv, csv2api.

Top comments (0)