简体   繁体   English

在反序列化嵌套的JSON结构时,Serde返回SyntaxError“期望值”

[英]Serde returns a SyntaxError “expected value” when deserializing nested JSON structs

I'm trying to deserialize a Spotify metadata JSON from the web API ( specifications ). 我正在尝试从Web API( 规范 )反序列化Spotify元数据JSON。 I'm using hyper to retrieve the JSON from the server and serde to turn the JSON into something I can actually use within Rust. 我正在使用hyper来从服务器和serde中检索JSON,以将JSON转换为我可以在Rust中实际使用的东西。 The JSON is retrieved from the server just fine, but when I try to turn the JSON into an object that can be used Rust panicks and throws an error: 从服务器检索JSON很好,但是当我尝试将JSON转换为可以使用的对象时,可以使用Rust panicks并抛出错误:

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

This is not helpful in the least way, because it doesn't indicate where things go wrong at all. 这在最小的方面没有帮助,因为它根本不表示出错的地方。 When searching the web I stumbled upon a serde issue , which leads me to think that the problem is related to the nested structure of the JSON. 在搜索网络时,我偶然发现了一个serde问题 ,这让我认为问题与JSON的嵌套结构有关。

Can anyone see where things go wrong? 任何人都可以看到出错的地方? Fixing the error would be the best solution for me, but if another crate turns out to be a better solution I'd like to hear that too. 修复错误对我来说是最好的解决方案,但如果另一个箱子是一个更好的解决方案,我也想听到。 I've already tried rustc-serialize, but that crate can't handle the 'type' variables within the json. 我已经尝试过rustc-serialize,但是crate无法处理json中的'type'变量。

The code I use is: 我使用的代码是:

#![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();
}

The JSON: JSON:

{
  "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"
}

You've attempted to parse some JSON and it failed. 您试图解析一些JSON,但失败了。 When you called unwrap on the Result , the program panicked because of this failure: 当您在Result上调用unwrap时,由于此失败,程序会惊慌失措:

SyntaxError("expected value", 11, 21)

The documentation for SyntaxError says the numbers are the line and column of the error. SyntaxError的文档说数字是错误的行和列。 Line 11, column 21 is: 第21行第21行是:

      "height" : 640,
                     ^

Looking at your structure, you have declared the height to be a u8 , an 8-bit unsigned number. 查看您的结构,您已将高度声明为u8 ,即8位无符号数。 This has the allowed values of 0-255. 其允许值为0-255。 640 does not fit into that. 640不适合。 Increasing the value to a u32 allows the JSON to be parsed. 将值增加到u32允许解析JSON。


Additionally, Rust style is to use CamelCase identifiers without consecutive capital letters for structs. 另外,Rust样式是使用CamelCase标识符而不使用连续的大写字母来表示结构。 External_URLs -> ExternalUrls . External_URLs - > ExternalUrls The compiler will actually warn you about this. 编译器实际上会警告你这件事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM