Something like this might also be similar to what you want, not exactly the
same as the Rust though. This approach does work in Nim like Araq said, but you
also have the additional flexibility of considering using a DSL for your API
instead, it might be more ergonomic.
import std/[options, macros]
type
Direction = enum
Input, Output
GpioConfig[
TEnabled: static bool,
TDirection: static Option[Direction]
] = object
proc initGpioConfig(): GpioConfig[false, none(Direction)] =
discard
proc enable(_: GpioConfig[false, none(Direction)]): GpioConfig[true,
none(Direction)] =
discard
proc disable[T](_: GpioConfig[true, T]): GpioConfig[false, none(Direction)]
=
discard
proc setDirection(_: GpioConfig[true, none(Direction)], direction: static
Direction): GpioConfig[true, some(direction)] =
discard
var config = initGpioConfig()
assert not compiles config.disable()
assert not compiles config.setDirection(Input)
var enabled = config.enable()
var redisabled = enabled.disable()
var input = enabled.setDirection(Input)
assert input is GpioConfig[true, some(Input)]
Run