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

Reply via email to