feedly_api 0.5.0

rust implementation of the feedly REST API
Documentation
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,
        })
    }
}