use std::collections::VecDeque;
use std::default::Default;
use json;
use json::Value;
use data::{Comment, Thing};
use App;
use errors::ParseError;
use failure::Error;
#[derive(Debug, Clone)]
pub struct Listing<T> {
pub children: VecDeque<T>,
}
impl<T> Listing<T> {
pub fn new() -> Listing<T> {
Listing { children: VecDeque::new() }
}
}
impl<T> Default for Listing<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Iterator for Listing<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.children.pop_front()
}
}
impl Listing<Comment> {
pub fn traverse(self) -> Vec<Comment> {
let mut comments = Vec::new();
for comment in self.children {
comments.push(comment.clone());
{
comments.append(&mut comment.replies.traverse());
}
}
comments
}
fn insert_comment_recursive(&mut self, comment: &Comment) -> bool {
for c in &mut self.children {
if c.id == comment.parent_id[3..comment.parent_id.len()] {
c.replies.children.push_back(comment.clone());
return true;
} else if c.replies.insert_comment_recursive(comment) {
return true;
}
}
false
}
pub fn insert_comment(&mut self, comment: Comment) {
if !self.insert_comment_recursive(&comment) {
self.children.push_back(comment);
}
}
pub fn from_value(listing_data: &Value, post_id: &str, app: &App) -> Result<Listing<Comment>, Error> {
let mut listing: Listing<Comment> = Listing::new();
if let Some(array) = listing_data.as_array() {
for item in array {
let kind = item["kind"].as_str().unwrap();
if kind == "t1" {
listing.children.push_back(if let Ok(c) = Comment::from_value(item, app) {
c
} else {
return Err(Error::from(ParseError {
thing_type: "Listing<Comment>".to_string(),
json: json::to_string_pretty(listing_data).unwrap(),
}));
});
} else if kind == "more" {
let more = item["data"]["children"].as_array().unwrap();
let more_id = item["data"]["id"].as_str().unwrap();
if !more.is_empty() {
debug!("Need some children {}", json::to_string_pretty(more).unwrap());
let more = more.iter().map(|i| i.as_str().unwrap()).collect::<Vec<&str>>();
for child in app.more_children(post_id, more_id, &more)? {
listing.children.push_back(child);
}
trace!("Successfully got children");
}
}
}
Ok(listing)
} else {
Err(Error::from(ParseError {
thing_type: "Listing<Comment>".to_string(),
json: json::to_string_pretty(listing_data).unwrap(),
}))
}
}
}