DEV Community

Ushakov Michael
Ushakov Michael

Posted on

Beyond fmt: Building a Flexible Text Builder in Go with Wissance/stringFormatter

Introduction

Go is renowned for its performance and simplicity, especially in system programming and web services. Its standard fmt package is a workhorse for string formatting. However, when building complex text output—like dynamic configuration strings, detailed logs, or formatted reports—developers often find themselves writing repetitive code or wrestling with fmt.Sprintf's verb-based syntax.

This article explores the Wissance/stringFormatter project, an open-source Go module that reimagines text building. It introduces a familiar, template-based approach (think C# or Python) that is not only syntactically convenient but, according to its benchmarks, also outperforms the standard fmt package in several scenarios. We will dive into its core features, from positional and named argument formatting to advanced data type handling, and see how it positions itself as a true "flexible text builder."

Core Features: Template Syntax and Performance

at its heart, stringFormatter provides a high-performance alternative to fmt for building strings from templates. Its main appeal is the use of familiar placeholder syntax {0}, {name}, which many developers find more readable for complex templates.

Flexible Formatting Methods

The library offers two primary methods for text construction, catering to different use cases:

Positional Formatting with Format

This function uses indexed placeholders like {0}, {1}. It's straightforward for scenarios where the argument order is clear.

result := stringFormatter.Format("Hello {0}, welcome to {1}!", "User", "GoApp")
Enter fullscreen mode Exit fullscreen mode
// Output: "Hello User, welcome to GoApp!"
Enter fullscreen mode Exit fullscreen mode

Named Formatting with FormatComplex: This method shines when building strings with many parameters or when the template needs to be self-documenting. By passing a map[string]any, you can use descriptive names like {user} or {port}.

params := map[string]any{"user": "admin", "port": 8080, "ssl": true}
result := stringFormatter.FormatComplex("Config: user={user}, port={port}, ssl={ssl}", params)
Enter fullscreen mode Exit fullscreen mode
// Output: "Config: user=admin, port=8080, ssl=true"
Enter fullscreen mode Exit fullscreen mode

This approach makes templates significantly easier to read and maintain.

Advanced Argument Formatting

What elevates stringFormatter from a simple templating tool to a "flexible text builder" is its support for advanced formatting directives directly within the placeholders. You can control the output representation of various data types:

Numeric Formatting: It supports binary (B), hexadecimal (X), and octal (o) representations, complete with padding.

stringFormatter.Format("{0:B8} in hex is {0:X2}", 15)
Enter fullscreen mode Exit fullscreen mode
// Output: "00001111 in hex is 0f"
Enter fullscreen mode Exit fullscreen mode

Floating-Point Precision: Control decimal places or use scientific notation:

stringFormatter.Format("Value: {0:F4} or {0:E2}", 10.456789)
Enter fullscreen mode Exit fullscreen mode
// Output: "Value: 10.4568 or 1.05e+01"
Enter fullscreen mode Exit fullscreen mode

Slice Formatting: Join slices with a custom separator effortlessly using the L directive.

ids := []int{1, 2, 3, 4}
stringFormatter.Format("IDs: {0:L-}", ids) 
Enter fullscreen mode Exit fullscreen mode
// Output: "IDs: 1-2-3-4"
Enter fullscreen mode Exit fullscreen mode

Code Style Conversion: Dynamically convert between naming conventions like snake_case, camelCase, and kebab-case using the c directive.

stringFormatter.Format("Converted: {0:c:snake}", "MyVariable")
Enter fullscreen mode Exit fullscreen mode
// Output: "Converted: my_variable"
Enter fullscreen mode Exit fullscreen mode

Beyond Formatting: Utility Functions
The project also packages other useful text utilities, reinforcing its role as a comprehensive text manipulation toolkit:

MapToString: Converts a map into a formatted string, allowing you to define the pattern for each key-value pair.

SliceToString / SliceSameTypeToString: Provides high-performance slice-to-string conversion, which benchmarks show as significantly faster than manual loops using fmt.

Conclusion

The Wissance/stringFormatter project offers a compelling alternative for Go developers who frequently engage in complex string building. By combining a clean, template-based syntax with advanced formatting options and a focus on performance, it successfully creates a more flexible and expressive text builder than what's readily available in the standard library.

Whether you need to generate dynamic configuration files, create human-readable reports, or simply want a faster way to format slices and maps, stringFormatter provides a robust, well-tested, and high-performance solution. It demonstrates that sometimes, looking beyond the standard library's tools can lead to cleaner code and better performance.

Top comments (0)