vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.76k stars 2.16k forks source link

toml: cannot decode tables into maps #22634

Open gechandesu opened 2 hours ago

gechandesu commented 2 hours ago

Describe the bug

The subject.

Reproduction Steps

module main

import toml

struct Item {
    name string
}

struct Doc {
    items map[string]Item
}

fn main() {
    doc := Doc{
        items: {
            'first':  Item{
                name: 'first one'
            }
            'second': Item{
                name: 'second one'
            }
        }
    }
    encoded := toml.encode[Doc](doc)
    decoded := toml.decode[Doc](encoded)!

    assert decoded == doc
}

Expected Behavior

Assertion passed.

Current Behavior

decoded.items is empty:

~ $ v run toml_issue_.v
toml_issue_.v:27: FAIL: fn main.main: assert decoded == doc
   left value: decoded = Doc{
    items: {}
}
  right value: doc = Doc{
    items: {'first': Item{
        name: 'first one'
    }, 'second': Item{
        name: 'second one'
    }}
}
V panic: Assertion failed...
v hash: 97c6cd0
/tmp/v_1000/toml_issue_.01JAX6P20BN5TX8R9NGB7F3229.tmp.c:10411: at _v_panic: Backtrace
/tmp/v_1000/toml_issue_.01JAX6P20BN5TX8R9NGB7F3229.tmp.c:30554: by main__main
/tmp/v_1000/toml_issue_.01JAX6P20BN5TX8R9NGB7F3229.tmp.c:30873: by main

Possible Solution

No response

Additional Information/Context

No response

V version

V 0.4.8 97c6cd0

Environment details (OS name and version, etc.)

V full version: V 0.4.8 5ec9bb5.97c6cd0 OS: linux, Linux version 6.6.8-arch1-1 (linux@archlinux) (gcc (GCC) 13.2.1 20230801, GNU ld (GNU Binutils) 2.41.0) #1 SMP PREEMPT_DYNAMIC Thu, 21 Dec 2023 19:01:01 +0000 Processor: 16 cpus, 64bit, little endian, 12th Gen Intel(R) Core(TM) i5-1240P

getwd: /home/ge vexe: /home/ge/.vlang/v vexe mtime: 2024-10-23 16:44:23

vroot: OK, value: /home/ge/.vlang VMODULES: OK, value: /home/ge/.vmodules VTMP: OK, value: /tmp/v_1000

Git version: git version 2.46.1 Git vroot status: weekly.2024.43-20-g97c6cd09 .git/config present: true

CC version: cc (GCC) 14.2.1 20240910 thirdparty/tcc status: thirdparty-linux-amd64 0134e9b9

[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

Huly®: V_0.6-21083

gechandesu commented 1 hour ago

The workaround is parsing by hand using from_toml() method.

Code

```v module main import maps import toml struct Item { name string } struct Doc { mut: items map[string]Item } fn (mut d Doc) from_toml(doc toml.Any) { items := doc.as_map()['items'] or { toml.Any(map[string]toml.Any{}) }.as_map() for key, val in items { item := { key: Item{ name: val.as_map()['name'] or { toml.Any{} }.string() } } maps.merge_in_place(mut d.items, item) } } fn main() { doc := Doc{ items: { 'first': Item{ name: 'first one' } 'second': Item{ name: 'second one' } } } encoded := toml.encode[Doc](doc) decoded := toml.decode[Doc](encoded)! assert decoded == doc } ```