use crate::{
auth::Auth,
client::{route::Route, Client},
error::Error,
model::{link::Link, listing::Listing, misc::Fullname, misc::Params, thing::Thing, user::User},
};
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Comment {
pub author: String,
pub link_id: Fullname,
pub subreddit_id: Fullname,
pub parent_id: Fullname,
pub name: Fullname,
pub body: String,
pub body_html: String,
#[doc(hidden)]
pub replies: Option<Box<Thing>>,
}
impl Comment {
pub async fn author<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<User, Error> {
client.user(&self.author).await
}
pub async fn replies<T: Auth + Send + Sync>(
&self,
client: &Client<T>,
) -> Result<Vec<Comment>, Error> {
if let Some(r) = self.replies.clone() {
let listing: Listing = Thing::try_into(*r)?;
let replies: Vec<Comment> = Listing::try_into(listing)?;
return Ok(replies);
}
client.replies(self.link_id.name(), self.name.name()).await
}
pub async fn parent<T: Auth + Send + Sync>(
&self,
client: &Client<T>,
) -> Result<Option<Comment>, Error> {
if self.parent_id == self.subreddit_id {
return Ok(None);
}
let parent_comment = client.comment(&self.parent_id.name()).await?;
Ok(Some(parent_comment))
}
pub async fn link<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<Link, Error> {
client.link(self.link_id.as_ref()).await
}
pub async fn reply<T: Auth + Send + Sync>(
&self,
client: &Client<T>,
body: &str,
) -> Result<(), Error> {
client.submit_comment(self.name.as_ref(), body).await
}
pub async fn lock<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
client
.post(Route::Lock, &Params::new().add("id", self.name.as_ref()))
.await
.and(Ok(()))
}
pub async fn unlock<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
client
.post(Route::Unlock, &Params::new().add("id", self.name.as_ref()))
.await
.and(Ok(()))
}
}