As @shirleyquirk suggested, you could use an object with a string field. That
would be very helpful if you need to be treating the value like a string often.
This would be what a full string-compatible example would look like, complete
with implicit conversion:
type HandLike* {.requiresInit.} = object
## String of 5 characters containing only {'A', 'K', 'Q', 'T', '2',
'3', '4', '5', '6', '7', '8', '9'}
val: string
proc hl*(str: string): HandLike =
## Converts a `string` to `HandLike`
if str.len != 5:
raise newException(ValueError, "HandLike must be 5 characters long")
for i in 0 ..< str.len:
let c = str[i]
if c != 'A' and c != 'K' and c != 'Q' and c != 'T' and (c < '2' or
c > '9'):
raise newException(ValueError, "HandLike cannot contain \"" & c
& "\" characters")
return HandLike(val: str)
# Using the `converter` keyword, we can implicitly convert `HandLike` to
`string` without any extra steps
converter `$`*(this: HandLike): string =
return this.val
proc firstCard*(hand: HandLike): char =
## Returns the first card of a hand as a `char`
# As you can see, we can use the `[]` operator on `hand` because it's
automatically being converted to `string` for us
return hand[0]
let myHand = hl"AQT25"
echo firstCard(myHand) # 'A'
Run