Tier: Foundational · Status: Full · Java original:
firefly-common-utils· .NET project:FireflyFramework.Utils
utils is the framework's general-purpose helper grab-bag — the
small set of primitives every module reaches for and that don't fit
into a more specific module:
- Try / TryOf — panic-safe function execution with the panic value
surfaced as an
error. - Retry.Do / DoValue — exponential-backoff retry with jitter and a pluggable retryable-error predicate.
- Slugify — URL-safe lower-case slug from any UTF-8 string, NFD-normalising and dropping combining marks.
- AES-256-GCM crypto —
EncryptAESGCM,DecryptAESGCM, plusDeriveKey256(SHA-256 KDF) and base64 helpers. - Templates —
RenderText(text/template) andRenderHTML(html/templatewith auto-escaping).
Without a shared helper module, every other module ends up
re-implementing the same patterns slightly differently — Try-style
panic recovery is a one-off variant in three places, retry policies
disagree on jitter semantics, and crypto wrappers leak the underlying
nonce semantics. utils lifts these into a single canonical set so
the platform behaves uniformly.
| Group | Function / type |
|---|---|
| Try | Try(fn) error, TryOf[T](fn) (T, error) — panic-recovering wrappers |
| Retry | Do(ctx, cfg, fn) error, DoValue[T](ctx, cfg, fn) (T, error) |
| Retry | RetryConfig{MaxAttempts, InitialDelay, MaxDelay, Multiplier, JitterRatio, RetryableErr} |
| Slug | Slugify(s string) string |
| Crypto | DeriveKey256(passphrase) []byte |
| Crypto | EncryptAESGCM(key, plaintext) ([]byte, error) |
| Crypto | DecryptAESGCM(key, payload) ([]byte, error) — fails with ErrCipherText |
| Crypto | EncodeBase64(b), DecodeBase64(s) — URL-safe (with or without padding) |
| Templates | RenderText(name, source, data) (string, error) |
| Templates | RenderHTML(name, source, data) (string, error) — auto-escaping |
import (
"context"
"github.com/fireflyframework/fireflyframework-go/utils"
)
cfg := utils.DefaultRetry() // 3 attempts, 100ms→5s, ×2, ±20% jitter
result, err := utils.DoValue(ctx, cfg, func(ctx context.Context) (Order, error) {
return remote.PlaceOrder(ctx, req)
})
slug := utils.Slugify("Cañón del Río") // "canon-del-rio"
key := utils.DeriveKey256("super-secret")
ct, _ := utils.EncryptAESGCM(key, []byte("hi"))
pt, _ := utils.DecryptAESGCM(key, ct) // []byte("hi")
body, _ := utils.RenderHTML("welcome", `<p>Hello {{.Name}}</p>`, m)cd utils
go test ./...Suite covers panic-as-error, retry attempts + non-retryable short-circuit, slug edge cases (combining marks, leading/trailing separators, Unicode), AES-GCM round-trip + tamper detection, base64 round-trip, and HTML-escape preservation.