Does any one know if it's possible to define a custom pragma that you can attach to object definition to create custom getters and setters? Here I create an object with a dirty flag, and when any field is set its marked as dirty. I want to make it a simpler macro.
This works but I want it to be part of the object definition:
import macros
macro genDirtyGettersAndSetters(v: typed) =
## Adds getters and setters that mark the .dirty fields when set.
let typeDesc = getTypeInst(v)
let sym = typeDesc[^1]
let symImpl = sym.getTypeImpl
result = newStmtList()
for field in symImpl[2]:
let
nameIdent = newIdentNode($field[0])
typeIdent = newIdentNode($field[1])
let nameEq = nnkAccQuoted.newTree(
nameIdent,
newIdentNode("=")
)
result.add quote do:
proc `nameEq`*(x: var Foo, v: `typeIdent`) =
x.dirty = true
x.`nameIdent` = v
proc `nameIdent`*(x: Foo): `typeIdent` =
x.`nameIdent`
type
Foo* = object # {.genDirtyGettersAndSetters.} <-- I want it here
dirty: bool
name: string
a: int
genDirtyGettersAndSetters(Foo) # <-- but here works
As a block pragma?:
{. genDirtyGettersAndSetters .}:
type Foo = object
I face the same limitation and just implemented a typeDef macro in my constructor package to get around it, resuling in a DSL that looks like.
import ../src/constructor
typeDef(Test, true):
a b = int
d = seq[int]:
get(true):
test.dBacker
set(true): #In setters value is the input value
if value.len >= 1:
test.dBacker = value[0..2]
var a = Test()
a.d = @[100, 200, 300, 400]
assert a.d == @[100 ,200, 300] #Means the Setter did the job