![](/img/trans.png)
[英]“invalid type: map, expected a sequence” when deserializing a nested JSON structure with Serde
[英]Serde returns a SyntaxError “expected value” when deserializing nested JSON structs
我正在嘗試從Web API( 規范 )反序列化Spotify元數據JSON。 我正在使用hyper來從服務器和serde中檢索JSON,以將JSON轉換為我可以在Rust中實際使用的東西。 從服務器檢索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
這在最小的方面沒有幫助,因為它根本不表示出錯的地方。 在搜索網絡時,我偶然發現了一個serde問題 ,這讓我認為問題與JSON的嵌套結構有關。
任何人都可以看到出錯的地方? 修復錯誤對我來說是最好的解決方案,但如果另一個箱子是一個更好的解決方案,我也想聽到。 我已經嘗試過rustc-serialize,但是crate無法處理json中的'type'變量。
我使用的代碼是:
#![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:
{
"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
時,由於此失敗,程序會驚慌失措:
SyntaxError("expected value", 11, 21)
SyntaxError
的文檔說數字是錯誤的行和列。 第21行第21行是:
"height" : 640,
^
查看您的結構,您已將高度聲明為u8
,即8位無符號數。 其允許值為0-255。 640不適合。 將值增加到u32
允許解析JSON。
另外,Rust樣式是使用CamelCase
標識符而不使用連續的大寫字母來表示結構。 External_URLs
- > ExternalUrls
。 編譯器實際上會警告你這件事。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.