Skip to content

Instantly share code, notes, and snippets.

@prantlf
Last active April 21, 2024 15:27
Show Gist options
  • Save prantlf/efaf649625af24223994de180088e104 to your computer and use it in GitHub Desktop.
Save prantlf/efaf649625af24223994de180088e104 to your computer and use it in GitHub Desktop.
Crashes because of wrong recursive generics resolution of a struct reference in V
#!/usr/bin/env -S v run
// import json
// import os
import v.reflection { get_type }
// Declare structures covering a subset of a HAR file
struct HarContent {
size i64
mime_type string @[json: 'mimeType']
}
struct HarResponse {
content HarContent
}
struct HarEntry {
response HarResponse
}
pub struct HarLog {
entries []HarEntry
}
struct Har {
log HarLog
}
// Declare function printing object contents using generics
fn show[T](val T) {
$if T is string {
show_string(val)
} $else $if T is $array {
show_array(val)
} $else $if T is $struct {
show_struct(&val)
} $else {
print('primitive: ${val.str()}')
}
}
fn show_array[T](array []T) {
println('array []${T.name}')
for i, item in array {
println('item ${i}')
show(item)
println('')
}
}
fn show_struct[T](object &T) {
println('struct ${T.name}')
$for field in T.fields {
mut json_name := field.name
for attr in field.attrs {
if attr.starts_with('json: ') {
json_name = attr[6..]
}
}
print('key: ')
show_string(json_name)
println('')
println('value ${T.name}.${field.name} (json: ${json_name}) of type ${type_name(field.typ)}')
$if field.typ is string {
print('string: ')
show_string(object.$(field.name))
} $else $if field.is_array {
show_array(object.$(field.name))
} $else $if field.is_struct {
item := object.$(field.name)
show_struct(&item)
} $else {
print('primitive: ')
print(object.$(field.name).str())
}
println('')
}
}
fn show_string(s string) {
print(`"`)
print(s)
print(`"`)
}
fn type_name(idx int) string {
if typ := get_type(idx) {
return typ.name
}
panic('unknown type ${idx}')
}
// Read a HAR file and deserialise it using the built-in json support
// raw := os.read_file('har.json')!
// har := json.decode(Har, raw)!
// Simulate a HAR deserialised from a JSON file
har := Har{
log: HarLog{
entries: [
HarEntry{
response: HarResponse{
content: HarContent{
size: 48752,
mime_type: "text/html"
}
}
}
]
}
}
// Show the deserialised object - crashes in generics
show(har)
#!/usr/bin/env -S v run
// import json
// import os
import v.reflection { get_type }
// Declare structures covering a subset of a HAR file
struct HarContent {
size i64
mime_type string @[json: 'mimeType']
}
struct HarResponse {
content HarContent
}
struct HarEntry {
response HarResponse
}
pub struct HarLog {
entries []HarEntry
}
struct Har {
log HarLog
}
// Declare function printing object contents using generics
fn show[T](mut val T) {
$if T is string {
show_string(val)
} $else $if T is $array {
show_array(mut val)
} $else $if T is $struct {
show_struct(mut val)
} $else {
print('primitive: ${val.str()}')
}
}
fn show_array[T](mut array []T) {
println('array []${T.name}')
for i, mut item in array {
println('item ${i}')
show(mut item)
println('')
}
}
fn show_struct[T](mut object T) {
println('struct ${T.name}')
$for field in T.fields {
mut json_name := field.name
for attr in field.attrs {
if attr.starts_with('json: ') {
json_name = attr[6..]
}
}
print('key: ')
show_string(json_name)
println('')
println('value ${T.name}.${field.name} (json: ${json_name}) of type ${type_name(field.typ)}')
$if field.typ is string {
print('string: ')
show_string(object.$(field.name))
} $else $if field.is_array {
show_array(mut object.$(field.name))
} $else $if field.is_struct {
show_struct(mut object.$(field.name))
} $else {
print('primitive: ')
print(object.$(field.name).str())
}
println('')
}
}
fn show_string(s string) {
print(`"`)
print(s)
print(`"`)
}
fn type_name(idx int) string {
if typ := get_type(idx) {
return typ.name
}
panic('unknown type ${idx}')
}
// Read a HAR file and deserialise it using the built-in json support
// raw := os.read_file('har.json')!
// har := json.decode(Har, raw)!
// Simulate a HAR deserialised from a JSON file
mut har := Har{
log: HarLog{
entries: [
HarEntry{
response: HarResponse{
content: HarContent{
size: 48752,
mime_type: "text/html"
}
}
}
]
}
}
// Show the deserialised object
show(mut har)
{
"log": {
"entries": [
{
"response": {
"content": {
"size": 48752,
"mimeType": "text/html"
}
}
}
]
}
}
#!/usr/bin/env -S v run
// import json
// import os
import v.reflection { get_type }
// Declare structures covering a subset of a HAR file
struct HarContent {
size i64
mime_type string @[json: 'mimeType']
}
struct HarResponse {
content HarContent
}
struct HarEntry {
response HarResponse
}
pub struct HarLog {
entries []HarEntry
}
struct Har {
log HarLog
}
// Declare function printing object contents using generics
fn show[T](val T) {
$if T is string {
show_string(val)
} $else $if T is $array {
show_array(val)
} $else $if T is $struct {
show_struct(val)
} $else {
print('primitive: ${val.str()}')
}
}
fn show_array[T](array []T) {
println('array []${T.name}')
for i, item in array {
println('item ${i}')
show(item)
println('')
}
}
fn show_struct[T](object T) {
println('struct ${T.name}')
$for field in T.fields {
mut json_name := field.name
for attr in field.attrs {
if attr.starts_with('json: ') {
json_name = attr[6..]
}
}
print('key: ')
show_string(json_name)
println('')
println('value ${T.name}.${field.name} (json: ${json_name}) of type ${type_name(field.typ)}')
$if field.typ is string {
print('string: ')
show_string(object.$(field.name))
} $else $if field.is_array {
show_array(object.$(field.name))
} $else $if field.is_struct {
show_struct(object.$(field.name))
} $else {
print('primitive: ')
print(object.$(field.name).str())
}
println('')
}
}
fn show_string(s string) {
print(`"`)
print(s)
print(`"`)
}
fn type_name(idx int) string {
if typ := get_type(idx) {
return typ.name
}
panic('unknown type ${idx}')
}
// Read a HAR file and deserialise it using the built-in json support
// raw := os.read_file('har.json')!
// har := json.decode(Har, raw)!
// Simulate a HAR deserialised from a JSON file
har := Har{
log: HarLog{
entries: [
HarEntry{
response: HarResponse{
content: HarContent{
size: 48752,
mime_type: "text/html"
}
}
}
]
}
}
// Show the deserialised object
show(har)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment