关于 rust:Serde 在反序列化嵌套的 JSON 结构时返回 SyntaxError “expected value”

Serde returns a SyntaxError "expected value" when deserializing nested JSON structs

我正在尝试从 Web API(规范)反序列化 Spotify 元数据 JSON。我正在使用 hyper 从服务器中检索 JSON,并使用 serde 将 JSON 转换为我可以在 Rust 中实际使用的东西。从服务器检索 JSON 就好了,但是当我尝试将 JSON 转换为可以使用的对象时,Rust panic并抛出错误:

1
thread '<main>' panicked at 'called 'Result::unwrap()' on an 'Err' value: SyntaxError("expected value", 11, 21)', ../src/libcore/result.rs:746

这一点也没有帮助,因为它根本无法指出哪里出了问题。在搜索网络时,我偶然发现了一个 serde 问题,这让我认为该问题与 JSON 的嵌套结构有关。

谁能看出哪里出了问题?修复错误对我来说是最好的解决方案,但如果另一个板条箱是一个更好的解决方案,我也想听听。我已经尝试过 rustc-serialize,但是那个 crate 无法处理 json 中的"类型"变量。

我使用的代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
#![feature(custom_attribute)]

extern crate hyper;
extern crate serde;
extern crate serde_json;

use std::io::Read;
use hyper::Client;
use hyper::header::Connection;

#[derive(Serialize, Deserialize)]
struct Track_Full {
    album: Album_Simp,
    artists: Vec<Artist_Simp>,
    available_markets: Vec<String>,
    disc_number: u8,
    duration_ms: u32,
    explicit: bool,
    external_ids: External_IDs,
    external_urls: External_URLs,
    href: String,
    id: String,
    name: String,
    popularity: u8,
    preview_url: String,
    track_number: u8,
    #[serde(rename="type")]
    _type: String,
    uri: String
}

#[derive(Serialize, Deserialize)]
struct Album_Simp {
    album_type: String,
    available_markets: Vec<String>,
    external_urls: External_URLs,
    href: String,
    id: String,
    images: Vec<Image>,
    name: String,
    #[serde(rename="type")]
    _type: String,
    uri: String
}

#[derive(Serialize, Deserialize)]
struct Artist_Simp {
    external_urls: External_URLs,
    href: String,
    id: String,
    name: String,
    #[serde(rename="type")]
    _type: String,
    uri: String
}

#[derive(Serialize, Deserialize)]
struct External_IDs {
    isrc: String
}

#[derive(Serialize, Deserialize)]
struct External_URLs {
    spotify: String
}

#[derive(Serialize, Deserialize)]
struct Image {
    height: u8,
    url: String,
    width: u8
}

fn main() {
    // Create a client.
    let mut client = Client::new();

    // Creating an outgoing request.
    let mut res = client.get("https://api.spotify.com/v1/tracks/0eGsygTp906u18L0Oimnem")
        // set a header
        .header(Connection::close())
        // let 'er go!
        .send().unwrap();

    // Read the Response.
    let mut body = String::new();
    res.read_to_string(&mut body).unwrap();

    println!("{}", body);

    let deserialized: Track_Full = serde_json::from_str(&body).unwrap();
}

JSON:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
 "album" : {
   "album_type" :"album",
   "available_markets" : ["AD","AR","AT","AU","BE","BG","BO","BR","CH","CL","CO","CR","CY","CZ","DE","DK","DO","EC","EE","ES","FI","FR","GR","GT","HK","HN","HU","IE","IS","IT","LI","LT","LU","LV","MC","MT","MY","NI","NL","NO","NZ","PA","PE","PH","PL","PT","PY","RO","SE","SG","SI","SK","SV","TR","TW","UY" ],
   "external_urls" : {
     "spotify" :"https://open.spotify.com/album/6TJmQnO44YE5BtTxH8pop1"
    },
   "href" :"https://api.spotify.com/v1/albums/6TJmQnO44YE5BtTxH8pop1",
   "id" :"6TJmQnO44YE5BtTxH8pop1",
   "images" : [ {
     "height" : 640,
     "url" :"https://i.scdn.co/image/8e13218039f81b000553e25522a7f0d7a0600f2e",
     "width" : 629
    }, {
     "height" : 300,
     "url" :"https://i.scdn.co/image/8c1e066b5d1045038437d92815d49987f519e44f",
     "width" : 295
    }, {
     "height" : 64,
     "url" :"https://i.scdn.co/image/d49268a8fc0768084f4750cf1647709e89a27172",
     "width" : 63
    } ],
   "name" :"Hot Fuss",
   "type" :"album",
   "uri" :"spotify:album:6TJmQnO44YE5BtTxH8pop1"
  },
 "artists" : [ {
   "external_urls" : {
     "spotify" :"https://open.spotify.com/artist/0C0XlULifJtAgn6ZNCW2eu"
    },
   "href" :"https://api.spotify.com/v1/artists/0C0XlULifJtAgn6ZNCW2eu",
   "id" :"0C0XlULifJtAgn6ZNCW2eu",
   "name" :"The Killers",
   "type" :"artist",
   "uri" :"spotify:artist:0C0XlULifJtAgn6ZNCW2eu"
  } ],
 "available_markets" : ["AD","AR","AT","AU","BE","BG","BO","BR","CH","CL","CO","CR","CY","CZ","DE","DK","DO","EC","EE","ES","FI","FR","GR","GT","HK","HN","HU","IE","IS","IT","LI","LT","LU","LV","MC","MT","MY","NI","NL","NO","NZ","PA","PE","PH","PL","PT","PY","RO","SE","SG","SI","SK","SV","TR","TW","UY" ],
 "disc_number" : 1,
 "duration_ms" : 222075,
 "explicit" : false,
 "external_ids" : {
   "isrc" :"USIR20400274"
  },
 "external_urls" : {
   "spotify" :"https://open.spotify.com/track/0eGsygTp906u18L0Oimnem"
  },
 "href" :"https://api.spotify.com/v1/tracks/0eGsygTp906u18L0Oimnem",
 "id" :"0eGsygTp906u18L0Oimnem",
 "name" :"Mr. Brightside",
 "popularity" : 74,
 "preview_url" :"https://p.scdn.co/mp3-preview/934da7155ec15deb326635d69d050543ecbee2b4",
 "track_number" : 2,
 "type" :"track",
 "uri" :"spotify:track:0eGsygTp906u18L0Oimnem"
}

您尝试解析一些 JSON,但它失败了。当您在 Result 上调用 unwrap 时,程序会因为这个失败而panic:

1
SyntaxError("expected value", 11, 21)

SyntaxError 的文档说数字是错误的行和列。第 11 行第 21 列是:

1
2
     "height" : 640,
                     ^

查看您的结构,您已将高度声明为 u8,一个 8 位无符号数。这具有 0-255 的允许值。 640不适合这个。将值增加到 u32 允许解析 JSON。

此外,Rust 风格是使用 CamelCase 标识符而不是连续大写字母的结构。 External_URLs -> ExternalUrls。编译器实际上会就此发出警告。