Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

another way to create interface #6

Closed
itsumura-h opened this issue Jan 22, 2024 · 0 comments · Fixed by #7
Closed

another way to create interface #6

itsumura-h opened this issue Jan 22, 2024 · 0 comments · Fixed by #7

Comments

@itsumura-h
Copy link
Owner

itsumura-h commented Jan 22, 2024

# interfaceDef:
#   type IRepository* = object of RootObj
#     hoge: proc (self: IRepository, str:string):Future[string]
#   type IRepository2* = object of RootObj
#     hoge: proc (self: IRepository2, str:string):Future[string]

macro interfaceDef(body:untyped):untyped =
  let strBody = body.repr

  var methods:seq[string]
  for interfaceRows in body: # type IRepository* = object of RootObj | type IRepository2* = object of RootObj
    let procRows = interfaceRows[0][2][2]
    for procRow in procRows: # hoge: proc (self: IRepository, str:string):Future[string]
      let procName = procRow[0] # hoge
      let procDef = procRow[1][0] # (self: IRepository, str:string):Future[string]
      var returnType = ""
      var args:seq[string] # @["self: IRepository", "str: string"]
      var argNames:seq[string] # @["self", "str"]
      for i, argsRow in procDef:
        if i == 0:
          if argsRow.repr.len > 0: returnType = ":" & argsRow.repr # Future[string]
          continue
        let argDef = argsRow.repr # self: IRepository | str: string
        args.add(argDef)
        let argName = argsRow[0].repr # self | str
        argNames.add(argName)

      let argsInMethod = args.join(", ")
      let argNamesInMethod = argNames.join(", ")
      let methodRow = &"proc {procName}*({argsInMethod}){returnType} = self.{procName}({argNamesInMethod})"
      methods.add(methodRow)
  let res = strBody & "\n" & methods.join("\n")
  echo res
  return parseStmt(res)
interfaceDef:
  type IRepository* = object of RootObj
    hoge: proc (self: IRepository, str:string):Future[string]
    piyo: proc (self: IRepository)

generate as bellow

type IRepository* = object of RootObj
  hoge: proc (self: IRepository, str:string):Future[string]
  piyo: proc (self: IRepository)

proc hoge*(self: IRepository, str:string):Future[string] = self.hoge(self, str)
proc piyo*(self: IRepository) = self.piyo(self)

implement

type Repository* = object of IRepository

proc hogeImpl(self: IRepository, str:string):Future[string] {.async.} =
  sleepAsync(0).await
  echo "Repository hoge"
  return str

proc piyoImpl(self: IRepository) =
  echo "Repository piyo"

proc new*(_:type Repository):Repository =
  return Repository(
    hoge: hogeImpl,
    piyo: piyoImpl,
  )
type Controller* = object
  repo:IRepository

proc new*(_:type Controller, repo:IRepository):Controller =
  return Controller(
    repo:repo
  )

proc hoge*(self:Controller, str:string){.async.} =
  echo self.repo.hoge(str).await

proc piyo*(self:Controller) =
  self.repo.piyo()
proc main(){.async.} =
  let repo = Repository.new()
  let controller = Controller.new(repo)
  controller.hoge("aaa").await
  controller.piyo()

main().waitFor()
@itsumura-h itsumura-h linked a pull request Jan 24, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant