2016-01-24 2 views
4

Я пытаюсь десериализовать метаданные Spotify JSON из веб-API (specifications). Я использую hyper для извлечения JSON с сервера и serde, чтобы превратить JSON в то, что я действительно могу использовать в Rust. JSON извлекается с сервера просто отлично, но когда я пытаюсь включить JSON в объект, который может быть использован Руст panicks и выдает ошибку:Serde возвращает ожидаемое значение SyntaxError при десериализации вложенных структур JSON

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

Это не полезно в наименьшему пути, потому что он не указывает, где все идет не так. При поиске в Интернете я наткнулся на a serde issue, что заставляет меня думать, что проблема связана с вложенной структурой JSON.

Может ли кто-нибудь увидеть, где все пошло не так? Исправление ошибки было бы лучшим решением для меня, но если другой ящик окажется лучшим решением, я бы тоже хотел это услышать. Я уже пробовал rustc-serialize, но этот ящик не может обрабатывать переменные типа в json.

код я использую:

#![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" 
} 

ответ

6

Вы попытались разобрать некоторые JSON и не удалось. Когда вы назвали unwrap на Result, программа охватила паника из-за этой неудачи:

SyntaxError("expected value", 11, 21) 

The documentation for SyntaxError говорит, что числа являются строка и столбец ошибки. Строка 11, столбец 21:

 "height" : 640, 
        ^

Глядя на вашу структуру, вы заявили высоту быть u8, 8-разрядное целое число без знака. Это допустимые значения 0-255. 640 не вписывается в это. Увеличение значения до u32 позволяет анализировать JSON.


Кроме того, Rust стиль использовать CamelCase идентификаторы без последовательных прописных букв для структур. External_URLs ->ExternalUrls. Компилятор действительно предупредит вас об этом.