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.5k stars 2.15k forks source link

x.json2 fails to decode a map with number keys #21683

Closed spytheman closed 1 week ago

spytheman commented 2 weeks ago

V doctor:

V full version: V 0.4.6 c689f80.3ad77b2
OS: linux, Ubuntu 20.04.6 LTS
Processor: 4 cpus, 64bit, little endian, Intel(R) Core(TM) i3-3225 CPU @ 3.30GHz

getwd: /space/v/oo
vexe: /space/v/oo/v
vexe mtime: 2024-06-15 17:29:20

vroot: OK, value: /space/v/oo
VMODULES: OK, value: /home/delian/.vmodules
VTMP: OK, value: /tmp/v_1000

Git version: git version 2.43.2
Git vroot status: weekly.2024.24-11-g3ad77b25
.git/config present: true

CC version: cc (Ubuntu 10.5.0-1ubuntu1~20.04) 10.5.0
thirdparty/tcc status: thirdparty-linux-amd64 40e5cbb5

What did you do? v -g -o vdbg cmd/v && vdbg j4.v

module main

import x.json2

const data = '
{
  "comments": {
    "26788945": {
      "id": "26788945",
      "message": "some comment 1"
    },
    "26788946": {
      "id": "26788946",
      "message": "some comment 2"
    },
    "26788947": {
      "id": "26788947",
      "message": "some comment 3"
    }
  }
}
'

struct Comment {
    id      string
    message string
}

struct Comments {
mut:
    comments map[string]Comment
}

fn main() {
    mut root := json2.decode[Comments](data)!
    println(root)
}

What did you expect to see?

A non empty structure

What did you see instead?

Comments{
    comments: {}
}

[!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.

spytheman commented 2 weeks ago

Note that a more manual version of the program works:

module main

import x.json2

const data = '
{
  "comments": {
    "26788945": {
      "id": "26788945",
      "message": "some comment 1"
    },
    "26788946": {
      "id": "26788946",
      "message": "some comment 2"
    },
    "26788947": {
      "id": "26788947",
      "message": "some comment 3"
    }
  }
}
'

struct Comment {
    id      string
    message string
}

struct Comments {
mut:
    comments map[string]Comment
}

fn main() {
    mut root := Comments{}
    for k, v in json2.raw_decode(data)!.as_map()['comments']!.as_map() {
        comment := json2.decode[Comment](v.str())!
        root.comments[k] = comment
    }
    println(root)
}

producing:

Comments{
    comments: {'26788945': Comment{
        id: '26788945'
        message: 'some comment 1'
    }, '26788946': Comment{
        id: '26788946'
        message: 'some comment 2'
    }, '26788947': Comment{
        id: '26788947'
        message: 'some comment 3'
    }}
}

I expected that root := json2.decode[Comments](data)! would produce the same.

spytheman commented 2 weeks ago

Using json also works:

module main

import json

const data = '
{
  "comments": {
    "26788945": {
      "id": "26788945",
      "message": "some comment 1"
    },
    "26788946": {
      "id": "26788946",
      "message": "some comment 2"
    },
    "26788947": {
      "id": "26788947",
      "message": "some comment 3"
    }
  }
}
'

struct Comment {
    id      string
    message string
}

struct Comments {
mut:
    comments map[string]Comment
}

fn main() {
    root := json.decode(Comments, data)!
    println(root)
}