Documentation
¶
Overview ¶
Package file provides functional programming utilities for working with file paths and I/O interfaces in Go.
Overview ¶
This package offers a collection of utility functions designed to work seamlessly with functional programming patterns, particularly with the fp-go library's pipe and composition utilities.
Path Manipulation ¶
The Join function provides a curried approach to path joining, making it easy to create reusable path builders:
import (
F "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/file"
)
// Create a reusable path builder
addConfig := file.Join("config.json")
configPath := addConfig("/etc/myapp")
// Result: "/etc/myapp/config.json"
// Use in a functional pipeline
logPath := F.Pipe1("/var/log", file.Join("app.log"))
// Result: "/var/log/app.log"
// Chain multiple joins
deepPath := F.Pipe2(
"/root",
file.Join("subdir"),
file.Join("file.txt"),
)
// Result: "/root/subdir/file.txt"
I/O Interface Conversions ¶
The package provides generic type conversion functions for common I/O interfaces. These are useful for type erasure when you need to work with interface types rather than concrete implementations:
import (
"bytes"
"io"
"github.com/IBM/fp-go/v2/file"
)
// Convert concrete types to interfaces
buf := bytes.NewBuffer([]byte("hello"))
var reader io.Reader = file.ToReader(buf)
writer := &bytes.Buffer{}
var w io.Writer = file.ToWriter(writer)
f, _ := os.Open("file.txt")
var closer io.Closer = file.ToCloser(f)
defer closer.Close()
Design Philosophy ¶
The functions in this package follow functional programming principles:
- Currying: Functions like Join return functions, enabling partial application
- Type Safety: Generic functions maintain type safety while providing flexibility
- Composability: All functions work well with fp-go's pipe and composition utilities
- Immutability: Functions don't modify their inputs
Performance ¶
The type conversion functions (ToReader, ToWriter, ToCloser) have zero overhead as they simply return their input cast to the interface type. The Join function uses Go's standard filepath.Join internally, ensuring cross-platform compatibility.
Package file provides utility functions for working with file paths and I/O interfaces. It offers functional programming utilities for path manipulation and type conversions for common I/O interfaces.
Index ¶
- Constants
- func NopReadCloser[R io.Reader](r R) io.ReadCloser
- func NopWriteCloser[W io.Writer](w W) io.WriteCloser
- func ToCloser[C io.Closer](c C) io.Closer
- func ToReadCloser[C io.ReadCloser](c C) io.ReadCloser
- func ToReader[R io.Reader](r R) io.Reader
- func ToWriteCloser[C io.WriteCloser](c C) io.WriteCloser
- func ToWriter[W io.Writer](w W) io.Writer
- type Endomorphism
Constants ¶
const (
STDIO = "-"
)
STDIO is a special constant representing standard input/output streams. When used as a filename with ReadFile or WriteFile, it causes the operation to use os.Stdin or os.Stdout respectively, instead of opening a file.
This convention is commonly used in Unix command-line tools to allow reading from stdin or writing to stdout by specifying "-" as the filename.
Variables ¶
This section is empty.
Functions ¶
func NopReadCloser ¶ added in v2.2.75
func NopReadCloser[R io.Reader](r R) io.ReadCloser
NopReadCloser wraps an io.Reader with a no-op Close method, converting it to an io.ReadCloser. This is useful when you need to satisfy an io.ReadCloser interface but don't need actual close functionality, such as when working with in-memory buffers or strings.
This function is a generic wrapper around io.NopCloser that preserves type information for better type inference in functional pipelines.
Type Parameters:
- R: Any type that implements io.Reader
Parameters:
- r: The io.Reader to wrap
Returns:
- io.ReadCloser: A ReadCloser that delegates Read calls to r and has a no-op Close
Example:
reader := strings.NewReader("hello world")
readCloser := NopReadCloser(reader)
defer readCloser.Close() // no-op, safe to call
data, _ := io.ReadAll(readCloser)
See Also:
- NopWriteCloser: Similar wrapper for io.Writer
func NopWriteCloser ¶ added in v2.2.75
func NopWriteCloser[W io.Writer](w W) io.WriteCloser
NopWriteCloser wraps an io.Writer with a no-op Close method, converting it to an io.WriteCloser. This is useful when you need to satisfy an io.WriteCloser interface but don't need actual close functionality, such as when writing to in-memory buffers or when the underlying writer doesn't require cleanup.
The returned WriteCloser delegates all Write calls to the underlying writer and returns nil from Close without performing any cleanup operations.
Type Parameters:
- W: Any type that implements io.Writer
Parameters:
- w: The io.Writer to wrap
Returns:
- io.WriteCloser: A WriteCloser that delegates Write calls to w and has a no-op Close
Example:
var buf bytes.Buffer
writeCloser := NopWriteCloser(&buf)
writeCloser.Write([]byte("hello"))
writeCloser.Close() // no-op, safe to call
fmt.Println(buf.String()) // prints: hello
See Also:
- NopReadCloser: Similar wrapper for io.Reader
func ToCloser ¶
ToCloser converts any type that implements io.Closer to the io.Closer interface. This is useful for type erasure when you need to work with the interface type rather than a concrete implementation.
Example:
import (
"os"
"io"
)
f, _ := os.Open("file.txt")
var closer io.Closer = file.ToCloser(f)
defer closer.Close()
// closer is now of type io.Closer
func ToReadCloser ¶ added in v2.2.74
func ToReadCloser[C io.ReadCloser](c C) io.ReadCloser
ToReadCloser converts any type that implements io.ReadCloser to the io.ReadCloser interface. This is useful for type erasure when you need to work with the interface type rather than a concrete implementation.
Example:
import (
"os"
"io"
)
f, _ := os.Open("input.txt")
var rc io.ReadCloser = file.ToReadCloser(f)
defer rc.Close()
// rc is now of type io.ReadCloser
func ToReader ¶
ToReader converts any type that implements io.Reader to the io.Reader interface. This is useful for type erasure when you need to work with the interface type rather than a concrete implementation.
Example:
import (
"bytes"
"io"
)
buf := bytes.NewBuffer([]byte("hello"))
var reader io.Reader = file.ToReader(buf)
// reader is now of type io.Reader
func ToWriteCloser ¶ added in v2.2.74
func ToWriteCloser[C io.WriteCloser](c C) io.WriteCloser
ToWriteCloser converts any type that implements io.WriteCloser to the io.WriteCloser interface. This is useful for type erasure when you need to work with the interface type rather than a concrete implementation.
Example:
import (
"os"
"io"
)
f, _ := os.Create("output.txt")
var wc io.WriteCloser = file.ToWriteCloser(f)
defer wc.Close()
wc.Write([]byte("hello"))
// wc is now of type io.WriteCloser
func ToWriter ¶
ToWriter converts any type that implements io.Writer to the io.Writer interface. This is useful for type erasure when you need to work with the interface type rather than a concrete implementation.
Example:
import (
"bytes"
"io"
)
buf := &bytes.Buffer{}
var writer io.Writer = file.ToWriter(buf)
// writer is now of type io.Writer
Types ¶
type Endomorphism ¶ added in v2.1.8
type Endomorphism[A any] = endomorphism.Endomorphism[A]
Endomorphism represents a function from a type to itself: A -> A. This is a type alias for endomorphism.Endomorphism[A].
In the context of the file package, this is used for functions that transform strings (paths) into strings (paths), such as the Join function.
An endomorphism has useful algebraic properties:
- Identity: There exists an identity endomorphism (the identity function)
- Composition: Endomorphisms can be composed to form new endomorphisms
- Associativity: Composition is associative
Example:
import F "github.com/IBM/fp-go/v2/function"
// Join returns an Endomorphism[string]
addConfig := file.Join("config.json") // Endomorphism[string]
addLogs := file.Join("logs") // Endomorphism[string]
// Compose endomorphisms
addConfigLogs := F.Flow2(addLogs, addConfig)
result := addConfigLogs("/var")
// result is "/var/logs/config.json"
func Join ¶
func Join(name string) Endomorphism[string]
Join appends a filename to a root path using the operating system's path separator. Returns a curried function that takes a root path and joins it with the provided name.
This function follows the "data last" principle, where the data (root path) is provided last, making it ideal for use in functional pipelines and partial application. The name parameter is fixed first, creating a reusable path builder function.
This is useful for creating reusable path builders in functional pipelines.
Example:
import F "github.com/IBM/fp-go/v2/function"
// Data last: fix the filename first, apply root path later
addConfig := file.Join("config.json")
path := addConfig("/etc/myapp")
// path is "/etc/myapp/config.json" on Unix
// path is "\etc\myapp\config.json" on Windows
// Using with Pipe (data flows through the pipeline)
result := F.Pipe1("/var/log", file.Join("app.log"))
// result is "/var/log/app.log" on Unix
// Chain multiple joins
result := F.Pipe2(
"/root",
file.Join("subdir"),
file.Join("file.txt"),
)
// result is "/root/subdir/file.txt"