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_worldHelloWorld). The implementation follows a four-step process:

  1. Split the input string on underscore characters.
  2. Capitalize the first rune of each non-empty segment using unicode.ToUpper.
  3. Concatenate segments using a strings.Builder to achieve zero-allocation string building.
  4. Apply the camelCommonAbbrReplacer to expand known abbreviations (e.g., idID, httpHTTP).

ToLowerCamel Implementation

The ToLowerCamel function produces lowerCamelCase (e.g., hello_worldhelloWorld). 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., HelloWorldhello_world). The algorithm executes in three phases:

  1. Abbreviation expansion using abbrCommonReplacer to convert known initialisms to lowercase forms (e.g., IDid).
  2. 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.
  3. 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 that ToUpperCamel and ToLowerCamel maintain conventional capitalization for recognized initialisms.
  • abbrCommonReplacer: Performs the inverse operation for ToUnderScore, 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 toUpperCamel function uses strings.Builder to avoid repeated string allocations during segment assembly.
  • Unicode-aware processing: All case transformations utilize the unicode package, 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:

  • ToUpperCamel capitalizes each word segment and restores known abbreviations to their conventional uppercase form.
  • ToLowerCamel follows the same transformation path but forces the initial rune to lowercase.
  • ToUnderScore detects capital letter boundaries, inserts underscores, and lowercases the entire identifier while expanding abbreviations.

Summary

  • The CamelCase conversion logic lives in camelcase/camel.go within the go-pantheon/fabrica-util repository.
  • Three primary functionsToUpperCamel, ToLowerCamel, and ToUnderScore—handle bidirectional transformation between naming conventions.
  • Abbreviation awareness is implemented via pre-built strings.Replacer objects constructed from a sorted commonInitialisms list during package initialization.
  • Zero-allocation optimization is achieved through strings.Builder usage 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 HelloWorldhello_world and JSONDatajson_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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →