Coder Social home page Coder Social logo

gokit's Introduction

⬆️ For table of contents, click the above icon

Build GoDoc

Frequently needed, stupid simple, packages in Go.

Directory structure

Low-level packages

Directory structure follows Go's stdlib where there are equivalents. E.g. httputils is found in net/http/httputils/.

Higher-level, "app", packages

Go's stdlib (wisely) doesn't implement higher level/app-level concepts.

Higher-level concepts are in app/ like backoff/retry algorithms or external service related things like AWS wrappers or Prometheus helpers.

Deprecations

  • csrf/ - just use SameSite cookies
  • crypto/pkencryptedstream/ - provides confidentiality, but is malleable (ciphertext is not authenticated). Use Age instead.

gokit's People

Contributors

joonas-fi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gokit's Issues

Ternary operator

Prototype:

// 'ternary operator'
func IfElseAssign[T any](val bool, ifTrue T, ifFalse T) T {
	if val {
		return ifTrue
	} else {
		return ifFalse
	}
}

// 'ternary operator' (lazy production of value)
func IfElseAssignFn[T any](val bool, ifTrue func() T, ifFalse func() T) T {
	if val {
		return ifTrue()
	} else {
		return ifFalse()
	}
}

// "adapter" for making values for `IfElseAssignFn` without having to type the full `func () string { return "foo" }`
func fn[T any](val T) func() T {
	return func() T { return val }
}

func main() {
	name := "Joonas"
	powerEstimate := IfElseAssignFn(name == "Joonas", fn(9001), fn(3))
	powerEstimate = IfElseAssign(name == "Joonas", 9001, 3)
	fmt.Printf("Power of %s = %d\n", name, powerEstimate)
}

`ezhttp`: support for not following redirects

var (
        // can't patch existing HTTP client because we could end up modifying `http.DefaultClient`
        // https://stackoverflow.com/a/38150816
	noFollowRedirects = ezhttp.Client(&http.Client{
		CheckRedirect: func(_ *http.Request, _ []*http.Request) error {
			// no error - just don't follow redirects
			return http.ErrUseLastResponse
		},
	})
)

JSON errors: line numbers

Playground code:

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"strings"
)

// (ab)using the fact that the JSON decoder has accumulated over all it's read plus it's working on the new buffer
// it's about to receive now.
type lineCounter struct {
	committedLines int
	committedBytes int64

	uncommitted      []byte
	uncommittedLines int
}

func (l *lineCounter) LineNumberFromOffset(offset int64) int {
	if offset < l.committedBytes {
		panic("offset < l.committedBytes")
	}

	intoUncommitted := offset - l.committedBytes

	linesIntoUncommitted := countNewlines(l.uncommitted[:intoUncommitted])

	return l.committedLines + linesIntoUncommitted
}

var _ io.Writer = (*lineCounter)(nil)

func (l *lineCounter) Write(buf []byte) (int, error) {
	// the fact that `Write()` was called means that the previous uncommitted buffer was consumed fully. "commit" now.
	l.committedBytes += int64(len(l.uncommitted))
	l.committedLines += l.uncommittedLines

	l.uncommittedLines = countNewlines(buf)
	l.uncommitted = buf

	return len(buf), nil
}

func main() {
	lc := &lineCounter{}

	jd := json.NewDecoder(io.TeeReader(strings.NewReader(`{


	"Foo": "bar"}`), lc))
	err := jd.Decode(&struct{ Foo struct{} }{})
	if err != nil {
		fmt.Printf("err=%v pos=%d\n", err, lc.LineNumberFromOffset(jd.InputOffset()))
	}

	fmt.Println("Hello, 世界")
}

func countNewlines(buf []byte) int {
	newlines := 0

	for _, ch := range buf {
		if ch == '\n' {
			newlines++
		}
	}

	return newlines
}

Atomic file partial filename should be random (or use locking somehow)

If two processes are racing to make the same final file:

rename /run/notifydedup/counter.json.part /run/notifydedup/counter.json: no such file or directory; also failed removing temp file: remove /run/notifydedup/counter.json.part: no such file or directory

Think timeline:

  • Process 1 starts producing counter.json.part
  • Process 2 starts producing counter.json.part, overriding first one
  • Process 1 renames the part file to target (thinking it is its own part file), effectively replacing the target file with an incomplete file

Is it possible to use locking with the part file in a way that two competing processes are not racing to produce the target file?

Result type

Some sketching:

type Result[T any] struct {
	item *T
	err  error
}

func Ok[T any](value T) Result[T] {
	return Result[T]{
		item: &value,
		err:  nil,
	}
}

func Err[T any](err error) Result[T] {
	return Result[T]{
		item: nil,
		err:  err,
	}
}

func getTemp(succeed bool) Result[string] {
	if succeed {
		return Ok("warm")
	} else {
		return Err[string](errors.New("could not succeed"))
	}
}

func main() {
	temp := getTemp(true)
	fmt.Printf("temp=%s\n", *temp.item)
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.