I am trying to detect objects with a declared default so I can then detect instances where they are not the default value. The closest I got was:
import std/[options, typetraits]
type
ObjectWithDefaults* {.explain.} = concept x
var hasExplicit = false
for name, value in default(typeof(x)).fieldPairs:
when default(typeof(value)) != value:
hasExplicit = true
break
hasExplicit == true
TestObjectWithDefaults = object
name: string = "DefaultName"
count: int = 0 # ideally we'd catch this even if ints default to 0
enabled: bool = false
optionalValue: Option[int] = none(int)
echo TestObjectWithDefaults(count: 1) is ObjectWithDefaults
This returns false. Is there a better way? This works:
import std/[options, typetraits]
proc hasAnyExplicitDefault[T](t: typedesc[T]): bool =
var x = T.default
for name, value in x.fieldPairs:
if default(typeof(value)) != value:
return true
return false
type
ObjectWithDefaults* {.explain.} = concept x
hasAnyExplicitDefault(typeof(x)) == true
default(T) is independent of the type it is contained within
Playground link: https://play.nim-lang.org/#pasty=rtiVCtOr
Also, I believe {.explain.} only "explains" when overload resolution fails (see docs), i.e. if you do
proc foo[T: ObjectWithDefaults](x: T) =
echo "is ObjectWithDefaults", x
# using your failing example...
foo(TestObjectWithDefaults())
# ... or my playground failing example
foo(Foo())
If you want to mark this case as "true":
count: int = 0 # ideally we'd catch this even if ints default to 0
then I think you'll need to use a macro, as you need to check the AST for the assignment.