我正在尝试使用Serde编写API包装器。尝试运行程序时出现此错误:
Err(Error { kind: Json(Error("invalid type: map, expected a sequence", line: 1, column: 2)), url: None })
听起来好像Serde遇到{
,根据我当前模型的设置方式,它期望[
,但也许我对这种理论不太了解。
直接从端点返回的JSON是:
[
{
"title": "Pad Abort Test",
"event_date_utc": "2015-05-06T13:00:00Z",
"event_date_unix": 1430917200,
"flight_number": null,
"details": "Crew Dragon tests launch abort system, which can provide astronauts with escape capability all the way to orbit.",
"links": {
"reddit": "https:\/\/www.reddit.com\/r\/spacex\/comments\/3527zv\/official_video_pad_abort_test_2015\/",
"article": "https:\/\/spaceflightnow.com\/2015\/04\/21\/dragon-pad-abort-test-set-for-early-may\/",
"wikipedia": "https:\/\/en.wikipedia.org\/wiki\/Pad_abort_test"
}
},
{
"title": "SpaceX Awarded Commercial Crew Contract",
"event_date_utc": "2014-09-16T01:00:00Z",
"event_date_unix": 1410829200,
"flight_number": null,
"details": "NASA awards $2.6 billion SpaceX contract to fly American astronauts.",
"links": {
"reddit": null,
"article": "https:\/\/www.washingtonpost.com\/news\/the-switch\/wp\/2014\/09\/16\/nasa-awards-space-contract-to-boeing-and-spacex\/?utm_term=.d6388390d071",
"wikipedia": null
}
}
]
我知道我的代码是错误的-我只是不知道如何解决它。在这里:
models.rs
#[derive(Debug, Deserialize)]
pub struct HistoricalEvents {
items: Vec<HistoricalEvent>,
}
#[derive(Debug, Deserialize)]
pub struct HistoricalEvent {
title: String,
event_date_utc: String,
event_date_unix: u64,
flight_number: Option<u32>,
details: Option<String>,
links: Links,
}
#[derive(Debug, Deserialize)]
struct Links {
reddit: Option<String>,
article: Option<String>,
wikipedia: Option<String>,
}
lib.rs
的一部分pub fn history(
start_date: Option<String>,
end_date: Option<String>,
flight_number: Option<u32>,
sort_dir: Option<SortDir>,
) -> Result<HistoricalEvents, failure::Error> {
let mut params = HashMap::new();
start_date.and_then(|string| params.insert("start", string));
end_date.and_then(|string| params.insert("end", string));
flight_number.and_then(|num| params.insert("flight_number", num.to_string()));
sort_dir.and_then(|dir| params.insert("order", dir.to_string()));
return send_request("info/history", Some(params));
}
fn send_request<T>(
endpoint: &str,
params: Option<HashMap<&str, String>>,
) -> Result<T, failure::Error>
where
T: DeserializeOwned,
{
let base = &("https://api.spacexdata.com/v2/".to_owned() + endpoint);
let url = match params {
Some(map) => Url::parse_with_params(base, map),
None => Url::parse(base),
};
let client = Client::new();
let mut request = client.get(url.unwrap().as_str());
let mut response = request.send()?;
Ok(response.json()?)
}