Skip to content

Lightweight Go library that provides comprehensive string manipulation, type conversion, formatting, and error handling with a fluid API, specifically designed for small devices and web applications using TinyGo as the target compiler.

License

Notifications You must be signed in to change notification settings

cdvelop/tinystring

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TinyString

Project Badges

TinyString is a lightweight Go library that provides comprehensive string manipulation, type conversion, formatting, and multilingual error handling with a fluid API, specifically designed for small devices and web applications using TinyGo as the target compiler.

Key Features

  • 🚀 Fluid and chainable API - Easy to use and readable operations
  • 📝 Complete string toolkit - Transformations, conversions, formatting, and error handling
  • 🌍 Multilingual error messages - Built-in dictionary system with 9 languages
  • 🧵 Concurrency safe - Thread-safe operations for concurrent environments
  • 📦 Zero dependencies - No fmt, strings, strconv, or errors imports
  • 🎯 TinyGo optimized - Manual implementations for minimal binary size
  • 🌐 WebAssembly-first - Designed for modern web deployment
  • 🔄 Universal type support - Works with strings, numbers, booleans, and slices
  • Performance focused - Predictable allocations and custom optimizations

Installation

go get github.com/cdvelop/tinystring

Usage

import . "github.com/cdvelop/tinystring"

// Quick start - Basic conversion and transformation
text := Convert("Hóla Múndo").Tilde().ToLower().String() // out: "hola mundo"

// Working with different data types
numText := Convert(42).String()     // out: "42"
boolText := Convert(true).String()  // out: "true"

// Memory-efficient approach using string pointers
original := "Él Múrcielago Rápido"
Convert(&original).Tilde().CamelLow().Apply()
// original is now: "elMurcielagoRapido"

// Efficient, Unified builder and chaining example usage in loops and reuse, with accent normalization (Tilde)
items := []string{"  ÁPPLE  ", "  banána  ", "  piñata  ","  ÑANDÚ  "}
builder := Convert() // without params reused buffer = optimal performance
for i, item := range items {
    processed := Convert(item).
        TrimSpace(). // TrimSpace whitespace
        Tilde(). // Normalize accents
        ToLower(). // Convert to lowercase
        Capitalize(). // Capitalize first letter
        String() // Finalize the string
    builder.Write(processed)
    if i < len(items)-1 {
        builder.Write(" - ")
    }
}

out := builder.String() // Finalize the string hiding the error
out, err := builder.StringErr() // OR finalize with error handling

// out: "Apple - Banana - Piñata - Ñandu", err: nil

📚 Standard Library Equivalents

🔤 strings Package

Replace common strings package functions with TinyString equivalents:

Go Standard TinyString Equivalent
strings.Builder c:= Convert() c.Write(a) c.Write(b) c.String()
strings.Contains() Contains(s, substr)
strings.Index() Index(s, substr)
strings.LastIndex() LastIndex(s, substr)
strings.Join() Convert(slice).Join(sep).String()
strings.Repeat() Convert(s).Repeat(n).String()
strings.Replace() Convert(s).Replace(old, new).String()
strings.Split() Convert(s).Split(sep).String()
strings.ToLower() Convert(s).ToLower().String()
strings.ToUpper() Convert(s).ToUpper().String()
strings.TrimSpace() Convert(s).TrimSpace().String()
strings.TrimPrefix() Convert(s).TrimPrefix(prefix).String()
strings.TrimSuffix() Convert(s).TrimSuffix(suffix).String()
strings.HasPrefix() HasPrefix(s, prefix)
strings.HasSuffix() HasSuffix(s, suffix)
filepath.Base() PathBase(path)

Other String Transformations

Convert("hello world").CamelLow().String() // out: "helloWorld"
Convert("hello world").CamelUp().String()  // out: "HelloWorld"
Convert("hello world").SnakeLow().String() // out: "hello_world"
Convert("hello world").SnakeUp().String()  // out: "HELLO_WORLD"

String Search & Operations

// Search and count
pos := Index("hello world", "world")                  // out: 6 (first occurrence)
found := Contains("hello world", "world")              // out: true
count := Count("abracadabra", "abra")       // out: 2

// Prefix / Suffix checks
isPref := HasPrefix("hello", "he")          // out: true
isSuf := HasSuffix("file.txt", ".txt")      // out: true

// Note: this library follows the standard library semantics for prefixes/suffixes:
// an empty prefix or suffix is considered a match (HasPrefix(s, "") == true,
// HasSuffix(s, "") == true).

// Find last occurrence (useful for file extensions)
pos := LastIndex("image.backup.jpg", ".")             // out: 12
if pos >= 0 {
    extension := "image.backup.jpg"[pos+1:]           // out: "jpg"
}

// ⚠️ Note: Index, Contains and LastIndex are global functions, not methods.
// Do NOT use: Convert(s).Contains(substr) // ❌ Incorrect, will not compile
// Use:        Index(s, substr)            // ✅ Correct
//             Contains(s, substr)         // ✅ Correct
//             LastIndex(s, substr)        // ✅ Correct


// PathBase
PathBase("/a/b/c.txt") // -> "c.txt"
PathBase("folder/file.txt")   // -> "file.txt"
PathBase("")           // -> "."
PathBase("c:\file program\app.exe") // -> "app.exe"

// Replace operations
Convert("hello world").Replace("world", "Go").String() // out: "hello Go"
Convert("test 123 test").Replace(123, 456).String()    // out: "test 456 test"

String Splitting & Joining

// Split strings (always use Convert(...).Split(...))
parts := Convert("apple,banana,cherry").Split(",")
// out: []string{"apple", "banana", "cherry"}

parts := Convert("hello world new").Split()  // Handles whitespace
// out: []string{"hello", "world", "new"}

// Join slices
Convert([]string{"Hello", "World"}).Join().String()    // out: "Hello World"
Convert([]string{"a", "b", "c"}).Join("-").String()    // out: "a-b-c"

String Trimming & Cleaning

// TrimSpace operations
Convert("  hello  ").TrimSpace().String()                    // out: "hello"
Convert("prefix-data").TrimPrefix("prefix-").String()   // out: "data"
Convert("file.txt").TrimSuffix(".txt").String()         // out: "file"

// Repeat strings
Convert("Go").Repeat(3).String()                        // out: "GoGoGo"

🔢 strconv Package

Replace strconv package functions for type conversions:

Go Standard TinyString Equivalent
strconv.Itoa() Convert(i).String()
strconv.Atoi() Convert(s).Int()
strconv.ParseFloat() Convert(s).Float64()
strconv.ParseBool() Convert(s).Bool()
strconv.FormatFloat() Convert(f).Round(n).String()
strconv.Quote() Convert(s).Quote().String()

Type Conversions

// String to numbers => Int,Int32,Int64,Uint,Uint32,Uint64,Float32,Float64 eg:
result, err := Convert("123").Int()        // out: 123, nil
result, err := Convert("456").Uint()       // out: 456, nil  
result, err := Convert("3.14").Float64()     // out: 3.14, nil

// Numbers to string
Convert(42).String()      // out: "42"
Convert(3.14159).String() // out: "3.14159"

// Boolean conversions
result, err := Convert("true").Bool()  // out: true, nil
result, err := Convert(42).Bool()      // out: true, nil (non-zero = true)
result, err := Convert(0).Bool()       // out: false, nil

// String quoting
Convert("hello").Quote().String()           // out: "\"hello\""
Convert("say \"hello\"").Quote().String()  // out: "\"say \\\"hello\\\"\""

Number Formatting

// Decimal rounding: keep N decimals, round or truncate
// By default, rounds using "round half to even" (bankers rounding)
// Pass true as the second argument to truncate (no rounding), e.g.:
Convert("3.14159").Round(2).String()        // "3.14" (rounded)
Convert("3.155").Round(2).String()          // "3.16" (rounded)
Convert("3.14159").Round(2, true).String()  // "3.14" (truncated, NOT rounded)
Convert("3.159").Round(2, true).String()    // "3.15" (truncated, NOT rounded)

// Formatting with thousands separator (EU default)
Convert(2189009.00).Thousands().String()        // out: "2.189.009"
// Anglo/US style (comma, dot)
Convert(2189009.00).Thousands(true).String()    // out: "2,189,009"

🖨️ fmt Package

Replace fmt package functions for formatting:

Go Standard TinyString Equivalent
fmt.Sprintf() Fmt(format, args...)
fmt.Sprint() Convert(v).String()
fmt.Fprintf() Fprintf(w, format, args...)
fmt.Sscanf() Sscanf(src, format, args...)

String Formatting

// Printf-style formatting
result := Fmt("Hello %s, you have %d messages", "John", 5)
// out: "Hello John, you have 5 messages"

// Multiple format specifiers
result := Fmt("Number: %d, Float: %.2f, Bool: %v", 42, 3.14159, true)
// out: "Number: 42, Float: 3.14, Bool: true"

// Advanced formatting (hex, binary, octal)
result := Fmt("Hex: %x, Binary: %b, Octal: %o", 255, 10, 8)
// out: "Hex: ff, Binary: 1010, Octal: 10"

// Write formatted output to io.Writer
var buf bytes.Buffer
Fprintf(&buf, "Hello %s, count: %d\n", "world", 42)

// Write to file
file, _ := os.Create("output.txt")
Fprintf(file, "Data: %v\n", someData)

// Parse formatted text from string (like fmt.Sscanf)
var pos int
var name string
n, err := Sscanf("!3F question", "!%x %s", &pos, &name)
// n = 2, pos = 63, name = "question", err = nil

// Parse complex formats
var code, unicode int
var word string
n, err := Sscanf("!3F U+003F question", "!%x U+%x %s", &code, &unicode, &word)
// n = 3, code = 63, unicode = 63, word = "question", err = nil

❌ errors Package

Replace errors package functions for error handling with multilingual support:

Go Standard TinyString Equivalent
errors.New() Err(message)
fmt.Errorf() Errf(format, args...)

Error Creation

// Multiple error messages and types
err := Err("invalid format", "expected number", 404)
// out: "invalid format expected number 404"

// Formatted errors (like fmt.Errorf)
err := Errf("invalid value: %s at position %d", "abc", 5)
// out: "invalid value: abc at position 5"

🚀 TinyString Exclusive Features

🌍 TinyString: Multilingual & Translation Support

TinyString enables multilingual error messages using reusable dictionary terms. It supports 9 languages and allows global or inline language selection.

// Set and get current language code
code := OutLang(ES) // returns "ES"
code = OutLang()    // auto-detects and returns code (e.g. "EN")

err := Err(D.Format, D.Invalid)
// → "formato inválido"

// return strings
msg := Translate(FR, D.Format, D.Invalid).String()
// → "format invalide"

// Force French
err = Err(FR, D.Empty, D.String)
// → "vide chaîne"

See dictionary.go for built-in words. Combine D. (default terms) and custom dictionaries for flexible messaging.

📘 Full documentation available in docs/TRANSLATE.md

🏷️ Message Type Detection

TinyString provides automatic message type classification to help identify the nature of text content. The system detects common message types like errors, warnings, success messages, and information using zero-allocation buffer-based pattern matching.

// Before: messagetype library usage
message := Translate(msgs...).String()
msgType := messagetype.DetectMessageType(message)

// After: tinystring Single operation with StringType() (zero allocations)
message, msgType := Translate(msgs...).StringType()

// Real example - Progress callback with message classification
progressCallback := func(msgs ...any) {
    message, msgType := Translate(msgs...).StringType()
    if msgType.IsError() {
        handleError(message)
    } else {
        logMessage(message, msgType)
    }
}

// Message type constants available via Msg struct
if msgType.IsError() {
    // Handle error case
}

// Available message types:
// Msg.Normal  - Default type for general content
// Msg.Info    - Information messages  
// Msg.Error   - Error messages and failures
// Msg.Warning - Warning and caution messages
// Msg.Success - Success and completion messages

// Zero allocations - reuses existing conversion buffers
// Perfect for logging, UI status messages, and error handling

✂️ Smart Truncation

// Basic truncation with ellipsis
Convert("Hello, World!").Truncate(10).String()       
// out: "Hello, ..."

// Name truncation for UI display
Convert("Jeronimo Dominguez").TruncateName(3, 15).String()
// out: "Jer. Dominguez"

// Advanced name handling
Convert("Juan Carlos Rodriguez").TruncateName(3, 20).String()
// out: "Jua. Car. Rodriguez"

🔧 Advanced Utilities

// Key-value parsing with the new API:
value, err := Convert("user:admin").KV()            // out: "admin", nil
value, err := Convert("count=42").KV("=")          // out: "42", nil

// Struct tag value extraction (TagValue):
value, found := Convert(`json:"name" Label:"Nombre"`).TagValue("Label") // out: "Nombre", true
value, found := Convert(`json:"name" Label:"Nombre"`).TagValue("xml")   // out: "", false



About

Lightweight Go library that provides comprehensive string manipulation, type conversion, formatting, and error handling with a fluid API, specifically designed for small devices and web applications using TinyGo as the target compiler.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published