1
0
mirror of https://github.com/shimunn/gitredditor.git synced 2023-11-17 18:42:43 +01:00

parsing works

This commit is contained in:
shimunn 2019-05-05 19:45:23 +02:00
parent fe2db9b8dc
commit 05c88b1486
2 changed files with 122 additions and 10 deletions

66
src/main.rs Normal file
View File

@ -0,0 +1,66 @@
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
use std::error::Error;
use std::fmt;
use std::iter;
use std::iter::Chain;
use std::thread;
use std::time::Duration;
mod model;
use crate::model::*;
fn main() {
let comments = Comments::for_user("shim__");
for comment in comments {
dbg!(comment);
thread::sleep(Duration::from_millis(100));
}
println!("Hello, world!");
}
/*fn fetch_comments<'a, T: AsRef<str> + fmt::Display>(
redditor: &'a T,
from: Option<String>,
) -> std::iter::Chain<
std::result::Result<
std::vec::Vec<model::Comment>,
std::boxed::Box<(dyn std::error::Error + 'static)>,
>,
std::vec::Vec<model::Comment>,
> {
fn request_paged(url: &str) -> Result<(Vec<Comment>, Option<String>), Box<Error>> {
let comment_json = reqwest::get(url)?.text()?;
let continuation: Option<String> = unimplemented!();
let comments: Vec<Comment> = unimplemented!();
return Ok((comments, continuation));
}
let page = request_paged(&format!("https://reddit.com/user/{}.json", redditor));
let next: std::iter::Chain<
std::result::Result<
std::vec::Vec<model::Comment>,
std::boxed::Box<(dyn std::error::Error + 'static)>,
>,
std::vec::Vec<model::Comment>,
> = if let Ok((_, cont)) = page {
fetch_comments(redditor, cont)
} else {
unimplemented!() //iter::once(Vec::with_capacity(0).iter()).chain([].into_iter().map(|_| fetch_comments("never_gonna_happen", None)))
};
iter::once([()].into_iter().map(|_| page)).chain([()].into_iter().flat_map(|_| next))
}*/
fn poll(interval: Duration, count: Option<u32>) {
let mut it: u32 = 0;
loop {
thread::sleep(interval);
it += 1;
if count.map(|c| c < it).unwrap_or(false) {
break;
}
}
}

View File

@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::de;
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::error::Error; use std::error::Error;
use std::iter; use std::iter;
use std::iter::Chain; use std::iter::Chain;
@ -8,11 +9,32 @@ use std::iter::Chain;
pub struct Comment { pub struct Comment {
score: u32, score: u32,
id: String, id: String,
created: u64, created: f64,
permalink: String, permalink: String,
edited: bool, #[serde(deserialize_with = "false_or_val")]
edited: Option<u64>,
} }
fn false_or_val<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
where
D: Deserializer<'de>,
{
let val = Value::deserialize(deserializer)?;
use serde_json::Value::*;
Ok(match val {
Number(num) => num.as_u64(),
Bool(true) => Some(1),
_ => None,
})
}
/*
#[derive(Serialize, Deserialize, Debug)]
pub struct ListItem<T: for<'a> Deserialize<'a>> {
kind: String,
data: T,
}*/
pub struct Comments { pub struct Comments {
pub url: String, pub url: String,
continuation: Option<String>, continuation: Option<String>,
@ -20,7 +42,7 @@ pub struct Comments {
} }
impl Comments { impl Comments {
fn new<T: ToString>(url: T) -> Comments { pub fn new<T: ToString>(url: T) -> Comments {
let url = url.to_string(); let url = url.to_string();
Comments { Comments {
url: url, url: url,
@ -28,6 +50,13 @@ impl Comments {
buffer: None, buffer: None,
} }
} }
pub fn for_user<T: ToString>(name: T) -> Comments {
Self::new(format!(
"https://www.reddit.com/user/{}.json",
name.to_string()
))
}
} }
impl Iterator for Comments { impl Iterator for Comments {
@ -35,11 +64,28 @@ impl Iterator for Comments {
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
fn request_paged(url: &str) -> Result<(Vec<Comment>, Option<String>), Box<Error>> { fn request_paged(url: &str) -> Result<(Vec<Comment>, Option<String>), Box<Error>> {
let comment_json = reqwest::get(url)?.text()?; dbg!(("Requesting", url));
let comment_json = dbg!(reqwest::get(url)?.text()?);
let continuation: Option<String> = unimplemented!(); let comment_json: Value = serde_json::from_str(&comment_json)?;
let comments: Vec<Comment> = unimplemented!(); let data: &Value = &comment_json["data"];
return Ok((comments, continuation)); let continuation: Option<String> = match &data["after"] {
Value::String(after) => Some(after.clone()),
_ => None,
};
//Kinda ugly .clone()
//let comments: Vec<ListItem<Comment>> = serde_json::from_value(data["children"].clone())?;
if let Some(children) = data["children"].as_array() {
let comments = children
.iter()
.map(|li| serde_json::from_value::<Comment>(li["data"].clone()))
.collect::<Result<Vec<_>, _>>();
comments
.map(|comments| (comments, continuation))
.map_err(|e| e.into())
} else {
Err("Parse err".into())
}
//return Ok((comments.iter().map(|li| li.data).collect(), continuation));
} }
if let (Some(ref mut buffer), ref mut continuation, ref url) = if let (Some(ref mut buffer), ref mut continuation, ref url) =