Fabrica-Util CamelCase Conversion: Underlying Implementation for Game-Dev Naming Conventions
Fabrica-Util implements CamelCase conversion through a specialized camelcase package that uses strings.Builder for zero-allocation concatenation, Unicode-aware case handling via the unicode package, and pre-built strings.Replacer objects to manage common initialisms like API and UUID.
The go-pantheon/fabrica-util repository provides essential utilities for game development workflows, including robust naming convention transformations. Its CamelCase conversion implementation handles bidirectional translation between snake_case, PascalCase, and camelCase formats while intelligently preserving common abbreviations. The core logic resides in the camelcase package, offering deterministic performance characteristics critical for code generation pipelines and configuration management.
Core Conversion Functions
The package exposes three primary functions in camelcase/camel.go, each optimized for specific naming convention requirements.
ToUpperCamel Implementation
The ToUpperCamel function converts any identifier to PascalCase (e.g., hello_world → HelloWorld). The implementation follows a four-step process:
- Split the input string on underscore characters.
- Capitalize the first rune of each non-empty segment using
unicode.ToUpper. - Concatenate segments using a
strings.Builderto achieve zero-allocation string building. - Apply the
camelCommonAbbrReplacerto expand known abbreviations (e.g.,id→ID,http→HTTP).
ToLowerCamel Implementation
The ToLowerCamel function produces lowerCamelCase (e.g., hello_world → helloWorld). This function reuses the ToUpperCamel logic entirely, then applies unicode.ToLower to the first rune of the result. The same abbreviation replacer executes after the initial lowercasing step, ensuring that initialisms remain properly capitalized within the identifier.
ToUnderScore Implementation
The ToUnderScore function performs the inverse operation, converting camelCase or PascalCase back to snake_case (e.g., HelloWorld → hello_world). The algorithm executes in three phases:
- Abbreviation expansion using
abbrCommonReplacerto convert known initialisms to lowercase forms (e.g.,ID→id). - Boundary detection by iterating over the rune slice and inserting an underscore before every uppercase letter or digit that follows a lowercase letter or digit.
- Lowercasing of all identified uppercase runes while copying remaining characters unchanged.
Abbreviation Handling with Initialisms
During package initialization (init()), the module constructs two specialized strings.Replacer objects from a curated commonInitialisms slice containing tokens like API, HTML, UUID, and ID.
camelCommonAbbrReplacer: Maps Pascal-cased versions of abbreviations back to their all-caps form. This ensures thatToUpperCamelandToLowerCamelmaintain conventional capitalization for recognized initialisms.abbrCommonReplacer: Performs the inverse operation forToUnderScore, converting all-caps tokens to lowercase before underscore insertion.
Both replacers are built once during initialization, making the conversion functions O(1) with respect to the number of abbreviations. The commonInitialisms slice is sorted by length (longer strings first) to prevent accidental prefix replacement, ensuring that UUID processes before ID.
Performance and Architectural Optimizations
The implementation prioritizes efficiency through several architectural decisions:
- Zero-allocation concatenation: The
toUpperCamelfunction usesstrings.Builderto avoid repeated string allocations during segment assembly. - Unicode-aware processing: All case transformations utilize the
unicodepackage, guaranteeing correct behavior for non-ASCII characters and international identifiers. - Deterministic behavior: The sorted initialism list and pre-compiled replacers ensure consistent output across identical inputs, critical for game development asset pipelines.
Practical Usage Examples
The following example demonstrates all three conversion functions in action:
package main
import (
"fmt"
"github.com/go-pantheon/fabrica-util/camelcase"
)
func main() {
// UpperCamel (PascalCase)
fmt.Println(camelcase.ToUpperCamel("player_health")) // -> PlayerHealth
fmt.Println(camelcase.ToUpperCamel("http_response_code")) // -> HTTPResponseCode
// LowerCamel
fmt.Println(camelcase.ToLowerCamel("player_health")) // -> playerHealth
fmt.Println(camelcase.ToLowerCamel("http_response_code")) // -> httpResponseCode
// Underscore (snake_case)
fmt.Println(camelcase.ToUnderScore("PlayerHealth")) // -> player_health
fmt.Println(camelcase.ToUnderScore("HTTPResponseCode")) // -> http_response_code
}
Explanation of the transformations:
ToUpperCamelcapitalizes each word segment and restores known abbreviations to their conventional uppercase form.ToLowerCamelfollows the same transformation path but forces the initial rune to lowercase.ToUnderScoredetects capital letter boundaries, inserts underscores, and lowercases the entire identifier while expanding abbreviations.
Summary
- The CamelCase conversion logic lives in
camelcase/camel.gowithin thego-pantheon/fabrica-utilrepository. - Three primary functions—
ToUpperCamel,ToLowerCamel, andToUnderScore—handle bidirectional transformation between naming conventions. - Abbreviation awareness is implemented via pre-built
strings.Replacerobjects constructed from a sortedcommonInitialismslist during package initialization. - Zero-allocation optimization is achieved through
strings.Builderusage and efficient rune manipulation. - Unicode compliance ensures correct handling of international characters beyond standard ASCII ranges.
Frequently Asked Questions
How does fabrica-util handle common abbreviations during CamelCase conversion?
The package maintains a curated list of common initialisms (such as API, HTML, and UUID) in the commonInitialisms slice. During the init() function, it constructs two strings.Replacer objects: one that maps lowercase/Pascal abbreviations to their uppercase forms for CamelCase output, and another that converts uppercase abbreviations to lowercase for snake_case output. This ensures that http_response becomes HTTPResponse rather than HttpResponse.
What is the time complexity of the CamelCase conversion functions?
The conversion functions operate in O(n) time relative to the input string length, where n represents the number of runes. Because the strings.Replacer objects are constructed once during package initialization, abbreviation handling is O(1) with respect to the number of initialisms. The use of strings.Builder ensures that concatenation overhead remains linear rather than quadratic.
How does the ToUnderScore function detect word boundaries?
The ToUnderScore function iterates over the input string as a rune slice and applies a boundary detection rule: it inserts an underscore before every uppercase letter or digit that immediately follows a lowercase letter or digit. This heuristic correctly identifies transitions like HelloWorld → hello_world and JSONData → json_data (after abbreviation processing). The algorithm processes the string in a single pass while building the output.
Where is the CamelCase conversion implementation located in the repository?
The complete implementation resides in [camelcase/camel.go](https://github.com/go-pantheon/fabrica-util/blob/main/camelcase/camel.go) within the go-pantheon/fabrica-util repository. Key sections include the initialism setup (lines 9–16), the init and buildReplacers functions (lines 23–41), the core conversion functions (lines 43–70), and the underscore conversion logic (lines 99–128). Comprehensive unit tests and benchmarks are available in camelcase/camel_test.go.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →