Skip to content
/ tern Public

A small generic utility library for Go that brings ternary-like expressions and a variety of conditional helpers to make complex branching more concise, readable, and type-safe.

License

Notifications You must be signed in to change notification settings

aminofox/tern

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tern — Ternary & Conditional Helpers for Go

tern is a small generic utility library for Go that brings ternary-like expressions and a variety of conditional helpers to make complex branching more concise, readable, and type-safe.

It supports lazy evaluation, chainable if/else-if/else flows, value/predicate-based switch/case, nullish coalescing for zero-values and pointers, and error-aware selectors.

Module: github.com/aminofox/tern
Go version: 1.20+ (1.22 recommended)


Installation

go get github.com/aminofox/tern

Features

  • Ternary Expressions

    • T(cond, thenVal, elseVal) — eager
    • TF(cond, thenFn, elseFn)lazy (evaluates only the selected branch)
  • Chainable Conditions (fluent, lazy)

    • When/WhenFnElseIf/ElseIfFnElse/ElseFn
  • Switch/Case Style Matching

    • Match by value: .Case(val, result), .CaseFn(val, func() R)
    • Match by predicate: .CaseWhen(pred, result), .CaseWhenFn(pred, func() R)
    • Fallback: .Default(def), .DefaultFn(func() R)
  • Nullish / Coalesce Helpers

    • FirstNonZero(vals...) — first non-zero-value element
    • OrElse, OrElseFn — zero-value fallback (lazy and eager versions)
    • PtrOr, PtrOrFn — pointer fallback (lazy and eager)
    • PtrCoalesce(vals...) — first non-nil pointer
  • Error-Aware Helpers

    • IfErr(val, err, fallback) — fallback on error
    • IfErrFn(val, err, func(error) T) — lazy fallback on error
    • Choose(producers...) — runs multiple producers until one returns (val, true)

Quick Examples

import (
    "fmt"
    "strings"

    "github.com/aminofox/tern"
)

// Ternary with nested conditions (lazy)
res := tern.TF[string](
    len(items) > 0,
    func() string { return strings.Join(items, ", ") },
    func() string {
        s := strings.TrimSpace(maybe)
        return tern.T[string](s != "", s, "N/A")
    },
)
fmt.Println(res) // "apple, banana"

// Chain if/else-if/else
grade := tern.When[string](score >= 90, "A").
    ElseIf(score >= 80, "B").
    ElseIf(score >= 70, "C").
    Else("D")

// Switch/case with predicate
perm := tern.Match[string, int](role).
    Case("root", 4).
    Case("admin", 3).
    CaseWhen(func(r string) bool { return strings.HasPrefix(r, "mod") }, 2).
    Default(1)

// Nullish coalescing
name := tern.PtrOr(user.Nickname, "Guest")
limit := tern.OrElse(req.Limit, 50)
first, _ := tern.FirstNonZero("", "abc", "xyz")

// Error-aware fallback
data, err := service.Load()
out := tern.IfErrFn(data, err, func(e error) string { return "cached" })

Running Tests & Examples

Run the full test suite (includes Example... functions that also appear in GoDoc):

go test ./...

Run the CLI example:

go run ./examples

Design Notes

  • All functions with the Fn suffix are lazy — only the selected branch is evaluated.
  • FirstNonZero works based on the Go zero-value for the type.
  • Match short-circuits on the first matching case.
  • Fully generic and type-safe (requires Go 1.18+).

License

MIT

About

A small generic utility library for Go that brings ternary-like expressions and a variety of conditional helpers to make complex branching more concise, readable, and type-safe.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages