common

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2025 License: MIT Imports: 2 Imported by: 0

README

Common

Go Reference codecov

Common provides shared utilities for protomcp.org projects.

Overview

The common package serves as a foundation for other protomcp.org repositories, providing reusable components for error handling and general utilities that are shared between nanorpc, protomcp, and related projects.

Features

  • Shared Types: Reusable data structures and interfaces
  • Error Handling: Consistent error patterns across projects
  • Utility Functions: General-purpose helper functions like slice tools
  • Testing Support: Integrates with darvaza.org/core for test utilities

Slice Utilities

The common package provides generic slice manipulation functions designed to prevent memory leaks when working with slices containing pointers or reference types.

ClearSlice

Zeros all elements in a slice (including unused capacity) and returns an empty slice that reuses the same underlying array:

// Example: Reusing a slice after clearing
responses := []Response{
    {ID: 1, Data: largeData1},
    {ID: 2, Data: largeData2},
    {ID: 3, Data: largeData3},
}

// Clear and reuse - all elements zeroed, length is 0, capacity preserved
responses = common.ClearSlice(responses)

// The slice can be reused without allocation
responses = append(responses, newResponse)

This is particularly useful for:

  • Connection pools that reuse response slices
  • Buffer management in high-throughput systems
  • Preventing memory leaks from references in unused capacity
ClearAndNilSlice

Zeros all elements in a slice (including unused capacity) and returns nil, completely releasing the underlying array for garbage collection:

// Example: Releasing memory completely
type Handler struct {
    buffer     []byte
    clients    []*Client
    responses  []Response
}

func (h *Handler) Close() {
    // Clear and release all memory
    h.buffer = common.ClearAndNilSlice(h.buffer)
    h.clients = common.ClearAndNilSlice(h.clients)
    h.responses = common.ClearAndNilSlice(h.responses)
}

Use cases:

  • Clean-up in Close() or shutdown methods
  • Releasing large temporary buffers
  • Ensuring complete memory release for GC
Memory Leak Prevention

These utilities solve a common Go pitfall where slicing doesn't clear elements in the underlying array:

// Problem: Memory leak with regular slicing
handlers := []*Handler{h1, h2, h3, h4, h5}
handlers = handlers[:2]  // h3, h4, h5 still referenced in underlying array!

// Solution: Use ClearSlice
handlers := []*Handler{h1, h2, h3, h4, h5}
handlers = common.ClearSlice(handlers)  // All pointers nil, no leaks
handlers = append(handlers, h1, h2)     // Safely reuse

String Building with LazyBuffer

LazyBuffer is a convenience wrapper around strings.Builder that eliminates error handling overhead. Unlike strings.Builder, LazyBuffer methods don't return errors, making code cleaner and more readable.

LazyBuffer Features
  • No error handling required: Methods handle errors internally
  • Method chaining: All write methods return the buffer for chaining
  • Nil-safe: All methods safely handle nil receivers
  • Empty string filtering: WriteString ignores empty strings
  • Full compatibility: Built on strings.Builder for performance
Basic Usage
var buf common.LazyBuffer

// Simple string building
buf.WriteString("Hello", " ", "world")
fmt.Println(buf.String()) // "Hello world"

// Method chaining
output := buf.WriteString("func ").
    WriteString(name).
    WriteRunes('(').
    Printf("ctx %s", contextType).
    WriteRunes(')').
    String()
Code Generation Example

LazyBuffer is particularly useful for code generation:

func generateMethod(name string, params []Param) string {
    var buf common.LazyBuffer

    buf.WriteString("func (s *Service) ").
        WriteString(name).
        WriteRunes('(')

    for i, p := range params {
        if i > 0 {
            buf.WriteString(", ")
        }
        buf.Printf("%s %s", p.Name, p.Type)
    }

    return buf.WriteString(") error {\n").
        WriteString("\t// TODO: implement\n").
        WriteString("\treturn nil\n").
        WriteRunes('}').
        String()
}
Template Rendering

Building complex strings without error handling clutter:

func renderHTML(title string, items []Item) string {
    var buf common.LazyBuffer

    buf.Printf("<html>\n<head><title>%s</title></head>\n<body>\n", title).
        WriteString("<ul>\n")

    for _, item := range items {
        buf.Printf("  <li>%s: %s</li>\n", item.Name, item.Description)
    }

    return buf.WriteString("</ul>\n</body>\n</html>").String()
}
Performance

LazyBuffer has minimal overhead compared to strings.Builder:

// LazyBuffer - clean, chainable code
var buf common.LazyBuffer
result := buf.WriteString("Hello").
    WriteRunes(' ').
    WriteString("World").
    String()

// strings.Builder - requires error handling
var sb strings.Builder
_, _ = sb.WriteString("Hello")
_, _ = sb.WriteRune(' ')
_, _ = sb.WriteString("World")
result := sb.String()

The convenience comes with negligible performance cost, making it ideal for cases where code clarity is more important than micro-optimizations.

Usage

This package is designed to be imported by other protomcp.org projects:

import (
    "protomcp.org/common"
)

Development

For development guidelines, please refer to AGENT.md.

License

See LICENCE.txt for licensing information.

Documentation

Overview

Package common provides shared utilities and helpers for protomcp.org projects.

The common package serves as a foundation library for the protomcp.org ecosystem, preventing code duplication across repositories like nanorpc and protomcp. It provides general-purpose utilities, test helpers, and patterns that are shared across multiple projects.

Slice Utilities

The package provides generic slice manipulation functions that help prevent memory leaks when working with slices containing pointers or reference types:

  • ClearSlice: Zeros all elements including unused capacity and returns an empty slice that reuses the underlying array
  • ClearAndNilSlice: Zeros all elements and returns nil, releasing the underlying array for garbage collection

These utilities are particularly useful when truncating slices that contain pointers, interfaces, or other reference types, as they ensure no references remain in the unused capacity that could prevent garbage collection.

Example usage:

// Prevent memory leaks when clearing a slice of pointers
handlers := []*Handler{h1, h2, h3}
handlers = ClearSlice(handlers)  // All pointers nil, slice empty but reusable

// Or completely release the underlying array
responses := []Response{{...}, {...}, {...}}
responses = ClearAndNilSlice(responses)  // All cleared, slice is nil

String Building

LazyBuffer provides a convenient wrapper around strings.Builder that eliminates the need for error handling. It's particularly useful for code generation, template rendering, or any scenario where you're building strings incrementally:

  • WriteString: Appends strings, ignoring empty ones
  • WriteRunes: Appends individual runes
  • Printf: Appends formatted strings
  • All methods support chaining and nil-safety

Example usage:

var buf LazyBuffer
output := buf.WriteString("func ").
	WriteString(name).
	WriteRunes('(').
	Printf("ctx %s", contextType).
	WriteRunes(')').
	String()

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClearAndNilSlice

func ClearAndNilSlice[T any](s []T) []T

ClearAndNilSlice zeros all elements in a slice (including unused capacity) and returns nil. This completely releases the underlying array for garbage collection.

Example:

responses := []Response{{...}, {...}, {...}}
responses = ClearAndNilSlice(responses)  // All elements zeroed, slice is nil

func ClearSlice

func ClearSlice[T any](s []T) []T

ClearSlice zeros all elements in a slice (including unused capacity) and returns an empty slice that reuses the same underlying array. This prevents memory leaks when truncating slices containing pointers or other reference types.

Example:

responses := []Response{{...}, {...}, {...}}
responses = ClearSlice(responses)  // All elements zeroed, length is 0

Types

type LazyBuffer

type LazyBuffer strings.Builder

LazyBuffer is a wrapper around strings.Builder that provides convenience methods for building output strings without requiring error handling. Unlike strings.Builder, LazyBuffer methods don't return errors, making it "lazy" - you can chain calls without `_, _ =` error handling. It also handles nil receivers gracefully.

LazyBuffer is particularly useful in code generation, template rendering, or any scenario where you're building strings incrementally and error handling would clutter the code without providing value (since strings.Builder methods only return errors on out-of-memory conditions).

Example:

var buf LazyBuffer
output := buf.WriteString("Hello").
	WriteRunes(' ').
	WriteString("world").
	Printf(", %d", 42).
	WriteRunes('!').
	String()
// output: "Hello world, 42!"

func (*LazyBuffer) Len

func (b *LazyBuffer) Len() int

Len returns the number of accumulated bytes. Returns 0 if receiver is nil.

func (*LazyBuffer) Printf

func (b *LazyBuffer) Printf(format string, args ...any) *LazyBuffer

Printf appends a formatted string to the buffer using fmt.Fprintf. Safe to call on nil receiver. Returns the buffer for method chaining.

func (*LazyBuffer) Reset

func (b *LazyBuffer) Reset()

Reset resets the buffer to be empty. Safe to call on nil receiver.

func (*LazyBuffer) String

func (b *LazyBuffer) String() string

String returns the accumulated string. Returns empty string if receiver is nil.

func (*LazyBuffer) WriteRunes

func (b *LazyBuffer) WriteRunes(rr ...rune) *LazyBuffer

WriteRunes appends one or more runes to the buffer. Safe to call on nil receiver. Returns the buffer for method chaining.

func (*LazyBuffer) WriteString

func (b *LazyBuffer) WriteString(ss ...string) *LazyBuffer

WriteString appends one or more strings to the buffer, ignoring empty strings. Safe to call on nil receiver. Returns the buffer for method chaining.

Directories

Path Synopsis
generator module
internal
build
Package build contains build system utilities and configuration.
Package build contains build system utilities and configuration.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL