interface_implements
implements macro creates toInterface proc.
Summary
| Latest Version | Unknown |
|---|---|
| License | MIT |
| CI Status | Failing |
| Downloads | 0 |
| Last Indexed | 2026-07-21 05:24 |
Tags
Installation
nimble install interface_implements
choosenim install interface_implements
git clone https://github.com/itsumura-h/nim-interface-implements
OS Compatibility
| Platform | Linux | macOS | Windows | FreeBSD | OpenBSD | NetBSD | Android | iOS | WASM | Embedded |
|---|---|---|---|---|---|---|---|---|---|---|
| interface_implements | ✓ | ✓ | ✓ | - | - | - | - | - | - | - |
Source
| Repository | https://github.com/itsumura-h/nim-interface-implements |
|---|---|
| Homepage | https://github.com/itsumura-h/nim-interface-implements |
| Registry Source | nimble_official |
README
interface-implements
There are two ways to achieve polymorphism in Nim. One is to create toInterface converter and another is dynamic dispatch.
toInterface converter
interface definition
type IRepository* = object
exec*: proc(msg:string):string
implementation
type Repository* = object
proc exec(self:Repository, msg:string):string =
return &"Repository {msg}"
converter toInterface*(self:Repository):IRepository =
return IRepository(
exec: proc(msg:string):string = self.exec(msg)
)
dynamic dispatch
interface definition
type IRepository* = object of RootObj
method exec*(self:IRepository, msg:string):string {.base.} = raise newException(CatchableError, "error")
implementation
type Repository* = object of IRepository
method exec*(self:Repository, msg:string):string =
return &"Repository {msg}"
install
nimble install interface_implements
implements
implements macro creates toInterface converter.
import interface_implements
implements Repository, IRepository:
proc func1(self:Repository, msg:string):string =
return "Repository1 " & msg
proc func2(self:Repository, number:int):string =
return "Repository2 " & $number
This is converted to bellow.
proc func1(self:Repository, msg:string):string =
return "Repository " & msg
proc func2(self:Repository, number:int):string =
return "Repository2 " & $number
converter toInterface*(self:Repository):IRepository =
return IRepository(
func1: proc(msg:string):string = self.func1(msg),
func2: proc(number:int):string = self.func2(number)
)
API
macro implements*(implName, interfaceName, procs:untyped):untyped
Example
repository_interface.nim
type IRepository* = object
exec*: proc(msg:string):string
mock_repository.nim
import interface_implements
import ./repository_interface
type MockRepository = object
proc newMockRepository*():MockRepository =
return MockRepository()
implements MockRepository, IRepository:
proc exec(self:MockRepository, msg:string):string =
return "MockRepository " & msg
repository.nim
import interface_implements
import ./repository_interface
type Repository = object
proc newRepository*():Repository =
return Repository()
implements Repository, IRepository:
proc exec(self:Repository, msg:string):string =
return "Repository " & msg
usecase.nim
import ./repository_interface
type Usecase = object
repository: IRepository
func newUsecase*(repository:IRepository):Usecase =
return Usecase(repository:repository)
proc exec*(self:Usecase, msg:string):string =
return self.repository.exec(msg)
presentation layer
block:
let repository = newMockRepository()
let usecase = newUsecase(repository)
assert "MockRepository mock" == usecase.exec("mock")
block:
let repository = newRepository()
let usecase = newUsecase(repository)
assert "Repository exec" == usecase.exec("exec")
interfaceDef
interfaceDef macro creates method of fields of Object.
This is only available in Nim 2.0.0 and above.
import interface_implements
interfaceDef:
type IRepository* = object of RootObj
exec: proc(self:IRepository, msg:string):string
This is converted to bellow.
type IRepository* = object of RootObj
method exec*(self:IRepository, msg:string):string {.base.} = raise newException(CatchableError, "Implementation exec of IRepository is not found")
API
macro interfaceDefs*(body:untyped):untyped
Example
repository_interface.nim
interfaceDef:
type IRepository* = object of RootObj
exec*: proc(msg:string):string
mock_repository.nim
import interface_implements
type MockRepository = object of IRepository
proc newMockRepository*():MockRepository =
return MockRepository()
method exec*(self:MockRepository, msg:string):string =
return "MockRepository " & msg
repository.nim
import interface_implements
type Repository = object of IRepository
proc newRepository*():Repository =
return Repository()
method exec*(self:Repository, msg:string):string =
return "Repository " & msg
usecase.nim
import ./repository_interface
type Usecase = object
repository: IRepository
func newUsecase*(repository:IRepository):Usecase =
return Usecase(repository:repository)
proc exec*(self:Usecase, msg:string):string =
return self.repository.exec(msg)
presentation layer
block:
let repository = newMockRepository()
let usecase = newUsecase(repository)
assert "MockRepository mock" == usecase.exec("mock")
block:
let repository = newRepository()
let usecase = newUsecase(repository)
assert "Repository exec" == usecase.exec("exec")
Both pattern achieve structure as bellow.

