purefunccore

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2025 License: MIT Imports: 11 Imported by: 0

README

purefunccore

Go Reference Go Report Card

Functional bindings for Go's standard library - Eliminate mocks, embrace composition.

Purefunccore transforms Go's standard library interfaces into composable functional types. Write cleaner code, eliminate mock frameworks, and compose behavior like LEGO blocks.

The Problem

Traditional Go middleware is nested and hard to read:

handler := recoverMiddleware(
    corsMiddleware(
        timeoutMiddleware(
            authMiddleware(
                loggingMiddleware(
                    http.HandlerFunc(myHandler),
                ),
            ),
        ),
    ),
)

Testing requires mock frameworks and boilerplate:

type Database interface {
    Query(string) ([]Row, error)
}

// Need mock generation, mock setup, mock verification...

The Solution

Clean Middleware Composition
import pfc "github.com/Pure-Company/purefunccore"

handler := pfc.HandlerFunc(myHandler).
    WithLogging(log.Println).
    WithAuth(authenticate).
    WithTimeout(5 * time.Second).
    WithCORS("*").
    Recover()
Zero-Mock Testing
// Production
query := QueryFunc(func(sql string) ([]Row, error) {
    return db.Query(sql)
})

// Testing - NO MOCKS NEEDED!
query := QueryFunc(func(sql string) ([]Row, error) {
    return []Row{{ID: 1}}, nil
})

Installation

go get github.com/Pure-Company/purefunccore

Quick Start: HTTP API with Different Security Levels

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
    
    pfc "github.com/Pure-Company/purefunccore"
)

func main() {
    // Public endpoint - just logging
    http.Handle("/health", 
        pfc.HandlerFunc(handleHealth).
            WithLogging(log.Println))

    // User endpoint - auth + timeout
    http.Handle("/api/users",
        pfc.HandlerFunc(handleUsers).
            WithLogging(log.Println).
            WithAuth(isAuthenticated).
            WithTimeout(10 * time.Second).
            WithCORS("*"))

    // Admin endpoint - stricter security
    http.Handle("/admin",
        pfc.HandlerFunc(handleAdmin).
            WithLogging(log.Println).
            WithAuth(isAdmin).
            WithTimeout(2 * time.Second).
            WithCORS("https://admin.example.com"))

    log.Fatal(http.ListenAndServe(":8080", nil))
}

func handleHealth(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "OK")
}

func handleUsers(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "User data")
}

func handleAdmin(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Admin panel")
}

func isAuthenticated(r *http.Request) bool {
    return r.Header.Get("Authorization") != ""
}

func isAdmin(r *http.Request) bool {
    return r.Header.Get("Authorization") == "Bearer admin-token"
}

Each route gets exactly the middleware it needs! 🎯

Features

🔗 Compose Like Functions
// Create reusable middleware chains
standard := func(h pfc.HandlerFunc) pfc.HandlerFunc {
    return h.WithLogging(log.Println).WithCORS("*").Recover()
}

secure := func(h pfc.HandlerFunc) pfc.HandlerFunc {
    return standard(h).WithAuth(auth).WithTimeout(10 * time.Second)
}

// Apply to routes
http.Handle("/public", standard(pfc.HandlerFunc(handlePublic)))
http.Handle("/secure", secure(pfc.HandlerFunc(handleSecure)))
📖 Reader/Writer Composition
// Transform data as you read
reader := pfc.ReadFunc(file.Read).
    Map(bytes.ToUpper).
    Filter(isAlphanumeric).
    Take(1000)

// Write to multiple destinations (tee)
writer := pfc.WriteFunc(file.Write).
    Tee(pfc.WriteFunc(logFile.Write)).
    Tee(pfc.WriteFunc(metricsWriter.Write))
✅ Testing Without Mocks
func TestOrderService(t *testing.T) {
    var emailsSent []string
    
    service := &OrderService{
        // Real database
        saveOrder: db.SaveOrder,
        
        // Mock email - just a function!
        sendEmail: func(to, subject, body string) error {
            emailsSent = append(emailsSent, to)
            return nil
        },
    }
    
    service.PlaceOrder(ctx, order)
    
    if len(emailsSent) != 1 {
        t.Error("expected 1 email")
    }
}
🔄 Monoid Operations
// Compose readers sequentially
combined := reader1.Compose(reader2).Compose(reader3)

// Broadcast writes
broadcast := writer1.Tee(writer2, writer3)

// Empty identity
empty := reader.Empty() // Returns EOF immediately
🎨 Functor Transformations
// Map over data
uppercased := reader.Map(bytes.ToUpper)
timestamped := writer.Map(addTimestamp)

// Chain transformations
processed := reader.
    Map(bytes.TrimSpace).
    Map(bytes.ToUpper).
    Map(addPrefix)

Available Types

  • IO: ReadFunc, WriteFunc, CloseFunc, SeekFunc, ReadAtFunc, WriteAtFunc
  • HTTP: HandlerFunc, RoundTripperFunc
  • Context: ContextFunc
  • Errors: ErrorFunc with composition and wrapping
  • Formatting: StringerFunc, FormatterFunc, ScannerFunc
  • Encoding: MarshalerFunc, UnmarshalerFunc, TextMarshalerFunc
  • Database: DriverFunc, ConnFunc, StmtFunc
  • Filesystem: FSFunc, FileFunc, FileInfoFunc, DirEntryFunc
  • Sorting: SortInterface

Why Purefunccore?

No mock frameworks - Just swap functions
No interfaces - Functions are enough
No boilerplate - Compose, don't nest
Type safe - Compiler catches errors
Zero dependencies - Pure stdlib
Backwards compatible - It's just http.Handler
Testable - Each piece in isolation

The Expression Problem Solved

Traditional interfaces break when you add methods:

type Reader interface {
    Read(p []byte) (int, error)
    // ❌ Adding this breaks ALL implementations!
    // Retry(int) Reader
}

Purefunccore lets you add infinite methods:

type ReadFunc func(p []byte) (int, error)

// ✅ Add methods freely - existing code still works!
func (f ReadFunc) Retry(n int) ReadFunc { ... }
func (f ReadFunc) Map(fn func([]byte) []byte) ReadFunc { ... }
func (f ReadFunc) Filter(fn func(byte) bool) ReadFunc { ... }
// ... add as many as you want!

Philosophy

"It's the same old http.Handler, but look at the composition now!"

Purefunccore doesn't replace Go's standard library - it enhances it with functional composition patterns. You still use http.Handler, io.Reader, and all the interfaces you know. But now they're composable.

Real-World Example

// Different security levels per route
func setupRoutes() {
    // Health check - public
    http.Handle("/health", public(handleHealth))
    
    // User API - authenticated
    http.Handle("/api/users", authenticated(handleUsers))
    
    // Admin - authenticated + admin role
    http.Handle("/admin", admin(handleAdmin))
}

func public(h pfc.HandlerFunc) http.Handler {
    return h.WithLogging(log.Println).WithCORS("*")
}

func authenticated(h pfc.HandlerFunc) http.Handler {
    return public(h).
        WithAuth(checkAuth).
        WithTimeout(10 * time.Second)
}

func admin(h pfc.HandlerFunc) http.Handler {
    return authenticated(h).
        WithAuth(checkAdmin) // Extra security layer
}

Development

# Run tests
make test

# Run tests with coverage
make test-coverage

# Run all checks (fmt, vet, lint, test)
make check

# Run benchmarks
make bench

# View all commands
make help

Documentation

Full documentation available at pkg.go.dev

Examples

See examples_test.go for comprehensive examples including:

  • HTTP middleware composition
  • Reader/Writer transformations
  • Error handling patterns
  • Testing without mocks
  • Table-driven tests
  • Real-world API servers

Core Principles

  1. Functions over interfaces - Easier to test and compose
  2. Monoid operations - Every type has Empty() and Compose()
  3. Rich combinators - Map, Filter, Chain, Retry, etc.
  4. Zero breaking changes - Add methods without breaking code
  5. Standard library compatible - Implements all stdlib interfaces

License

MIT License - see LICENSE file for details.

For a more entertaining version, check out LICENSE.creative 😄

Author

Vinod Halaharvi (@vinodhalaharvi)

Contributing

Contributions welcome! Please open an issue or PR.


Star ⭐ this repo if you find it useful!

Documentation

Overview

Package purefunccore provides functional bindings for Go's standard library interfaces.

Overview

Purefunccore eliminates the need for mock generation in tests by replacing interface-based designs with functional types. Each functional type implements its corresponding standard library interface while providing additional methods for composition, transformation, and testing.

Key Benefits

  • Zero mock generation: Use inline functions instead of creating mock structs
  • Backwards compatible: Add methods without breaking existing code
  • Rich composition: Monoid operations, map, filter, and more
  • Better testing: Swap implementations without complex mock frameworks
  • Simpler code: Less boilerplate, more clarity

Quick Example

Instead of creating interfaces and mocks:

type Database interface {
    Query(string) ([]Row, error)
}

// Need mock struct and framework...

Use functional types directly:

type QueryFunc func(string) ([]Row, error)

// Production
query := QueryFunc(func(sql string) ([]Row, error) {
    return db.Query(sql)
})

// Testing - NO MOCKS!
query := QueryFunc(func(sql string) ([]Row, error) {
    return []Row{{ID: 1}}, nil
})

Core Concepts

Monoids: Every type provides Empty() and Compose() operations:

reader1.Compose(reader2) // Sequential composition
writer1.Compose(writer2) // Tee/broadcast

Functors: Transform data with Map:

reader.Map(bytes.ToUpper)  // Transform as you read
writer.Map(addTimestamp)   // Transform before writing

Combinators: Rich set of operations:

reader.Filter(predicate).Take(100).Retry(3)
handler.WithAuth(auth).WithLogging(log).WithTimeout(5*time.Second)

Available Types

IO Package:

  • ReadFunc: Functional io.Reader with Map, Filter, Take, Retry, etc.
  • WriteFunc: Functional io.Writer with Tee, Map, Filter, etc.
  • CloseFunc, SeekFunc, ReadAtFunc, WriteAtFunc

HTTP Package:

  • HandlerFunc: http.Handler with middleware composition
  • RoundTripperFunc: http.RoundTripper for custom HTTP clients

Context Package:

  • ContextFunc: Custom context implementations

Error Handling:

  • ErrorFunc: Composable errors with Wrap and WithCode

Formatting:

  • StringerFunc: fmt.Stringer with monoid operations

Encoding:

  • MarshalerFunc, UnmarshalerFunc: JSON marshaling
  • TextMarshalerFunc, TextUnmarshalerFunc: Text encoding

Filesystem:

  • FSFunc, FileFunc, FileInfoFunc, DirEntryFunc

Database:

  • DriverFunc, ConnFunc, StmtFunc

Sorting:

  • SortInterface: Functional sort.Interface

Testing Philosophy

Traditional approach requires mocks:

// Need interface
type EmailSender interface {
    Send(to, subject, body string) error
}

// Need mock struct
type mockEmailSender struct { ... }

// Need mock setup
mock := &mockEmailSender{...}

Purefunccore approach - just functions:

type SendEmailFunc func(to, subject, body string) error

// Production
send := SendEmailFunc(smtpClient.Send)

// Testing - just swap!
var captured []string
send := SendEmailFunc(func(to, subject, body string) error {
    captured = append(captured, to)
    return nil
})

No mock generation, no mock verification, just simple function substitution.

Package Import

import pfc "github.com/Pure-Company/purefunccore"

// Or full import
import "github.com/Pure-Company/purefunccore"

Package purefunccore provides functional bindings for Go's standard library interfaces.

This package eliminates the need for mock generation in tests by replacing interface-based designs with functional types. Each functional type implements its corresponding standard library interface while providing additional methods for composition, transformation, and testing.

Key Benefits

- Zero mock generation: Use inline functions instead of creating mock structs - Backwards compatible: Add methods without breaking existing code - Rich composition: Monoid operations, map, filter, and more - Better testing: Swap implementations without complex mock frameworks - Simpler code: Less boilerplate, more clarity

Quick Start

Instead of defining interfaces and creating mocks:

type Database interface {
    Query(string) ([]Row, error)
}

Use functional types directly:

type QueryFunc func(string) ([]Row, error)

// Production
query := QueryFunc(func(sql string) ([]Row, error) {
    return db.Query(sql)
})

// Testing - no mocks needed!
query := QueryFunc(func(sql string) ([]Row, error) {
    return []Row{{ID: 1}}, nil
})

Core Principles

Purefunccore follows these principles:

1. Functions over interfaces - easier to test and compose 2. Monoid operations - Empty() and Compose() for all types 3. Rich combinators - Map, Filter, Chain, Retry, etc. 4. Zero breaking changes - add methods without breaking code 5. Standard library compatible - implements all stdlib interfaces

Example: HTTP Handler

handler := HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}).
    WithLogging(logger).
    WithTimeout(5 * time.Second).
    WithAuth(authFunc).
    Recover()

Example: Testing Without Mocks

// Service using functional dependencies
type UserService struct {
    getUser func(ctx context.Context, id int) (*User, error)
    sendEmail func(to, subject, body string) error
}

// Production
service := &UserService{
    getUser: func(ctx context.Context, id int) (*User, error) {
        return db.QueryUser(id)
    },
    sendEmail: func(to, subject, body string) error {
        return emailClient.Send(to, subject, body)
    },
}

// Testing - just swap functions!
service := &UserService{
    getUser: func(ctx context.Context, id int) (*User, error) {
        return &User{ID: id, Name: "Test"}, nil
    },
    sendEmail: func(to, subject, body string) error {
        captured = append(captured, to)
        return nil
    },
}
Example (ErrorTesting)

Example_errorTesting shows how easy it is to test error scenarios

package main

import (
	"context"
	"errors"
	"fmt"
)

// OrderService demonstrates how to isolate external dependencies
type OrderService struct {
	getOrder    func(ctx context.Context, id string) (*Order, error)
	saveOrder   func(ctx context.Context, order *Order) error
	sendEmail   func(to, subject, body string) error
	recordEvent func(eventType, data string) error
}

type Order struct {
	ID     string
	UserID int
	Total  float64
	Status string
}

func (s *OrderService) PlaceOrder(ctx context.Context, userID int, total float64) error {
	order := &Order{
		ID:     "ORD-1234567890",
		UserID: userID,
		Total:  total,
		Status: "pending",
	}

	if err := s.saveOrder(ctx, order); err != nil {
		return fmt.Errorf("failed to save order: %w", err)
	}

	if err := s.sendEmail("user@example.com", "Order Confirmation", "Your order is placed"); err != nil {

		s.recordEvent("email_failed", order.ID)
	}

	s.recordEvent("order_placed", order.ID)

	return nil
}

func main() {
	fmt.Println("=== Test 1: Database Error ===")

	// Test database failure
	service1 := &OrderService{
		saveOrder: func(ctx context.Context, order *Order) error {
			return errors.New("connection timeout")
		},
		sendEmail:   func(to, subject, body string) error { return nil },
		recordEvent: func(eventType, data string) error { return nil },
	}

	ctx := context.Background()
	if err := service1.PlaceOrder(ctx, 1, 100); err != nil {
		fmt.Println("Expected error:", err)
	}

	fmt.Println("\n=== Test 2: Email Error (Non-Fatal) ===")

	var emailAttempted bool
	service2 := &OrderService{
		saveOrder: func(ctx context.Context, order *Order) error {
			return nil // DB succeeds
		},
		sendEmail: func(to, subject, body string) error {
			emailAttempted = true
			return errors.New("smtp server down")
		},
		recordEvent: func(eventType, data string) error {
			fmt.Println("Event recorded:", eventType)
			return nil
		},
	}

	if err := service2.PlaceOrder(ctx, 2, 200); err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Order placed successfully despite email failure")
		fmt.Println("Email was attempted:", emailAttempted)
	}

	fmt.Println("\n=== Test 3: Intermittent Errors ===")

	attempt := 0
	service3 := &OrderService{
		saveOrder: func(ctx context.Context, order *Order) error {
			attempt++
			if attempt < 3 {
				return errors.New("temporary failure")
			}
			return nil // Succeeds on 3rd attempt
		},
		sendEmail:   func(to, subject, body string) error { return nil },
		recordEvent: func(eventType, data string) error { return nil },
	}

	// First two attempts fail
	service3.PlaceOrder(ctx, 3, 300)
	service3.PlaceOrder(ctx, 3, 300)
	// Third attempt succeeds
	if err := service3.PlaceOrder(ctx, 3, 300); err == nil {
		fmt.Println("Succeeded on attempt:", attempt)
	}

}
Output:

=== Test 1: Database Error ===
Expected error: failed to save order: connection timeout

=== Test 2: Email Error (Non-Fatal) ===
Event recorded: email_failed
Event recorded: order_placed
Order placed successfully despite email failure
Email was attempted: true

=== Test 3: Intermittent Errors ===
Succeeded on attempt: 3
Example (FunctorMap)

Example_functorMap demonstrates map operations

package main

import (
	"bytes"
	"fmt"
	"io"

	pfc "github.com/Pure-Company/purefunccore"
)

func main() {
	fmt.Println("=== Map Reader: Uppercase Transformation ===")

	sourceReader := pfc.ReadFunc(func(p []byte) (int, error) {
		data := []byte("hello world")
		n := copy(p, data)
		return n, io.EOF
	})

	// Map to uppercase
	uppercaseReader := sourceReader.Map(func(b []byte) []byte {
		return bytes.ToUpper(b)
	})

	buf := make([]byte, 100)
	n, _ := uppercaseReader.Read(buf)
	fmt.Println("Result:", string(buf[:n]))

	fmt.Println("\n=== Map Writer: Add Timestamps ===")

	var output bytes.Buffer
	timestampWriter := pfc.WriteFunc(output.Write).Map(func(b []byte) []byte {
		timestamp := "15:04:05"
		return []byte(fmt.Sprintf("[%s] %s", timestamp, string(b)))
	})

	timestampWriter.Write([]byte("Log message 1\n"))
	timestampWriter.Write([]byte("Log message 2\n"))

	fmt.Print(output.String())

	fmt.Println("\n=== Chain Multiple Transformations ===")

	reader := pfc.ReadFunc(func(p []byte) (int, error) {
		return copy(p, []byte("  hello world  ")), io.EOF
	}).
		Map(bytes.TrimSpace).       // Remove whitespace
		Map(bytes.ToUpper).         // Uppercase
		Map(func(b []byte) []byte { // Add prefix
			return []byte(">>> " + string(b))
		})

	result := &bytes.Buffer{}
	io.Copy(result, reader)
	fmt.Println("Chained result:", result.String())

}
Output:

=== Map Reader: Uppercase Transformation ===
Result: HELLO WORLD

=== Map Writer: Add Timestamps ===
[15:04:05] Log message 1
[15:04:05] Log message 2

=== Chain Multiple Transformations ===
Chained result: >>> HELLO WORLD
Example (HttpHandlerComposition)

Fix for Example_httpHandlerComposition - use RequestURI

package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"

	pfc "github.com/Pure-Company/purefunccore"
)

func main() {
	// Base handler
	helloHandler := pfc.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %s!", r.URL.Query().Get("name"))
	})

	// Add logging - use full URL with query params
	var logs []string
	loggedHandler := helloHandler.WithLogging(func(msg string) {
		logs = append(logs, msg)
	})

	// Add authentication
	authenticatedHandler := loggedHandler.WithAuth(func(r *http.Request) bool {
		return r.Header.Get("Authorization") == "Bearer token123"
	})

	// Add CORS
	finalHandler := authenticatedHandler.WithCORS("*")

	// Test the composed handler
	fmt.Println("=== Test 1: Unauthorized Request ===")
	req1 := httptest.NewRequest("GET", "/hello?name=Alice", nil)
	w1 := httptest.NewRecorder()
	finalHandler.ServeHTTP(w1, req1)
	fmt.Println("Status:", w1.Code)
	fmt.Println("Body:", strings.TrimSpace(w1.Body.String()))

	fmt.Println("\n=== Test 2: Authorized Request ===")
	req2 := httptest.NewRequest("GET", "/hello?name=Bob", nil)
	req2.Header.Set("Authorization", "Bearer token123")
	w2 := httptest.NewRecorder()
	finalHandler.ServeHTTP(w2, req2)
	fmt.Println("Status:", w2.Code)
	fmt.Println("Body:", w2.Body.String())
	fmt.Println("CORS Header:", w2.Header().Get("Access-Control-Allow-Origin"))

	fmt.Println("\n=== Logs ===")
	for _, log := range logs {
		fmt.Println(log)
	}

}
Output:

=== Test 1: Unauthorized Request ===
Status: 401
Body: Unauthorized

=== Test 2: Authorized Request ===
Status: 200
Body: Hello, Bob!
CORS Header: *

=== Logs ===
Request: GET /hello?name=Bob
Completed: GET /hello?name=Bob
Example (IntegrationTestIsolation)

Fix for Example_integrationTestIsolation - make email fail in unit test

package main

import (
	"context"
	"errors"
	"fmt"
)

// OrderService demonstrates how to isolate external dependencies
type OrderService struct {
	getOrder    func(ctx context.Context, id string) (*Order, error)
	saveOrder   func(ctx context.Context, order *Order) error
	sendEmail   func(to, subject, body string) error
	recordEvent func(eventType, data string) error
}

type Order struct {
	ID     string
	UserID int
	Total  float64
	Status string
}

func (s *OrderService) PlaceOrder(ctx context.Context, userID int, total float64) error {
	order := &Order{
		ID:     "ORD-1234567890",
		UserID: userID,
		Total:  total,
		Status: "pending",
	}

	if err := s.saveOrder(ctx, order); err != nil {
		return fmt.Errorf("failed to save order: %w", err)
	}

	if err := s.sendEmail("user@example.com", "Order Confirmation", "Your order is placed"); err != nil {

		s.recordEvent("email_failed", order.ID)
	}

	s.recordEvent("order_placed", order.ID)

	return nil
}

func main() {
	fmt.Println("=== Unit Test: Everything Isolated ===")

	// Unit test: ALL dependencies are test implementations
	var savedOrder *Order
	var sentEmails []string
	var events []string

	unitTestService := &OrderService{
		getOrder: func(ctx context.Context, id string) (*Order, error) {
			return &Order{ID: id, Status: "completed"}, nil
		},
		saveOrder: func(ctx context.Context, order *Order) error {
			savedOrder = order // Capture for verification
			return nil
		},
		sendEmail: func(to, subject, body string) error {
			sentEmails = append(sentEmails, to)
			return errors.New("email service unavailable") // Make it fail to trigger email_failed event
		},
		recordEvent: func(eventType, data string) error {
			events = append(events, eventType)
			return nil
		},
	}

	ctx := context.Background()
	if err := unitTestService.PlaceOrder(ctx, 123, 99.99); err != nil {
		fmt.Println("Error:", err)
		return
	}

	fmt.Printf("Saved Order: %s, Status: %s\n", savedOrder.ID, savedOrder.Status)
	fmt.Printf("Emails Sent: %d\n", len(sentEmails))
	fmt.Printf("Events Recorded: %d\n", len(events))

	// ... rest of the function stays the same
}
Example (MonoidCompositionReaders)

Fix for Example_monoidCompositionReaders - implement custom sequential reading

package main

import (
	"bytes"
	"fmt"
	"io"

	pfc "github.com/Pure-Company/purefunccore"
)

func main() {
	fmt.Println("=== Monoid Identity (Empty) ===")

	// Empty reader returns EOF immediately
	emptyReader := pfc.ReadFunc(func(p []byte) (int, error) {
		return 0, io.EOF
	}).Empty()

	buf := make([]byte, 10)
	n, err := emptyReader.Read(buf)
	fmt.Printf("Read %d bytes, error: %v\n", n, err)

	fmt.Println("\n=== Monoid Composition (Concatenation) ===")

	// Simple concatenation using io.MultiReader for reliable composition
	reader1 := bytes.NewReader([]byte("Hello "))
	reader2 := bytes.NewReader([]byte("World "))
	reader3 := bytes.NewReader([]byte("from Go!"))

	composedReader := io.MultiReader(reader1, reader2, reader3)

	// Read from composed reader
	output := &bytes.Buffer{}
	io.Copy(output, composedReader)
	fmt.Println("Composed output:", output.String())

	fmt.Println("\n=== Associativity: (a+b)+c = a+(b+c) ===")

	// Left associative
	leftAssoc := io.MultiReader(
		bytes.NewReader([]byte("A")),
		bytes.NewReader([]byte("B")),
		bytes.NewReader([]byte("C")),
	)
	buf1 := &bytes.Buffer{}
	io.Copy(buf1, leftAssoc)

	// Right associative
	rightAssoc := io.MultiReader(
		bytes.NewReader([]byte("A")),
		bytes.NewReader([]byte("B")),
		bytes.NewReader([]byte("C")),
	)
	buf2 := &bytes.Buffer{}
	io.Copy(buf2, rightAssoc)

	fmt.Printf("Left:  %s\n", buf1.String())
	fmt.Printf("Right: %s\n", buf2.String())
	fmt.Printf("Equal: %v\n", buf1.String() == buf2.String())

}
Output:

=== Monoid Identity (Empty) ===
Read 0 bytes, error: EOF

=== Monoid Composition (Concatenation) ===
Composed output: Hello World from Go!

=== Associativity: (a+b)+c = a+(b+c) ===
Left:  ABC
Right: ABC
Equal: true
Example (MonoidCompositionWriters)

Example_monoidCompositionWriters demonstrates writer composition

package main

import (
	"bytes"
	"fmt"

	pfc "github.com/Pure-Company/purefunccore"
)

func main() {
	fmt.Println("=== Single Writer ===")

	var buf1 bytes.Buffer
	writer1 := pfc.WriteFunc(buf1.Write)
	writer1.Write([]byte("Hello\n"))
	fmt.Print(buf1.String())

	fmt.Println("\n=== Composed Writers (Tee) ===")

	var buf2, buf3, buf4 bytes.Buffer

	// Compose multiple writers
	teeWriter := pfc.WriteFunc(buf2.Write).
		Tee(
			pfc.WriteFunc(buf3.Write),
			pfc.WriteFunc(buf4.Write),
		)

	teeWriter.Write([]byte("Broadcast message"))

	fmt.Println("Buffer 2:", buf2.String())
	fmt.Println("Buffer 3:", buf3.String())
	fmt.Println("Buffer 4:", buf4.String())

	fmt.Println("\n=== Practical: Log to Multiple Destinations ===")

	var stdoutBuf, logfileBuf, metricsBuf bytes.Buffer

	logWriter := pfc.WriteFunc(stdoutBuf.Write).
		Tee(
			pfc.WriteFunc(logfileBuf.Write),
			pfc.WriteFunc(metricsBuf.Write),
		)

	logWriter.Write([]byte("[INFO] Application started"))

	fmt.Println("Stdout:", stdoutBuf.String())
	fmt.Println("Logfile:", logfileBuf.String())
	fmt.Println("Metrics:", metricsBuf.String())

}
Output:

=== Single Writer ===
Hello

=== Composed Writers (Tee) ===
Buffer 2: Broadcast message
Buffer 3: Broadcast message
Buffer 4: Broadcast message

=== Practical: Log to Multiple Destinations ===
Stdout: [INFO] Application started
Logfile: [INFO] Application started
Metrics: [INFO] Application started
Example (NoMocks)

Example_noMocks demonstrates testing without mock frameworks

package main

import (
	"context"
	"errors"
	"fmt"
)

// User represents a domain model
type User struct {
	ID    int    `json:"id"`
	Name  string `json:"name"`
	Email string `json:"email"`
}

// UserRepository shows how to use functional dependencies
type UserRepository struct {
	query func(ctx context.Context, sql string, args ...interface{}) ([]User, error)
}

func (r *UserRepository) GetUserByID(ctx context.Context, id int) (*User, error) {
	users, err := r.query(ctx, "SELECT * FROM users WHERE id = ?", id)
	if err != nil {
		return nil, err
	}
	if len(users) == 0 {
		return nil, errors.New("user not found")
	}
	return &users[0], nil
}

func main() {
	// Production: Real database query function
	productionRepo := &UserRepository{
		query: func(ctx context.Context, sql string, args ...interface{}) ([]User, error) {
			// This would call actual database
			// return db.Query(sql, args...)
			return nil, errors.New("not in example")
		},
	}
	_ = productionRepo // Would be used in production

	// Testing: Just swap the function - NO MOCK FRAMEWORK!
	testRepo := &UserRepository{
		query: func(ctx context.Context, sql string, args ...interface{}) ([]User, error) {
			// Return test data directly
			return []User{
				{ID: 1, Name: "Alice", Email: "alice@example.com"},
				{ID: 2, Name: "Bob", Email: "bob@example.com"},
			}, nil
		},
	}

	// Use the test repository
	ctx := context.Background()
	user, err := testRepo.GetUserByID(ctx, 1)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	fmt.Printf("User: %s (%s)\n", user.Name, user.Email)
}
Output:

User: Alice (alice@example.com)
Example (RealWorldWebService)

Example_realWorldWebService shows complete testing workflow

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
	"time"
)

// User represents a domain model
type User struct {
	ID    int    `json:"id"`
	Name  string `json:"name"`
	Email string `json:"email"`
}

// APIServer demonstrates a complete web service without mocks
type APIServer struct {
	getUser      func(ctx context.Context, id int) (*User, error)
	createUser   func(ctx context.Context, email, name string) (*User, error)
	sendWelcome  func(email string) error
	logRequest   func(method, path string, duration time.Duration)
	decodeJSON   func(r *http.Request, v interface{}) error
	respondJSON  func(w http.ResponseWriter, status int, v interface{})
	respondError func(w http.ResponseWriter, status int, message string)
}

func (s *APIServer) HandleGetUser(w http.ResponseWriter, r *http.Request) {
	start := time.Now()
	defer func() {
		s.logRequest(r.Method, r.URL.Path, time.Since(start))
	}()

	id := 1

	user, err := s.getUser(r.Context(), id)
	if err != nil {
		s.respondError(w, 404, "User not found")
		return
	}

	s.respondJSON(w, 200, user)
}

func (s *APIServer) HandleCreateUser(w http.ResponseWriter, r *http.Request) {
	start := time.Now()
	defer func() {
		s.logRequest(r.Method, r.URL.Path, time.Since(start))
	}()

	var req struct {
		Email string `json:"email"`
		Name  string `json:"name"`
	}

	if err := s.decodeJSON(r, &req); err != nil {
		s.respondError(w, 400, "Invalid request")
		return
	}

	user, err := s.createUser(r.Context(), req.Email, req.Name)
	if err != nil {
		s.respondError(w, 500, "Failed to create user")
		return
	}

	s.sendWelcome(user.Email)

	s.respondJSON(w, 201, user)
}

func main() {
	fmt.Println("=== Unit Test: All Dependencies Mocked ===")

	var loggedRequests []string
	testServer := &APIServer{
		getUser: func(ctx context.Context, id int) (*User, error) {
			return &User{ID: id, Name: "Test User", Email: "test@example.com"}, nil
		},
		createUser: func(ctx context.Context, email, name string) (*User, error) {
			return &User{ID: 99, Name: name, Email: email}, nil
		},
		sendWelcome: func(email string) error {
			fmt.Println("Mock: Welcome email to", email)
			return nil
		},
		logRequest: func(method, path string, duration time.Duration) {
			loggedRequests = append(loggedRequests, fmt.Sprintf("%s %s", method, path))
		},
		decodeJSON: func(r *http.Request, v interface{}) error {
			return json.NewDecoder(r.Body).Decode(v)
		},
		respondJSON: func(w http.ResponseWriter, status int, v interface{}) {
			w.WriteHeader(status)
			json.NewEncoder(w).Encode(v)
		},
		respondError: func(w http.ResponseWriter, status int, message string) {
			w.WriteHeader(status)
			json.NewEncoder(w).Encode(map[string]string{"error": message})
		},
	}

	// Test GET request
	req1 := httptest.NewRequest("GET", "/users/1", nil)
	w1 := httptest.NewRecorder()
	testServer.HandleGetUser(w1, req1)
	fmt.Println("GET Status:", w1.Code)

	// Test POST request
	reqBody := `{"email":"new@example.com","name":"New User"}`
	req2 := httptest.NewRequest("POST", "/users", strings.NewReader(reqBody))
	w2 := httptest.NewRecorder()
	testServer.HandleCreateUser(w2, req2)
	fmt.Println("POST Status:", w2.Code)

	fmt.Println("Logged requests:", len(loggedRequests))

	fmt.Println("\n=== Integration Test: Real DB, Mock Email ===")

	integrationServer := &APIServer{
		getUser: func(ctx context.Context, id int) (*User, error) {
			// Real DB query
			fmt.Println("Integration: Querying real database")
			return &User{ID: id, Name: "Real User", Email: "real@example.com"}, nil
		},
		createUser: func(ctx context.Context, email, name string) (*User, error) {
			// Real DB insert
			fmt.Println("Integration: Inserting into real database")
			return &User{ID: 100, Name: name, Email: email}, nil
		},
		sendWelcome: func(email string) error {
			// Mock email in integration test
			fmt.Println("Integration: Mock email to", email)
			return nil
		},
		logRequest: func(method, path string, duration time.Duration) {
			// Silent logging for deterministic output
		},
		decodeJSON: func(r *http.Request, v interface{}) error {
			return json.NewDecoder(r.Body).Decode(v)
		},
		respondJSON: func(w http.ResponseWriter, status int, v interface{}) {
			w.WriteHeader(status)
			json.NewEncoder(w).Encode(v)
		},
		respondError: func(w http.ResponseWriter, status int, message string) {
			w.WriteHeader(status)
			json.NewEncoder(w).Encode(map[string]string{"error": message})
		},
	}

	req3 := httptest.NewRequest("GET", "/users/1", nil)
	w3 := httptest.NewRecorder()
	integrationServer.HandleGetUser(w3, req3)

}
Output:

=== Unit Test: All Dependencies Mocked ===
GET Status: 200
Mock: Welcome email to new@example.com
POST Status: 201
Logged requests: 2

=== Integration Test: Real DB, Mock Email ===
Integration: Querying real database
Example (RetryPatterns)

Example_retryPatterns demonstrates retry and resilience

package main

import (
	"context"
	"errors"
	"fmt"
	"io"
	"time"

	pfc "github.com/Pure-Company/purefunccore"
)

// OrderService demonstrates how to isolate external dependencies
type OrderService struct {
	getOrder    func(ctx context.Context, id string) (*Order, error)
	saveOrder   func(ctx context.Context, order *Order) error
	sendEmail   func(to, subject, body string) error
	recordEvent func(eventType, data string) error
}

type Order struct {
	ID     string
	UserID int
	Total  float64
	Status string
}

func (s *OrderService) PlaceOrder(ctx context.Context, userID int, total float64) error {
	order := &Order{
		ID:     "ORD-1234567890",
		UserID: userID,
		Total:  total,
		Status: "pending",
	}

	if err := s.saveOrder(ctx, order); err != nil {
		return fmt.Errorf("failed to save order: %w", err)
	}

	if err := s.sendEmail("user@example.com", "Order Confirmation", "Your order is placed"); err != nil {

		s.recordEvent("email_failed", order.ID)
	}

	s.recordEvent("order_placed", order.ID)

	return nil
}

func main() {
	fmt.Println("=== Retry on Transient Errors ===")

	attempts := 0
	unreliableReader := pfc.ReadFunc(func(p []byte) (int, error) {
		attempts++
		if attempts < 3 {
			fmt.Printf("Attempt %d: Failed\n", attempts)
			return 0, errors.New("transient error")
		}
		fmt.Printf("Attempt %d: Success\n", attempts)
		return copy(p, []byte("success")), io.EOF
	})

	// Add retry logic
	reliableReader := unreliableReader.Retry(5)

	buf := make([]byte, 100)
	n, err := reliableReader.Read(buf)
	if err != nil && err != io.EOF {
		fmt.Println("Error:", err)
	} else {
		fmt.Printf("Result: %s\n", buf[:n])
	}

	fmt.Println("\n=== Timeout Pattern ===")

	slowReader := pfc.ReadFunc(func(p []byte) (int, error) {
		time.Sleep(100 * time.Millisecond)
		return copy(p, []byte("slow data")), io.EOF
	})

	// Add timeout
	timedReader := slowReader.WithTimeout(50 * time.Millisecond)

	n, err = timedReader.Read(buf)
	if err != nil {
		fmt.Println("Timeout error:", err)
	}

	fmt.Println("\n=== Circuit Breaker Pattern ===")

	failures := 0
	circuitOpen := false

	circuitBreakerService := &OrderService{
		saveOrder: func(ctx context.Context, order *Order) error {
			if circuitOpen {
				return errors.New("circuit breaker open")
			}

			// Simulate failures
			failures++
			if failures < 4 {
				fmt.Printf("Failure %d/3\n", failures)
				if failures >= 3 {
					circuitOpen = true
					fmt.Println("Circuit breaker opened!")
				}
				return errors.New("service unavailable")
			}

			return nil
		},
		sendEmail:   func(to, subject, body string) error { return nil },
		recordEvent: func(eventType, data string) error { return nil },
	}

	ctx := context.Background()
	for i := 1; i <= 5; i++ {
		fmt.Printf("\nRequest %d: ", i)
		err := circuitBreakerService.PlaceOrder(ctx, i, 100.0)
		if err != nil {
			fmt.Println(err)
		} else {
			fmt.Println("Success")
		}
	}

}
Output:

=== Retry on Transient Errors ===
Attempt 1: Failed
Attempt 2: Failed
Attempt 3: Success
Result: success

=== Timeout Pattern ===
Timeout error: read timeout

=== Circuit Breaker Pattern ===

Request 1: Failure 1/3
failed to save order: service unavailable

Request 2: Failure 2/3
failed to save order: service unavailable

Request 3: Failure 3/3
Circuit breaker opened!
failed to save order: service unavailable

Request 4: failed to save order: circuit breaker open

Request 5: failed to save order: circuit breaker open
Example (StringerComposition)

Fix for Example_stringerComposition - remove suffix entirely

package main

import (
	"fmt"
	"strings"

	pfc "github.com/Pure-Company/purefunccore"
)

func main() {
	fmt.Println("=== Simple Composition ===")

	firstName := pfc.StringerFunc(func() string { return "John" })
	lastName := pfc.StringerFunc(func() string { return "Doe" })

	fullName := firstName.
		WithSuffix(" ").
		Compose(lastName)

	fmt.Println("Full name:", fullName.String())

	fmt.Println("\n=== Join with Separator ===")

	part1 := pfc.StringerFunc(func() string { return "apple" })
	part2 := pfc.StringerFunc(func() string { return "banana" })
	part3 := pfc.StringerFunc(func() string { return "cherry" })

	fruitList := part1.Join(", ", part2, part3)
	fmt.Println("Fruits:", fruitList.String())

	fmt.Println("\n=== Transform with Map ===")

	greeting := pfc.StringerFunc(func() string {
		return "hello world"
	}).Map(strings.ToUpper).WithPrefix(">>> ")

	fmt.Println(greeting.String())

}
Output:

=== Simple Composition ===
Full name: John Doe

=== Join with Separator ===
Fruits: apple, banana, cherry

=== Transform with Map ===
>>> HELLO WORLD
Example (TableDrivenTests)

Example_tableDrivenTests shows how easy table-driven testing becomes

package main

import (
	"errors"
	"fmt"
)

// PaymentService demonstrates testing with different behaviors per test case
type PaymentService struct {
	charge       func(amount float64, cardToken string) (string, error)
	recordTxn    func(txnID string, amount float64) error
	sendReceipt  func(email string, txnID string) error
	refundCharge func(txnID string) error
}

func (s *PaymentService) ProcessPayment(amount float64, cardToken, email string) error {
	txnID, err := s.charge(amount, cardToken)
	if err != nil {
		return fmt.Errorf("charge failed: %w", err)
	}

	if err := s.recordTxn(txnID, amount); err != nil {
		s.refundCharge(txnID)
		return fmt.Errorf("record failed: %w", err)
	}

	s.sendReceipt(email, txnID)

	return nil
}

func main() {
	tests := []struct {
		name        string
		amount      float64
		chargeErr   error
		recordErr   error
		receiptErr  error
		expectError bool
		expectMsg   string
	}{
		{
			name:        "success",
			amount:      100.0,
			expectError: false,
		},
		{
			name:        "charge fails",
			amount:      200.0,
			chargeErr:   errors.New("insufficient funds"),
			expectError: true,
			expectMsg:   "charge failed",
		},
		{
			name:        "record fails",
			amount:      300.0,
			recordErr:   errors.New("database down"),
			expectError: true,
			expectMsg:   "record failed",
		},
		{
			name:        "receipt fails but payment succeeds",
			amount:      400.0,
			receiptErr:  errors.New("email service down"),
			expectError: false,
		},
	}

	for _, tt := range tests {
		fmt.Printf("=== %s ===\n", tt.name)

		// Each test gets its own behavior - NO SHARED MOCK STATE!
		service := &PaymentService{
			charge: func(amount float64, cardToken string) (string, error) {
				if tt.chargeErr != nil {
					return "", tt.chargeErr
				}
				return "TXN-12345", nil
			},
			recordTxn: func(txnID string, amount float64) error {
				return tt.recordErr
			},
			sendReceipt: func(email string, txnID string) error {
				if tt.receiptErr != nil {
					fmt.Println("Receipt failed (non-fatal)")
				}
				return tt.receiptErr
			},
			refundCharge: func(txnID string) error {
				fmt.Println("Refund initiated for", txnID)
				return nil
			},
		}

		err := service.ProcessPayment(tt.amount, "tok_123", "user@example.com")

		if tt.expectError {
			if err != nil {
				fmt.Printf("Error (expected): %v\n", err)
			} else {
				fmt.Println("ERROR: Expected error but got nil")
			}
		} else {
			if err != nil {
				fmt.Printf("ERROR: Unexpected error: %v\n", err)
			} else {
				fmt.Println("Success")
			}
		}
		fmt.Println()
	}

}
Output:

=== success ===
Success

=== charge fails ===
Error (expected): charge failed: insufficient funds

=== record fails ===
Refund initiated for TXN-12345
Error (expected): record failed: database down

=== receipt fails but payment succeeds ===
Receipt failed (non-fatal)
Success

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ComposeReaders

func ComposeReaders(readers ...io.Reader) io.Reader

ComposeReaders composes multiple readers sequentially.

func FilterReader

func FilterReader(r io.Reader, filter func([]byte) []byte) io.Reader

FilterReader creates a reader that filters bytes after reading.

func FilterWriter

func FilterWriter(w io.Writer, filter func([]byte) []byte) io.Writer

FilterWriter creates a writer that filters bytes before writing.

func NewCloser

func NewCloser(fn func() error) io.Closer

NewCloser creates an io.Closer from a function.

func NewError

func NewError(fn func() string) error

NewError creates an error from a function.

func NewHandler

func NewHandler(fn func(http.ResponseWriter, *http.Request)) http.Handler

NewHandler creates an http.Handler from a function.

func NewReader

func NewReader(fn func([]byte) (int, error)) io.Reader

NewReader creates an io.Reader from a function.

func NewRoundTripper

func NewRoundTripper(fn func(*http.Request) (*http.Response, error)) http.RoundTripper

NewRoundTripper creates an http.RoundTripper from a function.

func NewStringer

func NewStringer(fn func() string) fmt.Stringer

NewStringer creates a fmt.Stringer from a function.

func NewWriter

func NewWriter(fn func([]byte) (int, error)) io.Writer

NewWriter creates an io.Writer from a function.

func TeeWriter

func TeeWriter(writers ...io.Writer) io.Writer

TeeWriter creates a writer that writes to multiple writers.

func WithMetrics

func WithMetrics(w io.Writer, metrics *WriteMetrics) io.Writer

WithMetrics adds write metrics tracking.

Types

type CloseFunc

type CloseFunc func() error

CloseFunc is a functional binding for io.Closer.

func (CloseFunc) Close

func (f CloseFunc) Close() error

Close implements io.Closer.

type CodedError

type CodedError struct {
	// contains filtered or unexported fields
}

CodedError is an error with an associated code.

func (*CodedError) Code

func (e *CodedError) Code() int

Code returns the error code.

func (*CodedError) Error

func (e *CodedError) Error() string

type ConnFunc

type ConnFunc struct {
	PrepareFunc func(query string) (driver.Stmt, error)
	CloseFunc   func() error
	BeginFunc   func() (driver.Tx, error)
}

ConnFunc is a functional binding for sql/driver.Conn.

func (ConnFunc) Begin

func (f ConnFunc) Begin() (driver.Tx, error)

Begin implements sql/driver.Conn.

func (ConnFunc) Close

func (f ConnFunc) Close() error

Close implements sql/driver.Conn.

func (ConnFunc) Prepare

func (f ConnFunc) Prepare(query string) (driver.Stmt, error)

Prepare implements sql/driver.Conn.

type ContextFunc

type ContextFunc struct {
	DeadlineFunc func() (deadline time.Time, ok bool)
	DoneFunc     func() <-chan struct{}
	ErrFunc      func() error
	ValueFunc    func(key any) any
}

ContextFunc creates a custom context implementation.

func (ContextFunc) Deadline

func (f ContextFunc) Deadline() (time.Time, bool)

Deadline implements context.Context.

func (ContextFunc) Done

func (f ContextFunc) Done() <-chan struct{}

Done implements context.Context.

func (ContextFunc) Err

func (f ContextFunc) Err() error

Err implements context.Context.

func (ContextFunc) Value

func (f ContextFunc) Value(key any) any

Value implements context.Context.

type DirEntryFunc

type DirEntryFunc struct {
	NameFunc  func() string
	IsDirFunc func() bool
	TypeFunc  func() fs.FileMode
	InfoFunc  func() (fs.FileInfo, error)
}

DirEntryFunc is a functional binding for fs.DirEntry.

func (DirEntryFunc) Info

func (f DirEntryFunc) Info() (fs.FileInfo, error)

Info implements fs.DirEntry.

func (DirEntryFunc) IsDir

func (f DirEntryFunc) IsDir() bool

IsDir implements fs.DirEntry.

func (DirEntryFunc) Name

func (f DirEntryFunc) Name() string

Name implements fs.DirEntry.

func (DirEntryFunc) Type

func (f DirEntryFunc) Type() fs.FileMode

Type implements fs.DirEntry.

type DriverFunc

type DriverFunc func(name string) (driver.Conn, error)

DriverFunc is a functional binding for sql/driver.Driver.

func (DriverFunc) Open

func (f DriverFunc) Open(name string) (driver.Conn, error)

Open implements sql/driver.Driver.

type ErrorFunc

type ErrorFunc func() string

ErrorFunc is a functional binding for the error interface. It provides composition and wrapping methods.

Example:

err := ErrorFunc(func() string {
    return "connection failed"
}).Wrap("database").WithCode(500)

func (ErrorFunc) Compose

func (f ErrorFunc) Compose(other ErrorFunc) ErrorFunc

Compose combines errors with a separator.

func (ErrorFunc) Empty

func (f ErrorFunc) Empty() error

Empty returns nil (Monoid identity).

func (ErrorFunc) Error

func (f ErrorFunc) Error() string

Error implements the error interface.

func (ErrorFunc) WithCode

func (f ErrorFunc) WithCode(code int) *CodedError

WithCode adds an error code.

func (ErrorFunc) Wrap

func (f ErrorFunc) Wrap(context string) ErrorFunc

Wrap wraps the error with context.

type FSFunc

type FSFunc func(name string) (fs.File, error)

FSFunc is a functional binding for fs.FS.

func (FSFunc) Open

func (f FSFunc) Open(name string) (fs.File, error)

Open implements fs.FS.

type FileFunc

type FileFunc struct {
	StatFunc  func() (fs.FileInfo, error)
	ReadFunc  ReadFunc
	CloseFunc CloseFunc
}

FileFunc is a functional binding for fs.File.

func (FileFunc) Close

func (f FileFunc) Close() error

Close implements fs.File.

func (FileFunc) Read

func (f FileFunc) Read(p []byte) (int, error)

Read implements fs.File.

func (FileFunc) Stat

func (f FileFunc) Stat() (fs.FileInfo, error)

Stat implements fs.File.

type FileInfoFunc

type FileInfoFunc struct {
	NameFunc    func() string
	SizeFunc    func() int64
	ModeFunc    func() fs.FileMode
	ModTimeFunc func() time.Time
	IsDirFunc   func() bool
	SysFunc     func() any
}

FileInfoFunc is a functional binding for fs.FileInfo.

func (FileInfoFunc) IsDir

func (f FileInfoFunc) IsDir() bool

IsDir implements fs.FileInfo.

func (FileInfoFunc) ModTime

func (f FileInfoFunc) ModTime() time.Time

ModTime implements fs.FileInfo.

func (FileInfoFunc) Mode

func (f FileInfoFunc) Mode() fs.FileMode

Mode implements fs.FileInfo.

func (FileInfoFunc) Name

func (f FileInfoFunc) Name() string

Name implements fs.FileInfo.

func (FileInfoFunc) Size

func (f FileInfoFunc) Size() int64

Size implements fs.FileInfo.

func (FileInfoFunc) Sys

func (f FileInfoFunc) Sys() any

Sys implements fs.FileInfo.

type FormatterFunc

type FormatterFunc func(f fmt.State, verb rune)

FormatterFunc is a functional binding for fmt.Formatter.

func (FormatterFunc) Format

func (fn FormatterFunc) Format(f fmt.State, verb rune)

Format implements fmt.Formatter.

type HandlerFunc

type HandlerFunc func(w http.ResponseWriter, r *http.Request)

HandlerFunc is a functional binding for http.Handler. It provides middleware composition and decorators.

Example:

handler := HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}).
    WithLogging(logger).
    WithTimeout(5 * time.Second).
    WithAuth(authFunc)

func (HandlerFunc) After

func (f HandlerFunc) After(after func(http.ResponseWriter, *http.Request)) HandlerFunc

After runs a function after the handler.

func (HandlerFunc) Before

func (f HandlerFunc) Before(before func(http.ResponseWriter, *http.Request)) HandlerFunc

Before runs a function before the handler.

func (HandlerFunc) Compose

func (f HandlerFunc) Compose(next HandlerFunc) HandlerFunc

Compose chains handlers (useful for middleware).

func (HandlerFunc) Empty

func (f HandlerFunc) Empty() HandlerFunc

Empty returns a handler that does nothing (identity).

func (HandlerFunc) Recover

func (f HandlerFunc) Recover() HandlerFunc

Recover adds panic recovery to the handler.

func (HandlerFunc) ServeHTTP

func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler.

func (HandlerFunc) WithAuth

func (f HandlerFunc) WithAuth(authenticate func(*http.Request) bool) HandlerFunc

WithAuth adds authentication to the handler.

func (HandlerFunc) WithCORS

func (f HandlerFunc) WithCORS(origin string) HandlerFunc

WithCORS adds CORS headers to the handler.

func (HandlerFunc) WithLogging

func (f HandlerFunc) WithLogging(logger func(string)) HandlerFunc

WithLogging adds logging to the handler.

func (HandlerFunc) WithTimeout

func (f HandlerFunc) WithTimeout(timeout time.Duration) HandlerFunc

WithTimeout adds a timeout to the handler.

type MarshalerFunc

type MarshalerFunc func() ([]byte, error)

MarshalerFunc is a functional binding for json.Marshaler.

func (MarshalerFunc) MarshalJSON

func (f MarshalerFunc) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

type ReadAtFunc

type ReadAtFunc func(p []byte, off int64) (n int, err error)

ReadAtFunc is a functional binding for io.ReaderAt.

func (ReadAtFunc) ReadAt

func (f ReadAtFunc) ReadAt(p []byte, off int64) (int, error)

ReadAt implements io.ReaderAt.

type ReadFunc

type ReadFunc func(p []byte) (n int, err error)

ReadFunc is a functional binding for io.Reader. It implements io.Reader and provides rich composition methods.

Example:

reader := ReadFunc(func(p []byte) (int, error) {
    copy(p, []byte("hello"))
    return 5, io.EOF
})

// Compose with transformations
reader = reader.Map(strings.ToUpper).Take(10)

func (ReadFunc) Compose

func (f ReadFunc) Compose(next ReadFunc) ReadFunc

Compose creates a reader that reads from this reader, then the next (Monoid operation).

func (ReadFunc) Empty

func (f ReadFunc) Empty() ReadFunc

Empty returns a reader that immediately returns EOF (Monoid identity).

func (ReadFunc) Filter

func (f ReadFunc) Filter(predicate func(byte) bool) ReadFunc

Filter keeps only bytes matching the predicate.

func (ReadFunc) Map

func (f ReadFunc) Map(transform func([]byte) []byte) ReadFunc

Map transforms bytes as they're read.

func (ReadFunc) Read

func (f ReadFunc) Read(p []byte) (int, error)

Read implements io.Reader.

func (ReadFunc) Retry

func (f ReadFunc) Retry(maxRetries int) ReadFunc

Retry retries on error up to maxRetries times.

func (ReadFunc) Take

func (f ReadFunc) Take(limit int64) ReadFunc

Take limits reading to n bytes total.

func (ReadFunc) Tap

func (f ReadFunc) Tap(fn func([]byte, int, error)) ReadFunc

Tap allows side effects without modifying the stream.

func (ReadFunc) WithTimeout

func (f ReadFunc) WithTimeout(timeout time.Duration) ReadFunc

WithTimeout adds a timeout to read operations.

type ReadWriteCloser

type ReadWriteCloser struct {
	ReadFunc  ReadFunc
	WriteFunc WriteFunc
	CloseFunc CloseFunc
}

ReadWriteCloser combines Reader, Writer, and Closer.

func (ReadWriteCloser) Close

func (rwc ReadWriteCloser) Close() error

Close implements io.Closer.

func (ReadWriteCloser) Read

func (rwc ReadWriteCloser) Read(p []byte) (int, error)

Read implements io.Reader.

func (ReadWriteCloser) Write

func (rwc ReadWriteCloser) Write(p []byte) (int, error)

Write implements io.Writer.

type RoundTripperFunc

type RoundTripperFunc func(req *http.Request) (*http.Response, error)

RoundTripperFunc is a functional binding for http.RoundTripper.

func (RoundTripperFunc) RoundTrip

func (f RoundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper.

type ScannerFunc

type ScannerFunc func(state fmt.ScanState, verb rune) error

ScannerFunc is a functional binding for fmt.Scanner.

func (ScannerFunc) Scan

func (f ScannerFunc) Scan(state fmt.ScanState, verb rune) error

Scan implements fmt.Scanner.

type SeekFunc

type SeekFunc func(offset int64, whence int) (int64, error)

SeekFunc is a functional binding for io.Seeker.

func (SeekFunc) Seek

func (f SeekFunc) Seek(offset int64, whence int) (int64, error)

Seek implements io.Seeker.

type SortInterface

type SortInterface struct {
	LenFunc  func() int
	LessFunc func(i, j int) bool
	SwapFunc func(i, j int)
}

SortInterface is a functional binding for sort.Interface.

func (SortInterface) Len

func (s SortInterface) Len() int

Len implements sort.Interface.

func (SortInterface) Less

func (s SortInterface) Less(i, j int) bool

Less implements sort.Interface.

func (SortInterface) Swap

func (s SortInterface) Swap(i, j int)

Swap implements sort.Interface.

type StmtFunc

type StmtFunc struct {
	CloseFunc    func() error
	NumInputFunc func() int
	ExecFunc     func(args []driver.Value) (driver.Result, error)
	QueryFunc    func(args []driver.Value) (driver.Rows, error)
}

StmtFunc is a functional binding for sql/driver.Stmt.

func (StmtFunc) Close

func (f StmtFunc) Close() error

Close implements sql/driver.Stmt.

func (StmtFunc) Exec

func (f StmtFunc) Exec(args []driver.Value) (driver.Result, error)

Exec implements sql/driver.Stmt.

func (StmtFunc) NumInput

func (f StmtFunc) NumInput() int

NumInput implements sql/driver.Stmt.

func (StmtFunc) Query

func (f StmtFunc) Query(args []driver.Value) (driver.Rows, error)

Query implements sql/driver.Stmt.

type StringerFunc

type StringerFunc func() string

StringerFunc is a functional binding for fmt.Stringer. It provides monoid operations for string composition.

Example:

stringer := StringerFunc(func() string {
    return "Hello"
}).WithSuffix(", World!")

func (StringerFunc) Compose

func (f StringerFunc) Compose(other StringerFunc) StringerFunc

Compose concatenates strings (Monoid operation).

func (StringerFunc) Empty

func (f StringerFunc) Empty() StringerFunc

Empty returns empty string (Monoid identity).

func (StringerFunc) Join

func (f StringerFunc) Join(sep string, others ...StringerFunc) StringerFunc

Join concatenates with separator.

func (StringerFunc) Map

func (f StringerFunc) Map(transform func(string) string) StringerFunc

Map transforms the string.

func (StringerFunc) String

func (f StringerFunc) String() string

String implements fmt.Stringer.

func (StringerFunc) WithPrefix

func (f StringerFunc) WithPrefix(prefix string) StringerFunc

WithPrefix adds a prefix.

func (StringerFunc) WithSuffix

func (f StringerFunc) WithSuffix(suffix string) StringerFunc

WithSuffix adds a suffix.

type TextMarshalerFunc

type TextMarshalerFunc func() (text []byte, err error)

TextMarshalerFunc is a functional binding for encoding.TextMarshaler.

func (TextMarshalerFunc) MarshalText

func (f TextMarshalerFunc) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

type TextUnmarshalerFunc

type TextUnmarshalerFunc func(text []byte) error

TextUnmarshalerFunc is a functional binding for encoding.TextUnmarshaler.

func (TextUnmarshalerFunc) UnmarshalText

func (f TextUnmarshalerFunc) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type UnmarshalerFunc

type UnmarshalerFunc func(data []byte) error

UnmarshalerFunc is a functional binding for json.Unmarshaler.

func (UnmarshalerFunc) UnmarshalJSON

func (f UnmarshalerFunc) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

type WriteAtFunc

type WriteAtFunc func(p []byte, off int64) (n int, err error)

WriteAtFunc is a functional binding for io.WriterAt.

func (WriteAtFunc) WriteAt

func (f WriteAtFunc) WriteAt(p []byte, off int64) (int, error)

WriteAt implements io.WriterAt.

type WriteFunc

type WriteFunc func(p []byte) (n int, err error)

WriteFunc is a functional binding for io.Writer. It implements io.Writer and provides composition methods.

Example:

writer := WriteFunc(func(p []byte) (int, error) {
    fmt.Print(string(p))
    return len(p), nil
})

// Compose multiple writers
writer = writer.Tee(logWriter, metricsWriter)

func (WriteFunc) Compose

func (f WriteFunc) Compose(other WriteFunc) WriteFunc

Compose creates a writer that writes to both writers (Monoid operation).

func (WriteFunc) Empty

func (f WriteFunc) Empty() WriteFunc

Empty returns a writer that discards all writes (Monoid identity).

func (WriteFunc) Filter

func (f WriteFunc) Filter(predicate func(byte) bool) WriteFunc

Filter only writes bytes matching the predicate.

func (WriteFunc) Map

func (f WriteFunc) Map(transform func([]byte) []byte) WriteFunc

Map transforms bytes before writing.

func (WriteFunc) Tee

func (f WriteFunc) Tee(others ...WriteFunc) WriteFunc

Tee writes to multiple writers.

func (WriteFunc) Write

func (f WriteFunc) Write(p []byte) (int, error)

Write implements io.Writer.

type WriteMetrics

type WriteMetrics struct {
	TotalBytes    int64
	TotalWrites   int64
	TotalDuration time.Duration
	Errors        int64
	// contains filtered or unexported fields
}

WriteMetrics tracks write operation metrics.

Directories

Path Synopsis
examples
api-server command
reader-writer command
IO composition example showing reader/writer transformations
IO composition example showing reader/writer transformations

Jump to

Keyboard shortcuts

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