Skip to content

Repository files navigation

k1

Every gopher needs a k1t.

Type casting, reflection helpers, and everyday utilities for Go.

Go ReferenceGo VersionLicense: MIT


k1 (read: "k1t") is a small toolkit of the helpers you keep rewriting between projects: type casting that survives custom types and deep pointers, an Option type, safe pointer dereferencing, and set lookups.

The core idea: try a direct type switch first, fall back to reflection. So cast functions accept anything shaped right, not just exact types:

typeUserIDstringid:=UserID("u-42")
p:=&idcast.AsString(id) // "u-42"cast.AsString(&p) // "u-42" - pointers are dereferenced deeply

Note

As* functions panic on impossible conversions instead of returning errors. That is by design: k1 is testing-oriented, and in tests a panic is a failure you want loud.

Install

go get github.com/amberpixels/k1

Quick Start

package main
import (
"fmt""github.com/amberpixels/k1/cast""github.com/amberpixels/k1/maybe""github.com/amberpixels/k1/ptr""github.com/amberpixels/k1/set"
)
typeUserIDstringfuncmain() {
// cast: conversions that survive custom types and pointersid:=UserID("u-42")
fmt.Println(cast.AsString(&id)) // u-42// maybe: Option[T] instead of *Tport:=maybe.Some(8080)
ifport.Some() {
fmt.Println(port.Unwrap()) // 8080
}
// ptr: dereference with a zero-value fallbackvarname*stringfmt.Printf("%q\n", ptr.Deref(name)) // ""// set: map[T]struct{} without the ceremonyadmins:=set.NewLookup("alice", "bob")
fmt.Println(admins.Has("mallory")) // false
}

Casting

The cast package converts (As*) and checks (Is*):

cast.AsString([]byte("data")) // "data"cast.AsBytes("data") // []byte("data")cast.AsInt(42.0) // 42 - integral floats convert; 42.5 panicscast.AsFloat(42) // 42.0cast.AsTime(&customTime) // time.Time, also from custom time types

Full set: AsString, AsBytes, AsBool, AsInt, AsFloat, AsTime, AsKind, AsSliceOfAny, AsStrings - plus IsString, IsStringish, IsNil, IsInt, IsStrings, IsTime for checks.

IsString is strict by default (true only for an actual string); loosen it per call or globally:

cast.IsString(UserID("u-42")) // false - strict by defaultcast.IsString(UserID("u-42"), cast.AllowCustomTypes()) // truecast.IsString([]byte("hi"), cast.AllowAll()) // true - most permissivecast.ConfigureIsStringConfig(cast.AllowAll()) // change the default globally

Optionals

The maybe package is an Option[T] for comparable types, with marshaling that behaves well in configs and APIs:

port:=maybe.Some(8080)
port.Some() // trueport.Unwrap() // 8080; panics on Nonenone:=maybe.None[int]()
json.Marshal(port) // 8080json.Marshal(none) // null

None marshals as null in JSON and as the "None" sentinel in TOML; text unmarshalling treats empty, "null", and "None" as None. Shorthands: maybe.True(), maybe.False(), maybe.NoneBool(), maybe.NoneInt().

Everyday Helpers

  • ptr - ptr.Deref(p) dereferences with a zero-value fallback for nil; ptr.Clone(p) copies a pointee.
  • set - set.Lookup[T] is map[T]struct{} with Has/Add/Delete/Clear; build one with set.NewLookup("a", "b").
  • quick - quick.Append(a, b...) appends only elements not already present; trades extra memory (and GC pressure) for speed on large slices.
  • errs - errs.UnwrapDeep(err) walks a wrapped error chain to the root cause.
  • reflectish - IndirectDeep for deep pointer dereferencing, LengthOf for the length of anything length-y, panic-safe Interface.
  • k1 (root) - k1.JoinStringers(vals, ", ") joins any slice of fmt.Stringers.

Feedback

k1 is a solo, opinionated project - but if you stumbled upon it and have ideas, questions, or bug reports, an issue is always welcome :)

License

MIT © amberpixels

About

A Simple Toolkit for Casting, Reflection, and Everyday Go Utilities.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages