use super::entry::{Entry, Link};
use crate::ApiError;
use serde_derive::Deserialize;
use serde_json::Value;
#[derive(Debug, Deserialize)]
pub struct Stream {
pub id: String,
#[serde(default)]
pub title: Option<String>,
#[serde(default)]
pub direction: Option<String>,
#[serde(default)]
pub updated: Option<i64>,
#[serde(default)]
pub alternate: Option<Vec<Link>>,
#[serde(default)]
pub continuation: Option<String>,
pub items: Vec<Entry>,
}
impl Stream {
#[allow(clippy::type_complexity)]
pub fn decompose(
self,
) -> (
String,
Option<String>,
Option<String>,
Option<i64>,
Option<Vec<Link>>,
Option<String>,
Vec<Entry>,
) {
(
self.id,
self.title,
self.direction,
self.updated,
self.alternate,
self.continuation,
self.items,
)
}
pub fn manual_deserialize(data: &str) -> Result<Stream, ApiError> {
let stream_value: Value = serde_json::from_str(data).map_err(|e| {
log::error!("Failed to get serde_json:Value from string: {}", e);
log::error!("data: {}", data);
ApiError::ManualJson
})?;
let id = stream_value["id"]
.as_str()
.ok_or(ApiError::ManualJson)
.map_err(|e| {
log::error!("Stream doesn't contain field ID: {:?}", stream_value);
e
})?
.into();
let title = stream_value["title"].as_str().map(|t| t.into());
let direction = stream_value["direction"].as_str().map(|t| t.into());
let updated = stream_value["updated"].as_u64().map(|u| u as i64);
let alternate = Link::manual_deserialize_vec(&stream_value["alternate"])?;
let alternate = if alternate.is_empty() {
None
} else {
Some(alternate)
};
let continuation = stream_value["continuation"].as_str().map(|t| t.into());
let items = Entry::manual_deserialize_vec(&stream_value["items"])?;
Ok(Stream {
id,
title,
direction,
updated,
alternate,
continuation,
items,
})
}
}