Json2: How to "dereference" T after $if T is $pointer ?
#25375
-
|
Trying to make json2 encode (and later decode) struct references to produce texts like import x.json2
struct Struct{
a int
}
fn main() {
data := [
Struct{ a:1 }
Struct{ a:2 }
Struct{ a:3 }
]
refs := [
&Struct{ a:1 }
unsafe{nil}
&Struct{ a:3 }
]
println('not_refs_ok: ${json2.encode(data)}')
println('refs_fails: ${json2.encode(refs)}')
println('refs_almost: ${my_encode(refs)}')
}
fn my_encode[T](t T) string {
$if T is $array {
mut a := []string{}
for e in t {
a << my_encode_value(e)
}
return '[${a.join(',')}]'
}
return '' // TODO
}
fn my_encode_value[T](t T) string {
$if T is $pointer { // isreftype(t) {
if voidptr(t) == unsafe{nil} {
return 'null'
}
return json2.encode[Struct](T(t)) // refs
}
return json2.encode[T](t) // not refs
}Results: My idea is to add in $if T is $pointer { // isreftype(t) {
if voidptr(t) == unsafe{nil} {
return 'null'
}
return json2.encode[Struct](T(t)) // refs
}Above code works produces the correct elements of array Is there a way in this line of code "dereference" T which is |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
|
In theory one could use * to dereference a pointer. But that is not possible here since the type T has to be dereferenced. |
Beta Was this translation helpful? Give feedback.
-
|
This should be a feature suggestion. |
Beta Was this translation helpful? Give feedback.
-
|
Commit V 0.4.12 7801f5b solves this question for an encoder. For a decoder is a little bit different. struct Foo {
a int // single field on purpose
}
fn encode[T](t T) string {
$if T is $pointer{
if voidptr(t) == unsafe{nil} {
return 'null'
} else {
$for field in T.fields {
val := t.$(field.name)
return '&struct ${field.name}=${val}'
}
}
} $else $if T is $struct {
$for field in T.fields {
val := t.$(field.name)
return 'struct ${field.name}=${val}'
}
}
return '?'
}
fn main() {
assert encode(&Foo(unsafe{nil})) == 'null'
obj := Foo{ a:1 }
assert encode(obj) == 'struct a=1'
assert encode(&obj) == '&struct a=1'
ref := &Foo{ a:2 }
assert encode(*ref) == 'struct a=2'
assert encode(ref) == '&struct a=2'
}
|
Beta Was this translation helpful? Give feedback.
Commit V 0.4.12 7801f5b solves this question for an encoder. For a decoder is a little bit different.
https://play.vlang.io/p/926e017e92