You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

github.com/sonirico/vago

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/sonirico/vago

v0.8.1
Source
Go
Version published
Created
Source
a golang gopher napping in the beach

vago

The ultimate toolkit for vaGo developers. A comprehensive collection of functions, data structures, and utilities designed to enhance productivity and code quality with no learning curve and less effort.

Go Report Card Go Reference License: MIT Release

📖 View full documentation and examples on pkg.go.dev →

✨ Workspace Architecture

This project leverages Go workspaces to provide isolated dependencies for each module. This means:

  • 🎯 Lightweight imports: When you import fp or streams, you won't download database drivers or logging dependencies
  • 🔧 Modular design: Each module (db, lol, num) maintains its own go.mod with specific dependencies
  • 📦 Zero bloat: Use only what you need without carrying unnecessary dependencies
  • 🚀 Fast builds: Smaller dependency graphs lead to faster compilation and smaller binaries

Example: Importing github.com/sonirico/vago/fp will only pull functional programming utilities, not database connections or logging frameworks.

Modules

Table of Contents

🗃️ Db

Package db provides a unified set of abstractions, interfaces, and utilities for database access, transaction management, migrations, and efficient bulk operations across multiple backends.

Features:

  • Backend-agnostic interfaces for SQL (Postgres, ClickHouse), MongoDB, and Redis.
  • Context and transaction management with hooks for after-commit actions.
  • Executor interfaces for read-only, read-write, and transactional operations.
  • Bulk DML helpers: efficient bulk insert, update, and upsert with conflict handling.
  • Migration helpers for Postgres and ClickHouse using golang-migrate.
  • Type utilities for nullable JSON, array types, and custom scanning.
  • Common error types and helpers for consistent error handling.
  • Query helpers for generic, type-safe data access patterns.

Main Interfaces:

  • Handler, Querier, Tx, Result, Rows, Row: Abstract over database drivers.
  • Context: Extends context.Context with database query and transaction hooks.
  • Executor, ExecutorRO, ExecutorRW: Transactional execution patterns.
  • Bulkable, BulkableRanger: Bulk DML abstractions.

Backend Adapters:

  • db_pgx.go: Postgres (pgx) support
  • db_clickhouse.go: ClickHouse support
  • db_mongo.go: MongoDB support
  • db_redis.go: Redis support

Utilities:

  • utils_bulk_insert.go, utils_bulk_update.go, utils_bulk_upsert.go: Bulk DML
  • utils_in_clause.go, utils_order_clause.go, utils_query.go: Query helpers
  • types.go: NullJSON, NullJSONArray, and more
  • errors.go: Common error values and helpers
  • migrate.go, migrations_postgres.go, migrations_clickhouse.go: Migration helpers

Example:

import (
    "github.com/sonirico/vago/db"
    "github.com/sonirico/vago/lol"
)

Setup a logger and a database handler (e.g., pgx)
logger := lol.NewLogger()
handler, _ := db.OpenPgxConn(logger, "postgres://user:pass@localhost/db", false)
executor := db.NewExecutor(logger, handler)

Run a transactional operation: either all operations succeed, or none are applied
err := executor.DoWithTx(ctx, func(ctx db.Context) error {
    Multiple DB operations in a transaction
    if _, err := ctx.Querier().ExecContext(ctx, "INSERT INTO users (name) VALUES ($1)", "alice"); err != nil {
        return err
    }
    if _, err := ctx.Querier().ExecContext(ctx, "INSERT INTO accounts (user) VALUES ($1)", "alice"); err != nil {
        return err
    }
    If any error is returned, all changes are rolled back
    return nil
})

Functions

db BulkInsertSQL

ExampleBulkInsertSQL demonstrates how to use BulkInsertSQL to generate an SQL statement for bulk insertion.

Code
func ExampleBulkInsertSQL() {
	rows := BulkRanger[Bulkable]([]Bulkable{
		&mockBulkable{
			ColsVal: []string{"id", "name", "value"},
			RowVal:  []any{1, "foo", 100},
		},
		&mockBulkable{
			ColsVal: []string{"id", "name", "value"},
			RowVal:  []any{2, "bar", 200},
		},
	})
	query, args, _ := BulkInsertSQL(rows, "my_table")
	fmt.Println("SQL:", normalizeSQL(query))
	fmt.Println("ARGS:", args)
	// Output:
	// SQL: INSERT INTO my_table (id,name,value) VALUES ($1,$2,$3),($4,$5,$6)
	// ARGS: [1 foo 100 2 bar 200]
}

⬆️ Back to Top

db BulkUpdateSQL

ExampleBulkUpdateSQL demonstrates how to use BulkUpdateSQL to generate an SQL statement for bulk updates.

Code
func ExampleBulkUpdateSQL() {
	rows := mockBulkUpdate{
		&mockBulkUpdatable{
			pk:   [2]string{"int", "id"},
			cols: [][2]string{{"int", "value"}, {"text", "name"}},
			vals: []any{1, "foo", 100, "bar"},
		},
		&mockBulkUpdatable{
			pk:   [2]string{"int", "id"},
			cols: [][2]string{{"int", "value"}, {"text", "name"}},
			vals: []any{2, "baz", 200, "qux"},
		},
	}
	query, args, _ := BulkUpdateSQL(rows, "my_table")
	fmt.Println("SQL:", normalizeSQL(query))
	fmt.Println("ARGS:", args)
	// Output:
	// SQL: UPDATE my_table SET value = bulk_update_tmp.value::int,name = bulk_update_tmp.name::text FROM (VALUES ($1::int, $2::int, $3::text), ($4::int, $5::int, $6::text)) as bulk_update_tmp(id, value, name) WHERE my_table.id::int = bulk_update_tmp.id::int
	// ARGS: [1 foo 100 bar 2 baz 200 qux]
}

⬆️ Back to Top

db BulkUpsertSQL

Example for BulkUpsertSQL with update on conflict clause

Code
func ExampleBulkUpsertSQL() {
	rows := BulkRanger[Bulkable]([]Bulkable{
		&mockBulkable{
			PKVal:         []string{"id"},
			UniqueKeysVal: []string{"unique_key"},
			IncludePKVal:  true,
			ColsVal:       []string{"id", "unique_key", "value"},
			RowVal:        []any{1, "abc", 100},
		},
	})
	onConflictUpdate := false
	query, args, _ := BulkUpsertSQL(rows, "my_table", onConflictUpdate)
	fmt.Println("SQL:", normalizeSQL(query))
	fmt.Println("ARGS:", args)

	fmt.Println("--")

	onConflictUpdate = true
	query, args, _ = BulkUpsertSQL(rows, "my_table", onConflictUpdate)
	fmt.Println("SQL:", normalizeSQL(query))
	fmt.Println("ARGS:", args)

	// Output:
	// SQL: INSERT INTO my_table (id,unique_key,value) VALUES ($1,$2,$3) ON CONFLICT (unique_key) DO NOTHING RETURNING id,unique_key,value
	// ARGS: [1 abc 100]
	// --
	// SQL: INSERT INTO my_table (id,unique_key,value) VALUES ($1,$2,$3) ON CONFLICT (unique_key) DO UPDATE SET id = EXCLUDED.id,unique_key = EXCLUDED.unique_key,value = EXCLUDED.value RETURNING id,unique_key,value
	// ARGS: [1 abc 100]
}

⬆️ Back to Top

db Executor

Example for Do and DoWithTx usage with a database service and context.

Code
func ExampleExecutor() {
	db, mock, _ := sqlmock.New(
		sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
	defer db.Close()
	log := lol.ZeroTestLogger

	// Setup mock expectations
	mock.ExpectQuery("SELECT 1;").
		WillReturnRows(sqlmock.NewRows([]string{"n"}).AddRow(1))

	ex := newDatabaseSqlExecutor(log, db)

	err := ex.Do(context.Background(), func(ctx Context) error {
		var n int
		return ctx.Querier().
			QueryRowContext(ctx, "SELECT 1;").Scan(&n)
	})
	fmt.Println("Do error:", err)

	mock.ExpectBegin()
	mock.ExpectQuery("SELECT 2;").
		WillReturnRows(sqlmock.NewRows([]string{"n"}).AddRow(2))
	mock.ExpectCommit()

	err = ex.DoWithTx(context.Background(), func(ctx Context) error {
		var n int
		return ctx.Querier().QueryRowContext(ctx, "SELECT 2;").Scan(&n)
	})
	fmt.Println("DoWithTx error:", err)

	// Output:
	// Do error: <nil>
	// DoWithTx error: <nil>
}

⬆️ Back to Top

db In

ExampleIn demonstrates how to use the In function to generate an SQL IN clause and its arguments.

Code
func ExampleIn() {
	args := []any{"foo"}
	inArgs := []int{1, 2, 3}
	s, a := In(args, inArgs)
	fmt.Println(s)
	fmt.Println(a)
	// Output:
	// ($2,$3,$4)
	// [foo 1 2 3]
}

⬆️ Back to Top

db OrderBy_usage

ExampleOrderBy_usage demonstrates how to use OrderBy types to generate SQL ORDER BY clauses.

Code
func ExampleOrderBy_usage() {
	fmt.Println(OrderASC.FullClause("foo"))
	fmt.Println(OrderDESC.FullClause("foo"))
	// Output:
	//  ORDER BY foo ASC
	//  ORDER BY foo DESC
}

⬆️ Back to Top

⬆️ Back to Top


🪾 Ent

Package ent provides utilities for managing environment variables in a type-safe manner.

Functions

ent Bool

ExampleBool demonstrates how to retrieve boolean environment variables with various true/false representations.

Code
func ExampleBool() {
	// Set environment variable
	os.Setenv("DEBUG", "true")
	defer os.Unsetenv("DEBUG")

	debug := Bool("DEBUG", false)
	fmt.Println(debug)
	// Output:
	// 
	// true
}

⬆️ Back to Top

ent CondStrOrPanic

ExampleCondStrOrPanic demonstrates how to conditionally retrieve environment variables with panic on missing values.

Code
func ExampleCondStrOrPanic() {
	// Set environment variable
	os.Setenv("DEBUG_MODE", "true")
	defer os.Unsetenv("DEBUG_MODE")

	// Get value only if condition is true
	debugMode := CondStrOrPanic(true, "DEBUG_MODE")
	fmt.Println(debugMode)

	// Returns empty string if condition is false
	emptyValue := CondStrOrPanic(false, "DEBUG_MODE")
	fmt.Println(emptyValue)
	// Output:
	// 
	// true
	//
}

⬆️ Back to Top

ent Contains

ExampleContains demonstrates how to check if a value exists in a slice of strings.

Code
func ExampleContains() {
	fruits := []string{"apple", "banana", "cherry"}

	hasBanana := contains(fruits, "banana")
	fmt.Println(hasBanana)

	hasOrange := contains(fruits, "orange")
	fmt.Println(hasOrange)
	// Output:
	// 
	// true
	// false
}

⬆️ Back to Top

ent Duration

ExampleDuration demonstrates how to retrieve time.Duration environment variables with fallback values.

Code
func ExampleDuration() {
	// Set environment variable
	os.Setenv("REQUEST_TIMEOUT", "30s")
	defer os.Unsetenv("REQUEST_TIMEOUT")

	timeout := Duration("REQUEST_TIMEOUT", 10*time.Second)
	fmt.Println(timeout)
	// Output:
	// 
	// 30s
}

⬆️ Back to Top

ent Enum

ExampleEnum demonstrates how to retrieve environment variables with validation against allowed values.

Code
func ExampleEnum() {
	// Set environment variable
	os.Setenv("ENV", "staging")
	defer os.Unsetenv("ENV")

	env := Enum("ENV", "dev", "dev", "staging", "prod")
	fmt.Println(env)
	// Output:
	// 
	// staging
}

⬆️ Back to Top

ent EnumOrPanic

ExampleEnumOrPanic demonstrates how to retrieve required environment variables with validation against allowed values, panicking if invalid.

Code
func ExampleEnumOrPanic() {
	// Set environment variable
	os.Setenv("LOG_LEVEL", "info")
	defer os.Unsetenv("LOG_LEVEL")

	logLevel := EnumOrPanic("LOG_LEVEL", "debug", "info", "warn", "error")
	fmt.Println(logLevel)
	// Output:
	// 
	// info
}

⬆️ Back to Top

ent FixedStrOrPanic

ExampleFixedStrOrPanic demonstrates how to retrieve environment variables with length validation.

Code
func ExampleFixedStrOrPanic() {
	// Set environment variable with exact length
	os.Setenv("API_KEY", "abc123")
	defer os.Unsetenv("API_KEY")

	// Get value with length validation
	apiKey := FixedStrOrPanic("API_KEY", 6)
	fmt.Println(apiKey)
	// Output:
	// 
	// abc123
}

⬆️ Back to Top

ent Float64

ExampleFloat64 demonstrates how to retrieve float64 environment variables with fallback values.

Code
func ExampleFloat64() {
	// Set environment variable
	os.Setenv("PRICE", "19.99")
	defer os.Unsetenv("PRICE")

	price := Float64("PRICE", 0.0)
	fmt.Println(price)
	// Output:
	// 
	// 19.99
}

⬆️ Back to Top

ent Get

ExampleGet demonstrates how to retrieve environment variables with fallback values.

Code
func ExampleGet() {
	// Set an environment variable
	os.Setenv("APP_NAME", "MyApplication")
	defer os.Unsetenv("APP_NAME")

	// Get existing env var
	appName := Get("APP_NAME", "DefaultApp")
	fmt.Println(appName)

	// Get non-existing env var with fallback
	dbHost := Get("DB_HOST", "localhost")
	fmt.Println(dbHost)
	// Output:
	// 
	// MyApplication
	// localhost
}

⬆️ Back to Top

ent Int

ExampleInt demonstrates how to retrieve integer environment variables with fallback values.

Code
func ExampleInt() {
	// Set environment variable
	os.Setenv("WORKER_COUNT", "4")
	defer os.Unsetenv("WORKER_COUNT")

	workers := Int("WORKER_COUNT", 1)
	fmt.Println(workers)
	// Output:
	// 
	// 4
}

⬆️ Back to Top

ent Int64

ExampleInt64 demonstrates how to retrieve int64 environment variables with fallback values.

Code
func ExampleInt64() {
	// Set environment variable
	os.Setenv("MAX_CONNECTIONS", "100")
	defer os.Unsetenv("MAX_CONNECTIONS")

	maxConn := Int64("MAX_CONNECTIONS", 50)
	fmt.Println(maxConn)
	// Output:
	// 
	// 100
}

⬆️ Back to Top

ent Int64OrPanic

ExampleInt64OrPanic demonstrates how to retrieve required int64 environment variables that panic if missing or invalid.

Code
func ExampleInt64OrPanic() {
	// Set required environment variable
	os.Setenv("PORT", "8080")
	defer os.Unsetenv("PORT")

	port := Int64OrPanic("PORT")
	fmt.Println(port)
	// Output:
	// 
	// 8080
}

⬆️ Back to Top

ent IntOrPanic

ExampleIntOrPanic demonstrates how to retrieve required integer environment variables that panic if missing or invalid.

Code
func ExampleIntOrPanic() {
	// Set required environment variable
	os.Setenv("TIMEOUT", "30")
	defer os.Unsetenv("TIMEOUT")

	timeout := IntOrPanic("TIMEOUT")
	fmt.Println(timeout)
	// Output:
	// 
	// 30
}

⬆️ Back to Top

ent JSON

ExampleJSON demonstrates how to parse JSON environment variables into Go structs with type safety.

Code
func ExampleJSON() {
	type Config struct {
		Host string `json:"host"`
		Port int    `json:"port"`
	}

	// Set environment variable
	os.Setenv("DB_CONFIG", `{"host":"localhost","port":5432}`)
	defer os.Unsetenv("DB_CONFIG")

	config, err := JSON[Config]("DB_CONFIG", `{"host":"127.0.0.1","port":3306}`)
	if err != nil {
		panic(err)
	}
	fmt.Println(config.Host)
	// Output:
	// 
	// localhost
}

⬆️ Back to Top

ent SliceInt

ExampleSliceInt demonstrates how to retrieve integer slice environment variables from comma-separated values.

Code
func ExampleSliceInt() {
	// Set environment variable
	os.Setenv("PORTS", "8080,8081,8082")
	defer os.Unsetenv("PORTS")

	ports := SliceInt("PORTS", []int{3000})
	fmt.Println(len(ports))
	// Output:
	// 
	// 3
}

⬆️ Back to Top

ent SliceStr

ExampleSliceStr demonstrates how to retrieve string slice environment variables from comma-separated values.

Code
func ExampleSliceStr() {
	// Set environment variable
	os.Setenv("ALLOWED_HOSTS", "localhost,127.0.0.1,example.com")
	defer os.Unsetenv("ALLOWED_HOSTS")

	hosts := SliceStr("ALLOWED_HOSTS", []string{"localhost"})
	fmt.Println(len(hosts))
	// Output:
	// 
	// 3
}

⬆️ Back to Top

ent Str

ExampleStr demonstrates how to retrieve string environment variables with fallback values.

Code
func ExampleStr() {
	// Set environment variable
	os.Setenv("USER_NAME", "john_doe")
	defer os.Unsetenv("USER_NAME")

	username := Str("USER_NAME", "anonymous")
	fmt.Println(username)
	// Output:
	// 
	// john_doe
}

⬆️ Back to Top

ent StrOrPanic

ExampleStrOrPanic demonstrates how to retrieve required environment variables that panic if missing.

Code
func ExampleStrOrPanic() {
	// Set required environment variable
	os.Setenv("REQUIRED_CONFIG", "important_value")
	defer os.Unsetenv("REQUIRED_CONFIG")

	// Get required value (panics if missing)
	config := StrOrPanic("REQUIRED_CONFIG")
	fmt.Println(config)
	// Output:
	// 
	// important_value
}

⬆️ Back to Top

⬆️ Back to Top


🪄 Fp

Functional programming utilities including Option and Result types.

Functions

fp Err

ExampleErr demonstrates creating an error Result.

Code
func ExampleErr() {
	// Create an error result
	result := Err[string](errors.New("something failed"))

	fmt.Printf("Is error: %t\n", result.IsErr())
	fmt.Printf("Value: %s\n", result.UnwrapOr("default"))

	// Output:
	// Is error: true
	// Value: default
}

⬆️ Back to Top

fp None

ExampleNone demonstrates creating an empty Option.

Code
func ExampleNone() {
	// Create an empty Option
	empty := None[string]()

	fmt.Printf("Has value: %t\n", empty.IsSome())
	fmt.Printf("Value: %s\n", empty.UnwrapOr("default"))

	// Output:
	// Has value: false
	// Value: default
}

⬆️ Back to Top

fp Ok

ExampleOk demonstrates creating a successful Result.

Code
func ExampleOk() {
	// Create a successful result
	result := Ok("Success!")

	fmt.Printf("Is ok: %t\n", result.IsOk())
	fmt.Printf("Value: %s\n", result.UnwrapOr("default"))

	// Output:
	// Is ok: true
	// Value: Success!
}

⬆️ Back to Top

fp OkZero

ExampleOkZero demonstrates creating a Result with zero value.

Code
func ExampleOkZero() {
	// Create a successful result with zero value
	result := OkZero[int]()

	fmt.Printf("Is ok: %t\n", result.IsOk())
	fmt.Printf("Value: %d\n", result.UnwrapOr(-1))

	// Output:
	// Is ok: true
	// Value: 0
}

⬆️ Back to Top

fp Option

ExampleOption demonstrates basic usage of the Option type.

Code
func ExampleOption() {
	// Create Some and None options
	someValue := Some(42)
	noneValue := None[int]()

	// Check if options have values
	fmt.Printf("Some has value: %v\n", someValue.IsSome())
	fmt.Printf("None has value: %v\n", noneValue.IsSome())

	// Extract values safely
	if value, ok := someValue.Unwrap(); ok {
		fmt.Printf("Value: %d\n", value)
	}

	// Output:
	// Some has value: true
	// None has value: false
	// Value: 42
}

⬆️ Back to Top

fp OptionFromPtr

ExampleOptionFromPtr demonstrates creating Option from a pointer.

Code
func ExampleOptionFromPtr() {
	// From valid pointer
	value := "hello"
	opt1 := OptionFromPtr(&value)

	// From nil pointer
	var nilPtr *string
	opt2 := OptionFromPtr(nilPtr)

	fmt.Printf("From pointer: %s\n", opt1.UnwrapOr("empty"))
	fmt.Printf("From nil: %s\n", opt2.UnwrapOr("empty"))

	// Output:
	// From pointer: hello
	// From nil: empty
}

⬆️ Back to Top

fp OptionFromTuple

ExampleOptionFromTuple demonstrates creating Option from a tuple pattern.

Code
func ExampleOptionFromTuple() {
	// Common Go pattern: value, ok
	getValue := func(key string) (string, bool) {
		data := map[string]string{"name": "Alice", "age": "25"}
		value, ok := data[key]
		return value, ok
	}

	// Convert to Option
	nameOpt := OptionFromTuple(getValue("name"))
	missingOpt := OptionFromTuple(getValue("missing"))

	fmt.Printf("Name: %s\n", nameOpt.UnwrapOr("unknown"))
	fmt.Printf("Missing: %s\n", missingOpt.UnwrapOr("unknown"))

	// Output:
	// Name: Alice
	// Missing: unknown
}

⬆️ Back to Top

fp Option_Map

ExampleOption_Map demonstrates transforming values inside Option.

Code
func ExampleOption_Map() {
	// Start with an optional number
	maybeNumber := Some(5)

	// Transform it to its square
	maybeSquare := maybeNumber.Map(func(x int) int { return x * x })

	// Transform None value
	noneNumber := None[int]()
	noneSquare := noneNumber.Map(func(x int) int { return x * x })

	fmt.Printf("Square of 5: %v\n", maybeSquare.UnwrapOr(0))
	fmt.Printf("Square of None: %v\n", noneSquare.UnwrapOr(-1))

	// Output:
	// Square of 5: 25
	// Square of None: -1
}

⬆️ Back to Top

fp Option_Match

ExampleOption_Match demonstrates pattern matching with Option.

Code
func ExampleOption_Match() {
	// Helper function that may return a value
	getValue := func(id int) Option[string] {
		if id > 0 {
			return Some(fmt.Sprintf("User_%d", id))
		}
		return None[string]()
	}

	// Pattern match on the result
	validUser := getValue(42)
	invalidUser := getValue(-1)

	result1 := validUser.Match(
		func(user string) Option[string] {
			return Some("Found: " + user)
		},
		func() Option[string] {
			return Some("No user found")
		},
	)

	result2 := invalidUser.Match(
		func(user string) Option[string] {
			return Some("Found: " + user)
		},
		func() Option[string] {
			return Some("No user found")
		},
	)

	fmt.Printf("Valid user: %s\n", result1.UnwrapOr(""))
	fmt.Printf("Invalid user: %s\n", result2.UnwrapOr(""))

	// Output:
	// Valid user: Found: User_42
	// Invalid user: No user found
}

⬆️ Back to Top

fp Option_Or

ExampleOption_Or demonstrates providing fallback values.

Code
func ExampleOption_Or() {
	// Create some options
	primary := None[string]()
	secondary := Some("backup")
	tertiary := Some("fallback")

	// Chain fallbacks
	result := primary.Or(secondary).Or(tertiary)

	fmt.Printf("Result: %s\n", result.UnwrapOr("default"))

	// Output:
	// Result: backup
}

⬆️ Back to Top

fp Result

ExampleResult demonstrates basic usage of the Result type.

Code
func ExampleResult() {
	// Create successful and error results
	success := Ok("Hello, World!")
	failure := Err[string](errors.New("something went wrong"))

	// Check if results are ok
	fmt.Printf("Success is ok: %v\n", success.IsOk())
	fmt.Printf("Failure is ok: %v\n", failure.IsOk())

	// Extract values safely
	if value, err := success.Unwrap(); err == nil {
		fmt.Printf("Success value: %s\n", value)
	}

	if _, err := failure.Unwrap(); err != nil {
		fmt.Printf("Failure error: %v\n", err)
	}

	// Output:
	// Success is ok: true
	// Failure is ok: false
	// Success value: Hello, World!
	// Failure error: something went wrong
}

⬆️ Back to Top

fp Result_Map

ExampleResult_Map demonstrates transforming values inside Result.

Code
func ExampleResult_Map() {
	// Start with a result containing a number
	result := Ok(5)

	// Transform to its square
	squared := result.Map(func(x int) int { return x * x })

	// Transform an error result
	errorResult := Err[int](errors.New("invalid input"))
	errorSquared := errorResult.Map(func(x int) int { return x * x })

	fmt.Printf("Square of 5: %v\n", squared.UnwrapOr(0))
	fmt.Printf("Square of error: %v\n", errorSquared.UnwrapOr(-1))

	// Output:
	// Square of 5: 25
	// Square of error: -1
}

⬆️ Back to Top

fp Result_Match

ExampleResult_Match demonstrates pattern matching with Result.

Code
func ExampleResult_Match() {
	// Helper function that may fail
	divide := func(x, y int) Result[int] {
		if y == 0 {
			return Err[int](errors.New("division by zero"))
		}
		return Ok(x / y)
	}

	// Pattern match on results
	success := divide(10, 2)
	failure := divide(10, 0)

	result1 := success.Match(
		func(value int) Result[int] {
			return Ok(value * 2)
		},
		func(err error) Result[int] {
			return Err[int](fmt.Errorf("handled: %w", err))
		},
	)

	result2 := failure.Match(
		func(value int) Result[int] {
			return Ok(value * 2)
		},
		func(err error) Result[int] {
			return Err[int](fmt.Errorf("handled: %w", err))
		},
	)

	fmt.Printf("Success result: %v\n", result1.UnwrapOr(-1))
	fmt.Printf("Failure handled: %v\n", result2.IsErr())

	// Output:
	// Success result: 10
	// Failure handled: true
}

⬆️ Back to Top

fp Result_Or

ExampleResult_Or demonstrates providing fallback results.

Code
func ExampleResult_Or() {
	// Create primary and fallback results
	primary := Err[string](errors.New("primary failed"))
	fallback := Ok("fallback value")

	// Use fallback when primary fails
	result := primary.Or(fallback)

	fmt.Printf("Result: %s\n", result.UnwrapOr("default"))

	// Output:
	// Result: fallback value
}

⬆️ Back to Top

fp Some

ExampleSome demonstrates creating an Option with a value.

Code
func ExampleSome() {
	// Create an Option containing a string
	message := Some("Hello, World!")

	fmt.Printf("Has value: %t\n", message.IsSome())
	fmt.Printf("Value: %s\n", message.UnwrapOr("default"))

	// Output:
	// Has value: true
	// Value: Hello, World!
}

⬆️ Back to Top

⬆️ Back to Top


📝 Lol

Package lol (lots of logs) provides a unified logging interface with multiple backends.

This package offers a simple, structured logging interface that can be backed by different logging implementations. Currently it supports zerolog as the primary backend.

Key features:

  • Structured logging with fields
  • Multiple log levels (trace, debug, info, warn, error, fatal, panic)
  • APM trace context integration
  • Environment-aware configuration
  • Testing utilities

Basic usage:

logger := lol.NewZerolog(
	lol.WithFields(lol.Fields{"service": "myapp"}),
	lol.WithEnv("production"),
	lol.WithLevel("info"),
	lol.WithWriter(os.Stdout),
	lol.WithAPM(lol.APMConfig{Enabled: true}),
)

logger.Info("Application started")
logger.WithField("user_id", 123).Warn("User action")

For testing:

testLogger := lol.NewTest()
testLogger.Error("This won't be printed")

Functions

lol Logger_LogLevels

ExampleLogger_LogLevels demonstrates different log levels

Code
func ExampleLogger_LogLevels() {
	var buf bytes.Buffer

	logger := NewZerolog(
		WithFields(Fields{"component": "auth"}),
		WithEnv(EnvDev),
		WithLevel(LevelTrace), // Set to trace level to see all messages
		WithWriter(&buf),
	)

	// Log at different levels
	logger.Trace("Entering authentication function")
	logger.Debug("Validating user credentials")
	logger.Info("User authentication successful")
	logger.Warn("Rate limit approaching")
	logger.Error("Authentication failed")

	output := buf.String()
	fmt.Printf(
		"Contains trace message: %t\n",
		bytes.Contains([]byte(output), []byte("Entering authentication")),
	)
	fmt.Printf(
		"Contains debug message: %t\n",
		bytes.Contains([]byte(output), []byte("Validating user")),
	)
	fmt.Printf(
		"Contains info message: %t\n",
		bytes.Contains([]byte(output), []byte("authentication successful")),
	)
	fmt.Printf("Contains warn message: %t\n", bytes.Contains([]byte(output), []byte("Rate limit")))
	fmt.Printf(
		"Contains error message: %t\n",
		bytes.Contains([]byte(output), []byte("Authentication failed")),
	)

	// Output:
	// Contains trace message: true
	// Contains debug message: true
	// Contains info message: true
	// Contains warn message: true
	// Contains error message: true
}

⬆️ Back to Top

lol Logger_WithField

ExampleLogger_WithField demonstrates adding contextual fields to log messages

Code
func ExampleLogger_WithField() {
	var buf bytes.Buffer

	logger := NewZerolog(
		WithFields(Fields{"app": "demo"}),
		WithEnv(EnvDev),
		WithLevel(LevelDebug),
		WithWriter(&buf),
	)

	// Chain multiple fields
	enrichedLogger := logger.WithField("request_id", "req-123").
		WithField("user_agent", "test-client")
	enrichedLogger.Info("Processing request")

	// Add more context
	enrichedLogger.WithField("duration_ms", 45).Info("Request completed")

	output := buf.String()
	fmt.Printf(
		"Output contains 'request_id': %t\n",
		bytes.Contains([]byte(output), []byte("request_id")),
	)
	fmt.Printf(
		"Output contains 'user_agent': %t\n",
		bytes.Contains([]byte(output), []byte("user_agent")),
	)
	fmt.Printf(
		"Output contains 'duration_ms': %t\n",
		bytes.Contains([]byte(output), []byte("duration_ms")),
	)

	// Output:
	// Output contains 'request_id': true
	// Output contains 'user_agent': true
	// Output contains 'duration_ms': true
}

⬆️ Back to Top

lol Logger_WithTrace

ExampleLogger_WithTrace demonstrates APM trace context integration

Code
func ExampleLogger_WithTrace() {
	var buf bytes.Buffer

	logger := NewZerolog(
		WithFields(Fields{"service": "payment-service"}),
		WithEnv(EnvDev),
		WithLevel(LevelInfo),
		WithWriter(&buf),
		WithApm(), // Enable APM tracing
	)

	// Create an APM transaction (simulating real APM integration)
	tracer := apm.DefaultTracer()
	tx := tracer.StartTransaction("payment-processing", "request")
	defer tx.End()

	// Create context with the transaction
	ctx := apm.ContextWithTransaction(context.Background(), tx)

	// Start a span for more detailed tracing
	span, ctx := apm.StartSpan(ctx, "payment-validation", "internal")
	defer span.End()

	// Create a logger with trace context
	tracedLogger := logger.WithTrace(ctx)

	// Log with trace context - these should include APM trace fields
	tracedLogger.Info("Processing payment request")
	tracedLogger.WithField("payment_id", "pay_123").
		WithField("amount", 99.99).
		Info("Payment validation started")

	// Log without trace context for comparison
	logger.Info("Regular log message without trace context")

	output := buf.String()
	fmt.Printf(
		"Output contains 'Processing payment': %t\n",
		bytes.Contains([]byte(output), []byte("Processing payment")),
	)
	fmt.Printf(
		"Output contains 'payment_id': %t\n",
		bytes.Contains([]byte(output), []byte("payment_id")),
	)
	fmt.Printf(
		"Output contains 'service': %t\n",
		bytes.Contains([]byte(output), []byte("service")),
	)

	// Check for APM trace fields in the output
	// The apmzerolog hook should add these fields when WithTrace is used
	fmt.Printf(
		"Output contains trace information: %t\n",
		bytes.Contains([]byte(output), []byte("trace")) ||
			bytes.Contains([]byte(output), []byte("transaction")) ||
			bytes.Contains([]byte(output), []byte("span")),
	)

	// Output:
	// Output contains 'Processing payment': true
	// Output contains 'payment_id': true
	// Output contains 'service': true
	// Output contains trace information: true
}

⬆️ Back to Top

lol NewZerolog

ExampleNewZerolog demonstrates creating a structured logger with zerolog backend

Code
func ExampleNewZerolog() {
	// Create a logger with custom fields and configuration
	var buf bytes.Buffer

	logger := NewZerolog(
		WithFields(Fields{"service": "example-app", "version": "1.0.0"}),
		WithEnv(EnvProd),
		WithLevel(LevelInfo),
		WithWriter(&buf),
	)

	// Log some messages
	logger.Info("Application started successfully")
	logger.WithField("user_id", 123).WithField("action", "login").Info("User logged in")
	logger.Warn("This is a warning message")

	fmt.Printf(
		"Logged output contains 'Application started': %t\n",
		bytes.Contains(buf.Bytes(), []byte("Application started")),
	)
	fmt.Printf(
		"Logged output contains 'user_id': %t\n",
		bytes.Contains(buf.Bytes(), []byte("user_id")),
	)
	fmt.Printf(
		"Logged output contains 'service': %t\n",
		bytes.Contains(buf.Bytes(), []byte("service")),
	)

	fmt.Printf(
		"Logged output contains 'version': %t\n",
		bytes.Contains(buf.Bytes(), []byte("version")),
	)

	// Output:
	// Logged output contains 'Application started': true
	// Logged output contains 'user_id': true
	// Logged output contains 'service': true
	// Logged output contains 'version': true
}

⬆️ Back to Top

⬆️ Back to Top


🗝️ Maps

Package maps provides generic utility functions to work with Go maps. It offers a functional approach to common map operations like filtering, mapping, reducing, and comparing maps.

Functions

maps Equals

ExampleEquals demonstrates comparing two maps for equality.

Code
func ExampleEquals() {
	// Create two maps
	map1 := map[string]int{"a": 1, "b": 2, "c": 3}
	map2 := map[string]int{"a": 1, "b": 2, "c": 3}
	map3 := map[string]int{"a": 1, "b": 2, "c": 4}

	// Compare using equality function
	equal1 := Equals(map1, map2, func(x, y int) bool { return x == y })
	equal2 := Equals(map1, map3, func(x, y int) bool { return x == y })

	fmt.Printf("map1 == map2: %t\n", equal1)
	fmt.Printf("map1 == map3: %t\n", equal2)
	// Output:
	// map1 == map2: true
	// map1 == map3: false
}

⬆️ Back to Top

maps Filter

ExampleFilter demonstrates filtering a map by key-value pairs.

Code
func ExampleFilter() {
	// Create a map of products to prices
	prices := map[string]int{
		"apple":  100,
		"banana": 50,
		"cherry": 200,
		"date":   75,
	}

	// Keep only items that cost more than 75
	expensive := Filter(prices, func(product string, price int) bool {
		return price > 75
	})

	fmt.Printf("Expensive items count: %d\n", len(expensive))
	// Output: Expensive items count: 2
}

⬆️ Back to Top

maps FilterMap

ExampleFilterMap demonstrates filtering and transforming in a single operation.

Code
func ExampleFilterMap() {
	// Create a map of names to ages
	ages := map[string]int{
		"Alice": 25,
		"Bob":   17,
		"Carol": 30,
		"Dave":  16,
	}

	// Keep only adults and transform to ID format
	adults := FilterMap(ages, func(name string, age int) fp.Option[tuples.Tuple2[string, string]] {
		if age >= 18 {
			id := fmt.Sprintf("ID_%s_%d", name, age)
			return fp.Some(tuples.Tuple2[string, string]{V1: name, V2: id})
		}
		return fp.None[tuples.Tuple2[string, string]]()
	})

	fmt.Printf("Adult count: %d\n", len(adults))
	// Output: Adult count: 2
}

⬆️ Back to Top

maps FilterMapTuple

ExampleFilterMapTuple demonstrates filtering and transforming using tuple returns.

Code
func ExampleFilterMapTuple() {
	// Create a map of scores
	scores := map[string]int{
		"Alice": 85,
		"Bob":   70,
		"Carol": 95,
		"Dave":  60,
	}

	// Keep high scores and convert to grade format
	grades := FilterMapTuple(scores, func(name string, score int) (string, string, bool) {
		if score >= 80 {
			var grade string
			if score >= 90 {
				grade = "A"
			} else {
				grade = "B"
			}
			return name, grade, true
		}
		return "", "", false
	})

	fmt.Printf("High performers: %d\n", len(grades))
	fmt.Printf("Alice's grade: %s\n", grades["Alice"])
	// Output:
	// High performers: 2
	// Alice's grade: B
}

⬆️ Back to Top

maps Fold

ExampleFold demonstrates folding a map with an initial value.

Code
func ExampleFold() {
	// Create a map of item prices
	prices := map[string]float64{
		"apple":  1.20,
		"banana": 0.80,
		"cherry": 2.50,
	}

	// Calculate total with initial tax
	totalWithTax := Fold(prices, func(acc float64, item string, price float64) float64 {
		return acc + price*1.1 // Add 10% tax
	}, 5.0) // Start with 5.0 base fee

	fmt.Printf("Total with tax: %.2f\n", totalWithTax)
	// Output:
	// Total with tax: 9.95
}

⬆️ Back to Top

maps Map

ExampleMap demonstrates transforming keys and values in a map.

Code
func ExampleMap() {
	// Create a map of numbers to their names
	numbers := map[int]string{
		1: "one",
		2: "two",
		3: "three",
	}

	// Transform to string keys and uppercase values
	transformed := Map(numbers, func(key int, value string) (string, string) {
		return fmt.Sprintf("num_%d", key), strings.ToUpper(value)
	})

	fmt.Println(transformed["num_1"])
	// Output: ONE
}

⬆️ Back to Top

maps Reduce

ExampleReduce demonstrates reducing a map to a single value.

Code
func ExampleReduce() {
	// Create a map of item quantities
	inventory := map[string]int{
		"apples":  10,
		"bananas": 5,
		"oranges": 8,
	}

	// Calculate total items (Reduce starts with zero value)
	total := Reduce(inventory, func(acc int, key string, value int) int {
		return acc + value
	})

	fmt.Printf("Total items: %d\n", total)
	// Output: Total items: 23
}

⬆️ Back to Top

maps Slice

ExampleSlice demonstrates converting a map to a slice.

Code
func ExampleSlice() {
	// Create a map of user data
	users := map[int]string{
		1: "Alice",
		2: "Bob",
		3: "Carol",
	}

	// Convert to slice of formatted strings
	userList := Slice(users, func(id int, name string) string {
		return fmt.Sprintf("ID:%d Name:%s", id, name)
	})

	fmt.Printf("Users count: %d\n", len(userList))
	// Note: map iteration order is not guaranteed
	// Output:
	// Users count: 3
}

⬆️ Back to Top

⬆️ Back to Top


🔢 Num

Numeric utilities including high-precision decimal operations.

Functions

num Abs

ExampleAbs demonstrates absolute value calculation

Code
func ExampleAbs() {
	// Calculate absolute values for different types
	intVal := -42
	floatVal := -3.14

	absInt := Abs(intVal)
	absFloat := Abs(floatVal)

	fmt.Printf("Original int: %d, Absolute: %d\n", intVal, absInt)
	fmt.Printf("Original float: %.2f, Absolute: %.2f\n", floatVal, absFloat)

	// Output:
	// Original int: -42, Absolute: 42
	// Original float: -3.14, Absolute: 3.14
}

⬆️ Back to Top

num Dec_Add

ExampleDec_Add demonstrates decimal addition

Code
func ExampleDec_Add() {
	// Perform decimal addition
	price1 := MustDecFromString("123.45")
	price2 := MustDecFromString("67.89")

	total := price1.Add(price2)

	fmt.Printf("Price 1: %s\n", price1.String())
	fmt.Printf("Price 2: %s\n", price2.String())
	fmt.Printf("Total: %s\n", total.String())

	// Output:
	// Price 1: 123.45
	// Price 2: 67.89
	// Total: 191.34
}

⬆️ Back to Top

num Dec_Compare

ExampleDec_Compare demonstrates decimal comparison

Code
func ExampleDec_Compare() {
	// Compare decimal values
	price1 := MustDecFromString("99.99")
	price2 := MustDecFromString("100.00")
	price3 := MustDecFromString("99.99")

	fmt.Printf("Price 1: %s\n", price1.String())
	fmt.Printf("Price 2: %s\n", price2.String())
	fmt.Printf("Price 3: %s\n", price3.String())

	fmt.Printf("Price 1 < Price 2: %t\n", price1.LessThan(price2))
	fmt.Printf("Price 1 > Price 2: %t\n", price1.GreaterThan(price2))
	fmt.Printf("Price 1 == Price 3: %t\n", price1.Equal(price3))
	fmt.Printf("Price 1 <= Price 2: %t\n", price1.LessThanOrEqual(price2))

	// Output:
	// Price 1: 99.99
	// Price 2: 100
	// Price 3: 99.99
	// Price 1 < Price 2: true
	// Price 1 > Price 2: false
	// Price 1 == Price 3: true
	// Price 1 <= Price 2: true
}

⬆️ Back to Top

num Dec_Div

ExampleDec_Div demonstrates decimal division

Code
func ExampleDec_Div() {
	// Calculate unit price
	totalCost := MustDecFromString("127.50")
	quantity := MustDecFromString("25")

	unitPrice := totalCost.Div(quantity)

	fmt.Printf("Total cost: %s\n", totalCost.String())
	fmt.Printf("Quantity: %s\n", quantity.String())
	fmt.Printf("Unit price: %s\n", unitPrice.String())

	// Output:
	// Total cost: 127.5
	// Quantity: 25
	// Unit price: 5.1
}

⬆️ Back to Top

num Dec_IsZero

ExampleDec_IsZero demonstrates zero checking

Code
func ExampleDec_IsZero() {
	// Check if decimal is zero
	zero := Zero
	nonZero := MustDecFromString("0.01")
	alsoZero := MustDecFromString("0.00")

	fmt.Printf("Zero value: %s, IsZero: %t\n", zero.String(), zero.IsZero())
	fmt.Printf("Non-zero value: %s, IsZero: %t\n", nonZero.String(), nonZero.IsZero())
	fmt.Printf("Also zero: %s, IsZero: %t\n", alsoZero.String(), alsoZero.IsZero())

	// Output:
	// Zero value: 0, IsZero: true
	// Non-zero value: 0.01, IsZero: false
	// Also zero: 0, IsZero: true
}

⬆️ Back to Top

num Dec_Mul

ExampleDec_Mul demonstrates decimal multiplication

Code
func ExampleDec_Mul() {
	// Calculate area
	length := MustDecFromString("12.5")
	width := MustDecFromString("8.4")

	area := length.Mul(width)

	fmt.Printf("Length: %s\n", length.String())
	fmt.Printf("Width: %s\n", width.String())
	fmt.Printf("Area: %s\n", area.String())

	// Output:
	// Length: 12.5
	// Width: 8.4
	// Area: 105
}

⬆️ Back to Top

num Dec_Percent

ExampleDec_Percent demonstrates percentage calculations

Code
func ExampleDec_Percent() {
	// Calculate percentage
	value := MustDecFromString("850.00")
	percentage := MustDecFromString("15") // 15%

	percentValue := value.ApplyPercent(percentage)
	finalValue := value.AddPercent(percentage)

	fmt.Printf("Original value: %s\n", value.String())
	fmt.Printf("Percentage: %s%%\n", percentage.String())
	fmt.Printf("Percentage amount: %s\n", percentValue.String())
	fmt.Printf("Final value (with percentage): %s\n", finalValue.String())

	// Output:
	// Original value: 850
	// Percentage: 15%
	// Percentage amount: 127.5
	// Final value (with percentage): 977.5
}

⬆️ Back to Top

num Dec_Round

ExampleDec_Round demonstrates decimal rounding

Code
func ExampleDec_Round() {
	// Round to different precision levels
	value := MustDecFromString("123.456789")

	rounded2 := value.RoundTo(2)
	rounded4 := value.RoundTo(4)
	rounded0 := value.RoundTo(0)

	fmt.Printf("Original: %s\n", value.String())
	fmt.Printf("Rounded to 2 decimals: %s\n", rounded2.String())
	fmt.Printf("Rounded to 4 decimals: %s\n", rounded4.String())
	fmt.Printf("Rounded to 0 decimals: %s\n", rounded0.String())

	// Output:
	// Original: 123.456789
	// Rounded to 2 decimals: 123.46
	// Rounded to 4 decimals: 123.4568
	// Rounded to 0 decimals: 123
}

⬆️ Back to Top

num Dec_Sub

ExampleDec_Sub demonstrates decimal subtraction

Code
func ExampleDec_Sub() {
	// Perform decimal subtraction
	balance := MustDecFromString("1000.00")
	withdrawal := MustDecFromString("750.25")

	remaining := balance.Sub(withdrawal)

	fmt.Printf("Initial balance: %s\n", balance.String())
	fmt.Printf("Withdrawal: %s\n", withdrawal.String())
	fmt.Printf("Remaining: %s\n", remaining.String())

	// Output:
	// Initial balance: 1000
	// Withdrawal: 750.25
	// Remaining: 249.75
}

⬆️ Back to Top

num MustDecFromAny

ExampleMustDecFromAny demonstrates creating a decimal from any supported type

Code
func ExampleMustDecFromAny() {
	// Create decimals from different types
	fromInt := MustDecFromAny(100)
	fromFloat := MustDecFromAny(3.14159)
	fromString := MustDecFromAny("42.42")

	fmt.Printf("From int: %s\n", fromInt.String())
	fmt.Printf("From float: %s\n", fromFloat.String())
	fmt.Printf("From string: %s\n", fromString.String())

	// Output:
	// From int: 100
	// From float: 3.14159
	// From string: 42.42
}

⬆️ Back to Top

num MustDecFromString

ExampleMustDecFromString demonstrates creating a decimal from a string (panics on error)

Code
func ExampleMustDecFromString() {
	// Create decimal from valid string
	price := MustDecFromString("999.99")

	fmt.Printf("Price: %s\n", price.String())
	if f, ok := price.Float64(); ok {
		fmt.Printf("As float: %.2f\n", f)
	}

	// Output:
	// Price: 999.99
}

⬆️ Back to Top

num NewDecFromFloat

ExampleNewDecFromFloat demonstrates creating a decimal from a float

Code
func ExampleNewDecFromFloat() {
	// Create decimal from float
	temperature := NewDecFromFloat(36.5)

	fmt.Printf("Temperature: %s\n", temperature.String())
	if f, ok := temperature.Float64(); ok {
		fmt.Printf("As float: %.1f\n", f)
	}
	fmt.Printf("Number of decimals: %d\n", temperature.NumberOfDecimals())

	// Output:
	// Temperature: 36.5
	// As float: 36.5
	// Number of decimals: 1
}

⬆️ Back to Top

num NewDecFromInt

ExampleNewDecFromInt demonstrates creating a decimal from an integer

Code
func ExampleNewDecFromInt() {
	// Create decimal from integer
	quantity := NewDecFromInt(42)

	fmt.Printf("Quantity: %s\n", quantity.String())
	fmt.Printf("As int: %d\n", quantity.IntPart())
	fmt.Printf("Is zero: %t\n", quantity.IsZero())

	// Output:
	// Quantity: 42
	// As int: 42
	// Is zero: false
}

⬆️ Back to Top

num NewDecFromString

ExampleNewDecFromString demonstrates creating a decimal from a string

Code
func ExampleNewDecFromString() {
	// Create decimal from string
	price, err := NewDecFromString("123.456")
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Price: %s\n", price.String())
	fmt.Printf("Is set: %t\n", price.Isset())

	// Try with invalid string
	_, err = NewDecFromString("invalid")
	fmt.Printf("Invalid string error: %v\n", err != nil)

	// Output:
	// Price: 123.456
	// Is set: true
	// Invalid string error: true
}

⬆️ Back to Top

⬆️ Back to Top


⛓️ Slices

Package slices provides a comprehensive set of generic utility functions for working with slices. It offers a functional approach to common slice operations such as transforming, filtering, searching, and manipulating elements in a type-safe manner.

Functions

slices All

ExampleAll demonstrates checking if all elements satisfy a condition.

Code
func ExampleAll() {
	// Create a slice of positive numbers
	numbers := []int{1, 2, 3, 4, 5}

	// Check if all numbers are positive
	allPositive := All(numbers, func(n int) bool {
		return n > 0
	})

	// Check if all numbers are even
	allEven := All(numbers, func(n int) bool {
		return n%2 == 0
	})

	fmt.Printf("All positive: %t\n", allPositive)
	fmt.Printf("All even: %t\n", allEven)
	// Output:
	// All positive: true
	// All even: false
}

⬆️ Back to Top

slices Contains

ExampleContains demonstrates checking if any element satisfies a condition.

Code
func ExampleContains() {
	// Create a slice of numbers
	numbers := []int{1, 2, 3, 4, 5}

	// Check if any number is greater than 3
	hasLarge := Contains(numbers, func(n int) bool {
		return n > 3
	})

	// Check if any number is negative
	hasNegative := Contains(numbers, func(n int) bool {
		return n < 0
	})

	fmt.Printf("Has number > 3: %t\n", hasLarge)
	fmt.Printf("Has negative: %t\n", hasNegative)
	// Output:
	// Has number > 3: true
	// Has negative: false
}

⬆️ Back to Top

slices Filter

ExampleFilter demonstrates filtering a slice to keep only elements that satisfy a condition.

Code
func ExampleFilter() {
	// Create a slice of numbers
	numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	// Filter to keep only even numbers
	evenNumbers := Filter(numbers, func(n int) bool {
		return n%2 == 0
	})

	fmt.Println(evenNumbers)
	// Output: [2 4 6 8 10]
}

⬆️ Back to Top

slices FilterMap

ExampleFilterMap demonstrates filtering and transforming in a single operation.

Code
func ExampleFilterMap() {
	// Create a slice of numbers
	numbers := []int{1, 2, 3, 4, 5, 6}

	// Keep only even numbers and square them
	evenSquares := FilterMap(numbers, func(n int) fp.Option[int] {
		if n%2 == 0 {
			return fp.Some(n * n)
		}
		return fp.None[int]()
	})

	fmt.Println(evenSquares)
	// Output: [4 16 36]
}

⬆️ Back to Top

slices Find

ExampleFind demonstrates finding the first element that matches a condition.

Code
func ExampleFind() {
	// Create a slice of names
	names := []string{"Alice", "Bob", "Charlie", "David"}

	// Find the first name that starts with 'C'
	result, found := Find(names, func(name string) bool {
		return len(name) > 0 && name[0] == 'C'
	})

	fmt.Printf("Found: %t, Name: %s\n", found, result)
	// Output: Found: true, Name: Charlie
}

⬆️ Back to Top

slices Fold

ExampleFold demonstrates folding a slice with an initial value.

Code
func ExampleFold() {
	// Create a slice of strings
	words := []string{"Hello", "World", "from", "Go"}

	// Join with custom separator and prefix
	result := Fold(words, func(acc, word string) string {
		if acc == "" {
			return "Greeting: " + word
		}
		return acc + " " + word
	}, "")

	fmt.Printf("Result: %s\n", result)
	// Output:
	// Result: Greeting: Hello World from Go
}

⬆️ Back to Top

slices Map

ExampleMap demonstrates transforming elements in a slice.

Code
func ExampleMap() {
	// Create a slice of numbers
	numbers := []int{1, 2, 3, 4, 5}

	// Transform each number by squaring it
	squares := Map(numbers, func(n int) int {
		return n * n
	})

	fmt.Println(squares)
	// Output: [1 4 9 16 25]
}

⬆️ Back to Top

slices Reduce

ExampleReduce demonstrates combining all elements into a single value.

Code
func ExampleReduce() {
	// Create a slice of numbers
	numbers := []int{1, 2, 3, 4, 5}

	// Sum all numbers
	sum := Reduce[int, int](numbers, func(acc, curr int) int {
		return acc + curr
	})

	fmt.Println(sum)
	// Output: 15
}

⬆️ Back to Top

slices Some

ExampleSome demonstrates checking if some elements satisfy a condition.

Code
func ExampleSome() {
	// Create a slice of words
	words := []string{"hello", "world", "go", "programming"}

	// Check if some words are short (< 4 characters)
	hasShort := Some(words, func(word string) bool {
		return len(word) < 4
	})

	fmt.Printf("Has short words: %t\n", hasShort)
	// Output:
	// Has short words: true
}

⬆️ Back to Top

slices ToMap

ExampleToMap demonstrates converting a slice to a map using a key function.

Code
func ExampleToMap() {
	// Create a slice of words
	words := []string{"apple", "banana", "cherry"}

	// Convert to map with first letter as key
	wordMap := ToMap(words, func(word string) rune {
		return rune(word[0])
	})

	fmt.Printf("'a' word: %s\n", wordMap['a'])
	fmt.Printf("'b' word: %s\n", wordMap['b'])
	// Output:
	// 'a' word: apple
	// 'b' word: banana
}

⬆️ Back to Top

⬆️ Back to Top


🌊 Streams

Package streams provides interfaces and types for reading and writing streams of data.

Functions

streams Batch

ExampleBatch demonstrates grouping stream elements into batches.

Code
func ExampleBatch() {
	// Create a stream from a slice of integers
	data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	stream := MemReader(data, nil)

	// Group into batches of 3
	batchStream := Batch(stream, 3)

	// Collect the results
	result, _ := Consume(batchStream)
	for i, batch := range result {
		fmt.Printf("Batch %d: %v\n", i+1, batch)
	}
	// Output:
	// Batch 1: [1 2 3]
	// Batch 2: [4 5 6]
	// Batch 3: [7 8 9]
	// Batch 4: [10]
}

⬆️ Back to Top

streams CSV

ExampleCSV demonstrates reading CSV data from a string.

Code
func ExampleCSV() {
	// Create a CSV reader from a string
	csvData := "name,age,city\nAlice,25,NYC\nBob,30,LA\nCharlie,35,Chicago"
	reader := io.NopCloser(strings.NewReader(csvData))

	// Create a CSV stream directly
	csvStream, _ := CSV[[]string](
		WithCSVReader(reader),
		WithCSVSeparator(","),
	)

	// Collect the results
	result, _ := Consume(csvStream)
	for i, row := range result {
		fmt.Printf("Row %d: %v\n", i+1, row)
	}
	// Output:
	// Row 1: [name age city]
	// Row 2: [Alice 25 NYC]
	// Row 3: [Bob 30 LA]
	// Row 4: [Charlie 35 Chicago]
}

⬆️ Back to Top

streams CSVTransform

ExampleCSVTransform demonstrates converting a stream to CSV format.

Code
func ExampleCSVTransform() {
	// Create a stream of employees
	employees := []Employee{
		{ID: 1, Name: "Alice Johnson", Department: "Engineering", Salary: 75000.00},
		{ID: 2, Name: "Bob Smith", Department: "Marketing", Salary: 65000.00},
		{ID: 3, Name: "Charlie Brown", Department: "Engineering", Salary: 80000.00},
	}
	stream := MemReader(employees, nil)

	// Transform to CSV with comma separator
	transform := CSVTransform(stream, CSVSeparatorComma)
	transform.WriteTo(os.Stdout)

	// Output:
	// ID,Name,Department,Salary
	// 1,Alice Johnson,Engineering,75000.00
	// 2,Bob Smith,Marketing,65000.00
	// 3,Charlie Brown,Engineering,80000.00
}

⬆️ Back to Top

streams CSVTransform_tabSeparated

ExampleCSVTransform_tabSeparated demonstrates CSV with tab separator.

Code
func ExampleCSVTransform_tabSeparated() {

	// Create a stream of products
	products := []ProductCSV{
		{SKU: "LAPTOP-001", Name: "Gaming Laptop", Price: 1299.99},
		{SKU: "MOUSE-002", Name: "Wireless Mouse", Price: 49.99},
		{SKU: "KEYBOARD-003", Name: "Mechanical Keyboard", Price: 129.99},
	}
	stream := MemReader(products, nil)

	// Transform to CSV with tab separator
	transform := CSVTransform(stream, CSVSeparatorTab)
	transform.WriteTo(os.Stdout)

	// Output:
	// SKU	Product Name	Price
	// LAPTOP-001	Gaming Laptop	$1299.99
	// MOUSE-002	Wireless Mouse	$49.99
	// KEYBOARD-003	Mechanical Keyboard	$129.99
}

⬆️ Back to Top

streams ConsumeErrSkip

ExampleConsumeErrSkip demonstrates consuming a stream while skipping errors.

Code
func ExampleConsumeErrSkip() {
	// Create a filter stream that may produce errors
	reader := strings.NewReader("1\n2\ninvalid\n4\n5")
	numbersStream := Lines(reader)

	// Create a filter that converts strings to numbers (may fail)
	filterStream := FilterMap(numbersStream, func(s string) (int, bool) {
		// Simulate conversion that might fail
		if s == "invalid" {
			return 0, false // This will be skipped
		}
		// Simple conversion for demonstration
		switch s {
		case "1":
			return 1, true
		case "2":
			return 2, true
		case "4":
			return 4, true
		case "5":
			return 5, true
		default:
			return 0, false
		}
	})

	// Consume all valid numbers, skipping errors
	numbers := ConsumeErrSkip(filterStream)

	fmt.Printf("Valid numbers: %v\n", numbers)

	// Output:
	// Valid numbers: [1 2 4 5]
}

⬆️ Back to Top

streams DB

ExampleDB demonstrates how to use DB with database rows.

Code
func ExampleDB() {
	// Mock data that simulates database rows
	mockData := &mockRows{
		data: [][]any{
			{1, "Alice"},
			{2, "Bob"},
			{3, "Charlie"},
		},
	}

	// Create a stream with a scan function
	stream := DB(mockData, func(rows DBRows, user *User) error {
		return rows.Scan(&user.ID, &user.Name)
	})

	// Iterate through the stream
	for stream.Next() {
		user := stream.Data()
		fmt.Printf("User ID: %d, Name: %s\n", user.ID, user.Name)
	}

	// Check for errors
	if err := stream.Err(); err != nil {
		log.Printf("Error during streaming: %v", err)
	}

	// Output:
	// User ID: 1, Name: Alice
	// User ID: 2, Name: Bob
	// User ID: 3, Name: Charlie
}

⬆️ Back to Top

streams Filter

ExampleFilter demonstrates filtering a stream of integers to keep only even numbers.

Code
func ExampleFilter() {
	// Create a stream from a slice of integers
	data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	stream := MemReader(data, nil)

	// Filter to keep only even numbers
	evenStream := Filter(stream, func(n int) bool {
		return n%2 == 0
	})

	// Collect the results
	result, _ := Consume(evenStream)
	fmt.Println(result)
	// Output: [2 4 6 8 10]
}

⬆️ Back to Top

streams FilterMap

ExampleFilterMap demonstrates filtering and transforming in a single operation.

Code
func ExampleFilterMap() {
	// Create a stream from a slice of integers
	data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	stream := MemReader(data, nil)

	// Filter even numbers and convert them to strings
	evenStrings := FilterMap(stream, func(n int) (string, bool) {
		if n%2 == 0 {
			return strconv.Itoa(n), true
		}
		return "", false
	})

	// Collect the results
	result, _ := Consume(evenStrings)
	fmt.Println(result)
	// Output: [2 4 6 8 10]
}

⬆️ Back to Top

streams Flatten

ExampleFlatten demonstrates flattening a stream of slices.

Code
func ExampleFlatten() {
	// Create a stream from a slice of slices
	data := [][]int{{1, 2}, {3, 4, 5}, {6}, {7, 8, 9}}
	stream := MemReader(data, nil)

	// Flatten the slices
	flattened := Flatten(stream)

	// Collect the results
	result, _ := Consume(flattened)
	fmt.Println(result)
	// Output: [1 2 3 4 5 6 7 8 9]
}

⬆️ Back to Top

streams Group

ExampleGroup demonstrates grouping consecutive items with the same key.

Code
func ExampleGroup() {
	// Create a stream from a slice of strings
	data := []string{"apple", "apricot", "banana", "blueberry", "cherry", "coconut"}
	stream := MemReader(data, nil)

	// Group by first letter
	Grouped := Group(stream, func(s string) rune {
		return rune(s[0])
	})

	// Collect the results
	result, _ := Consume(Grouped)
	for _, group := range result {
		fmt.Printf("Group: %v\n", group)
	}
	// Output:
	// Group: [apple apricot]
	// Group: [banana blueberry]
	// Group: [cherry coconut]
}

⬆️ Back to Top

streams JSON

ExampleJSON demonstrates reading JSON data line by line.

Code
func ExampleJSON() {
		// Create JSON-lines data (each line is a separate JSON object)
		jsonData := `{"name":"Alice","age":25}
	{"name":"Bob","age":30}
	{"name":"Charlie","age":35}`

		reader := strings.NewReader(jsonData)

		// Create a JSON stream for a simple struct
		type Person struct {
			Name string `json:"name"`
			Age  int    `json:"age"`
		}

		jsonStream := JSON[Person](io.NopCloser(reader))

		// Collect the results
		result, _ := Consume(jsonStream)
		for _, person := range result {
			fmt.Printf("Person: %s, Age: %d\n", person.Name, person.Age)
		}
		// Output:
		// Person: Alice, Age: 25
		// Person: Bob, Age: 30
		// Person: Charlie, Age: 35
}

⬆️ Back to Top

streams JSONEachRowTransform

ExampleJSONEachRowTransform demonstrates converting a stream to JSON lines format.

Code
func ExampleJSONEachRowTransform() {
	// Define a simple structure for demonstration
	type LogEntry struct {
		Timestamp string `json:"timestamp"`
		Level     string `json:"level"`
		Message   string `json:"message"`
	}

	// Create a stream of log entries
	logs := []LogEntry{
		{Timestamp: "2025-06-28T10:00:00Z", Level: "INFO", Message: "Application started"},
		{Timestamp: "2025-06-28T10:01:00Z", Level: "WARN", Message: "High memory usage detected"},
		{Timestamp: "2025-06-28T10:02:00Z", Level: "ERROR", Message: "Database connection failed"},
	}
	stream := MemReader(logs, nil)

	// Transform to JSON lines format and write to stdout
	transform := JSONEachRowTransform(stream)
	transform.WriteTo(os.Stdout)

	// Output:
	// {"timestamp":"2025-06-28T10:00:00Z","level":"INFO","message":"Application started"}
	// {"timestamp":"2025-06-28T10:01:00Z","level":"WARN","message":"High memory usage detected"}
	// {"timestamp":"2025-06-28T10:02:00Z","level":"ERROR","message":"Database connection failed"}
}

⬆️ Back to Top

streams JSONTransform

ExampleJSONTransform demonstrates converting a stream to JSON array format.

Code
func ExampleJSONTransform() {
	// Define a simple structure for demonstration
	type Person struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	}

	// Create a stream from a slice of persons
	people := []Person{
		{ID: 1, Name: "Alice"},
		{ID: 2, Name: "Bob"},
		{ID: 3, Name: "Charlie"},
	}
	stream := MemReader(people, nil)

	// Transform to JSON and write to stdout
	transform := JSONTransform(stream)
	transform.WriteTo(os.Stdout)

	// Output:
	// [{"id":1,"name":"Alice"},{"id":2,"name":"Bob"},{"id":3,"name":"Charlie"}]
}

⬆️ Back to Top

streams Lines

ExampleLines demonstrates reading lines from a string.

Code
func ExampleLines() {
	// Create a reader from a multiline string
	text := "line1\nline2\nline3\n"
	reader := strings.NewReader(text)

	// Create a lines stream
	lineStream := Lines(reader)

	// Collect the results
	result, _ := Consume(lineStream)
	fmt.Println(result)
	// Output: [line1 line2 line3]
}

⬆️ Back to Top

streams Map

ExampleMap demonstrates transforming elements in a stream.

Code
func ExampleMap() {
	// Create a stream from a slice of integers
	data := []int{1, 2, 3, 4, 5}
	stream := MemReader(data, nil)

	// Transform integers to their string representation
	stringStream := Map(stream, func(n int) string {
		return fmt.Sprintf("number_%d", n)
	})

	// Collect the results
	result, _ := Consume(stringStream)
	fmt.Println(result)
	// Output: [number_1 number_2 number_3 number_4 number_5]
}

⬆️ Back to Top

streams MemWriter

ExampleMemWriter demonstrates writing items to memory.

Code
func ExampleMemWriter() {
	// Create a memory writer for strings
	writer := MemWriter[string]()

	// Write some items
	items := []string{"hello", "world", "from", "memory"}
	for _, item := range items {
		writer.Write(item)
	}

	// Get all items
	result := writer.Items()

	fmt.Printf("Items written: %d\n", len(result))
	fmt.Printf("Items: %v\n", result)
	// Output:
	// Items written: 4
	// Items: [hello world from memory]
}

⬆️ Back to Top

streams Multicast

ExampleMulticast demonstrates broadcasting a stream to multiple destinations.

Code
func ExampleMulticast() {
	// Create a stream of numbers
	reader := strings.NewReader("1\n2\n3\n4\n5")
	source := Lines(reader)

	// Create two memory writers to collect data separately
	dest1 := MemWriter[string]()
	dest2 := MemWriter[string]()

	// Multicast the stream to both destinations
	counts, err := Multicast(source, dest1, dest2)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Written to dest1: %d items\n", counts[0])
	fmt.Printf("Written to dest2: %d items\n", counts[1])
	fmt.Printf("Dest1 data: %v\n", dest1.Items())
	fmt.Printf("Dest2 data: %v\n", dest2.Items())

	// Output:
	// Written to dest1: 5 items
	// Written to dest2: 5 items
	// Dest1 data: [1 2 3 4 5]
	// Dest2 data: [1 2 3 4 5]
}

⬆️ Back to Top

streams Pipe

ExamplePipe demonstrates piping data from one stream to another.

Code
func ExamplePipe() {
	// Create a source stream
	data := []string{"hello", "world", "from", "streams"}
	source := MemReader(data, nil)

	// Create a destination
	dest := MemWriter[string]()

	// Pipe data from source to destination
	bytesWritten, _ := Pipe(source, dest)

	fmt.Printf("Items written: %d\n", bytesWritten)
	fmt.Printf("Items: %v\n", dest.Items())
	// Output:
	// Items written: 4
	// Items: [hello world from streams]
}

⬆️ Back to Top

streams PipeCSV

ExamplePipeCSV demonstrates using the PipeCSV convenience function.

Code
func ExamplePipeCSV() {
	// Create a stream of employees
	employees := []Employee{
		{ID: 101, Name: "Diana Prince", Department: "Legal", Salary: 90000.00},
		{ID: 102, Name: "Clark Kent", Department: "Journalism", Salary: 55000.00},
	}
	stream := MemReader(employees, nil)

	// Use PipeCSV to write directly to stdout with comma separator
	rowsWritten, err := PipeCSV(stream, os.Stdout, CSVSeparatorComma)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("Rows written: %d\n", rowsWritten)

	// Output:
	// ID,Name,Department,Salary
	// 101,Diana Prince,Legal,90000.00
	// 102,Clark Kent,Journalism,55000.00
	// Rows written: 3
}

⬆️ Back to Top

streams PipeJSON

ExamplePipeJSON demonstrates using the PipeJSON convenience function.

Code
func ExamplePipeJSON() {
	// Define a simple structure
	type Product struct {
		ID    int     `json:"id"`
		Name  string  `json:"name"`
		Price float64 `json:"price"`
	}

	// Create a stream of products
	products := []Product{
		{ID: 1, Name: "Laptop", Price: 999.99},
		{ID: 2, Name: "Mouse", Price: 29.99},
	}
	stream := MemReader(products, nil)

	// Use PipeJSON to write directly to stdout
	bytesWritten, err := PipeJSON(stream, os.Stdout)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("\nBytes written: %d\n", bytesWritten)

	// Output:
	// [{"id":1,"name":"Laptop","price":999.99},{"id":2,"name":"Mouse","price":29.99}]
	// Bytes written: 79
}

⬆️ Back to Top

streams PipeJSONEachRow

ExamplePipeJSONEachRow demonstrates using the PipeJSONEachRow convenience function.

Code
func ExamplePipeJSONEachRow() {
	// Define a simple metric structure
	type Metric struct {
		Name  string  `json:"name"`
		Value float64 `json:"value"`
		Unit  string  `json:"unit"`
	}

	// Create a stream of metrics
	metrics := []Metric{
		{Name: "cpu_usage", Value: 85.5, Unit: "percent"},
		{Name: "memory_usage", Value: 1024, Unit: "MB"},
		{Name: "disk_usage", Value: 75.2, Unit: "percent"},
	}
	stream := MemReader(metrics, nil)

	// Use PipeJSONEachRow to write to stdout
	bytesWritten, err := PipeJSONEachRow(stream, os.Stdout)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("Bytes written: %d\n", bytesWritten)

	// Output:
	// {"name":"cpu_usage","value":85.5,"unit":"percent"}
	// {"name":"memory_usage","value":1024,"unit":"MB"}
	// {"name":"disk_usage","value":75.2,"unit":"percent"}
	// Bytes written: 152
}

⬆️ Back to Top

streams Reader

ExampleReader demonstrates reading byte chunks from an io.Reader.

Code
func ExampleReader() {
	// Create data to read
	data := "line1\nline2\nline3\n"
	reader := strings.NewReader(data)

	// Create a byte stream
	stream := Reader(reader)

	// Read all chunks
	var chunks []string
	for stream.Next() {
		chunks = append(chunks, string(stream.Data()))
	}

	fmt.Printf("Chunks: %d\n", len(chunks))
	fmt.Printf("First chunk: %q\n", chunks[0])
	// Output:
	// Chunks: 3
	// First chunk: "line1\n"
}

⬆️ Back to Top

streams Reduce

ExampleReduce demonstrates using Reduce to sum numbers from a stream.

Code
func ExampleReduce() {
	// Create a stream of numbers from strings
	reader := strings.NewReader("10\n20\n30\n40\n50")
	lines := Lines(reader)

	// Convert strings to numbers and sum them
	sum, _ := Reduce(Map(lines, func(s string) int {
		n, _ := strconv.Atoi(s)
		return n
	}), func(acc, n int) int {
		return acc + n
	}, 0)

	fmt.Printf("Sum: %d\n", sum)

	// Output:
	// Sum: 150
}

⬆️ Back to Top

streams ReduceMap

ExampleReduceMap demonstrates reducing a stream to a map with aggregated values.

Code
func ExampleReduceMap() {
	// Create a stream of words
	reader := strings.NewReader("apple\nbanana\napple\ncherry\nbanana\napple")
	stream := Lines(reader)

	// Count occurrences of each word
	counts, _ := ReduceMap(stream, func(acc map[string]int, word string) map[string]int {
		acc[word]++
		return acc
	})

	fmt.Printf("apple: %d\n", counts["apple"])
	fmt.Printf("banana: %d\n", counts["banana"])
	fmt.Printf("cherry: %d\n", counts["cherry"])

	// Output:
	// apple: 3
	// banana: 2
	// cherry: 1
}

⬆️ Back to Top

streams ReduceSlice

ExampleReduceSlice demonstrates collecting filtered items from a stream.

Code
func ExampleReduceSlice() {
	// Create a stream of words
	reader := strings.NewReader("cat\ndog\nelephant\nant\nbutterfly\nbird")
	stream := Lines(reader)

	// Collect only words longer than 3 characters
	longWords, _ := ReduceSlice(stream, func(acc []string, word string) []string {
		if len(word) > 3 {
			return append(acc, word)
		}
		return acc
	})

	fmt.Printf("Long words: %v\n", longWords)

	// Output:
	// Long words: [elephant butterfly bird]
}

⬆️ Back to Top

streams WriteAll

ExampleWriteAll demonstrates writing a slice to a stream.

Code
func ExampleWriteAll() {
	// Create data to write
	data := []string{"hello", "world", "streams"}

	// Create a memory writer
	writer := MemWriter[string]()

	// Write all data
	bytesWritten, err := WriteAll(writer, data)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Bytes written: %d\n", bytesWritten)
	fmt.Printf("Items: %v\n", writer.Items())
	// Output:
	// Bytes written: 3
	// Items: [hello world streams]
}

⬆️ Back to Top

⬆️ Back to Top


🔞 Zero

Zero-value utilities and string manipulation functions.

Functions

zero B2S

ExampleB2S demonstrates converting []byte to string without memory allocation

Code
func ExampleB2S() {
	// Convert []byte to string using zero-allocation conversion
	b := []byte("Hello, Gophers!")
	s := B2S(b)

	fmt.Printf("Original bytes: %v\n", b)
	fmt.Printf("Converted to string: %s\n", s)
	fmt.Printf("Length: %d\n", len(s))
	fmt.Printf(
		"Same underlying data: %t\n",
		uintptr(unsafe.Pointer(&b[0])) == uintptr(unsafe.Pointer(unsafe.StringData(s))),
	)

	// Output:
	// Original bytes: [72 101 108 108 111 44 32 71 111 112 104 101 114 115 33]
	// Converted to string: Hello, Gophers!
	// Length: 15
	// Same underlying data: true
}

⬆️ Back to Top

zero S2B

ExampleS2B demonstrates converting a string to []byte without memory allocation

Code
func ExampleS2B() {
	// Convert string to []byte using zero-allocation conversion
	s := "Hello, World!"
	b := S2B(s)

	fmt.Printf("Original string: %s\n", s)
	fmt.Printf("Converted to bytes: %v\n", b)
	fmt.Printf("Bytes as string: %s\n", string(b))
	fmt.Printf(
		"Same underlying data: %t\n",
		uintptr(unsafe.Pointer(unsafe.StringData(s))) == uintptr(unsafe.Pointer(&b[0])),
	)

	// Output:
	// Original string: Hello, World!
	// Converted to bytes: [72 101 108 108 111 44 32 87 111 114 108 100 33]
	// Bytes as string: Hello, World!
	// Same underlying data: true
}

⬆️ Back to Top

⬆️ Back to Top


FAQs

Package last updated on 18 Jul 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts