interface-implements
implements
macro creates toInterface
proc. It provides polymorphism.
Multiple procedures can be set in implements
block.
nimble install interface_implements
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
proc toInterface*(self:Repository):IRepository =
return (
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* = tuple
exec: proc(msg:string):string
mock_repository.nim
import repository_interface
import interface_implements
type MockRepository = ref object
proc newMockRepository*():MockRepository =
return MockRepository()
implements MockRepository, IRepository:
proc exec(self:MockRepository, msg:string):string =
return "MockRepository " & msg
repository.nim
import repository_interface
import interface_implements
type Repository = ref 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 = ref 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().toInterface()
let usecase = newUsecase(repository)
assert "MockRepository mock" == usecase.exec("mock")
block:
let repository = newRepository().toInterface()
let usecase = newUsecase(repository)
assert "Repository exec" == usecase.exec("exec")