nim-ffi/ffi/codegen/string_helpers.nim
Ivan FB ac303a707e
Start using CBOR (#23)
Co-authored-by: NagyZoltanPeter <113987313+NagyZoltanPeter@users.noreply.github.com>
Co-authored-by: Gabriel Cruz <8129788+gmelodie@users.noreply.github.com>
2026-05-16 01:08:42 +02:00

46 lines
1.6 KiB
Nim

## Identifier-casing helpers shared by the codegen modules and the FFI macro.
## All three operate on `Rune` via `std/unicode` so non-ASCII identifiers
## (rare in FFI symbols but possible in field names) round-trip correctly.
import std/[strutils, unicode]
proc toLower*(s: string): string =
## Unicode-aware lowercase for an entire string. Wraps `std/unicode`'s
## per-Rune `toLower` so callers don't have to iterate manually.
var buf = ""
for r in runes(s):
buf.add($r.toLower())
return buf
proc camelToSnakeCase*(s: string): string =
## Converts camelCase to snake_case. Inserts `_` before each uppercase rune
## that's not the first character and lowercases everything.
## e.g. "delayMs" → "delay_ms", "timerName" → "timer_name"
var snake = ""
var first = true
for r in runes(s):
if r.isUpper() and not first:
snake.add('_')
snake.add($r.toLower())
first = false
return snake
proc capitalizeFirstLetter*(s: string): string =
## Returns `s` with its first rune uppercased; the rest is left unchanged.
## e.g. "abc" → "Abc", "" → "", "Abc" → "Abc"
if s.len == 0:
return s
var runesSeq = toRunes(s)
runesSeq[0] = runesSeq[0].toUpper()
return $runesSeq
proc snakeToPascalCase*(s: string): string =
## Converts snake_case identifiers to PascalCase: split on `_`, uppercase
## the first rune of each part, concatenate.
## e.g. "testlib_create" → "TestlibCreate", "hello_world" → "HelloWorld"
let parts = s.split('_')
var pascal = ""
for p in parts:
pascal.add capitalizeFirstLetter(p)
return pascal