353 lines
9.8 KiB
Rust
353 lines
9.8 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SubredditPosts {
|
|
pub date_first: i64,
|
|
pub date_last: i64,
|
|
pub links: Vec<SubredditPost>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq)]
|
|
pub struct SubredditPost {
|
|
pub datakey: String,
|
|
pub domain: String,
|
|
pub flair: Option<String>,
|
|
pub link: String,
|
|
pub nsfw: bool,
|
|
pub sharer: String,
|
|
pub timestamp: i64,
|
|
pub title: String,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Derivative, Serialize, Deserialize, Debug, Clone)]
|
|
#[derivative(Hash)]
|
|
pub struct SubredditInfoFromGateway {
|
|
pub token: Option<String>,
|
|
pub dist: i64,
|
|
listingSort: String,
|
|
pub postIds: Option<Vec<String>>,
|
|
#[derivative(Hash = "ignore")]
|
|
pub posts: HashMap<String, SubredditPostFromGateway>,
|
|
#[derivative(Hash = "ignore")]
|
|
pub subreddits: HashMap<String, SubredditSubredditsFromGateway>,
|
|
#[derivative(Hash = "ignore")]
|
|
pub subredditAboutInfo: HashMap<String, SubredditAboutInfoFromGateway>,
|
|
#[derivative(Hash = "ignore")]
|
|
pub postFlair: HashMap<String, SubredditPostFlairFromGateway>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditThumbFromGateway {
|
|
pub url: String,
|
|
pub width: Option<i64>,
|
|
pub height: Option<i64>,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditMediaFromGateway {
|
|
pub obfuscated: Option<String>,
|
|
pub content: Option<String>,
|
|
pub r#type: Option<String>,
|
|
pub width: Option<i64>,
|
|
pub height: Option<i64>,
|
|
pub resolutions: Option<Vec<SubredditThumbFromGateway>>,
|
|
pub markdownContent: Option<String>,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Derivative, Serialize, Deserialize, Debug, Clone)]
|
|
#[derivative(Hash)]
|
|
pub struct SubredditPostFromGateway {
|
|
pub id: String,
|
|
pub numComments: i64,
|
|
#[derivative(Hash = "ignore")]
|
|
pub created: f64,
|
|
pub score: i64,
|
|
pub distinguishType: Option<String>,
|
|
pub isLocked: bool,
|
|
pub isStickied: bool,
|
|
pub thumbnail: Option<SubredditThumbFromGateway>,
|
|
pub title: String,
|
|
pub author: String,
|
|
pub authorId: Option<String>,
|
|
pub domain: Option<String>,
|
|
pub postId: String,
|
|
#[derivative(Hash = "ignore")]
|
|
pub upvoteRatio: f64,
|
|
pub numDuplicates: Option<i64>,
|
|
pub discussionType: Option<String>,
|
|
pub viewCount: i64,
|
|
pub goldCount: i64,
|
|
pub isArchived: bool,
|
|
pub contestMode: bool,
|
|
#[derivative(Hash = "ignore")]
|
|
pub gildings: Option<HashMap<String, i64>>,
|
|
pub postCategories: Option<String>,
|
|
pub suggestedSort: Option<String>,
|
|
pub belongsTo: Option<SubredditBelongsFromGateway>,
|
|
pub flair: Vec<SubredditFlairFromGateway>,
|
|
pub hidden: bool,
|
|
pub saved: bool,
|
|
pub isGildable: bool,
|
|
pub isMediaOnly: bool,
|
|
pub isSponsored: bool,
|
|
pub isNSFW: bool,
|
|
pub isMeta: bool,
|
|
pub isSpoiler: bool,
|
|
pub isBlank: bool,
|
|
pub sendReplies: bool,
|
|
pub voteState: i64,
|
|
pub permalink: Option<String>,
|
|
pub domainOverride: Option<String>,
|
|
pub media: Option<SubredditMediaFromGateway>,
|
|
pub preview: Option<SubredditThumbFromGateway>,
|
|
pub crosspostRootId: Option<String>,
|
|
pub crosspostParentId: Option<String>,
|
|
pub numCrossposts: i64,
|
|
pub isCrosspostable: bool,
|
|
pub liveCommentsWebsocket: Option<String>,
|
|
pub source: Option<SubredditSourceFromGateway>,
|
|
pub isOriginalContent: bool,
|
|
pub contentCategories: Option<Vec<String>>,
|
|
pub isScoreHidden: bool,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditBelongsFromGateway {
|
|
pub id: String,
|
|
pub r#type: String,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditFlairFromGateway {
|
|
pub text: Option<String>,
|
|
pub r#type: String,
|
|
pub textColor: Option<String>,
|
|
pub backgroundColor: Option<String>,
|
|
pub templateId: Option<String>,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditSourceFromGateway {
|
|
pub displayText: String,
|
|
pub url: String,
|
|
pub outboundUrl: Option<String>,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditSubredditsFromGateway {
|
|
pub allowChatPostCreation: bool,
|
|
pub isChatPostFeatureEnabled: bool,
|
|
pub displayText: String,
|
|
pub r#type: String,
|
|
pub id: String,
|
|
pub isQuarantined: bool,
|
|
pub isNSFW: bool,
|
|
pub name: String,
|
|
pub url: String,
|
|
pub title: String,
|
|
pub icon: Option<SubredditThumbFromGateway>,
|
|
pub whitelistStatus: Option<String>,
|
|
pub wls: Option<i64>,
|
|
pub communityIcon: Option<String>,
|
|
pub primaryColor: String,
|
|
pub subscribers: i64,
|
|
pub freeFormReports: Option<bool>,
|
|
pub isEnrolledInNewModmail: Option<bool>,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Derivative, Serialize, Deserialize, Debug, Clone)]
|
|
#[derivative(Hash)]
|
|
pub struct SubredditAboutInfoFromGateway {
|
|
pub accountsActive: i64,
|
|
pub advertiserCategory: String,
|
|
pub publicDescription: String,
|
|
pub showMedia: bool,
|
|
pub subscribers: i64,
|
|
pub restrictPosting: bool,
|
|
pub restrictCommenting: bool,
|
|
pub disableContributorRequests: bool,
|
|
#[derivative(Hash = "ignore")]
|
|
pub created: f64,
|
|
pub userIsBanned: bool,
|
|
pub emojisEnabled: bool,
|
|
pub allOriginalContent: bool,
|
|
pub originalContentTagEnabled: bool,
|
|
pub isCrosspostableSubreddit: bool,
|
|
pub allowedPostTypes: SubredditAllowedPostTypesFromGateway,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditAllowedPostTypesFromGateway {
|
|
pub links: bool,
|
|
pub images: bool,
|
|
pub videos: bool,
|
|
pub text: bool,
|
|
pub spoilers: bool,
|
|
pub polls: bool,
|
|
pub galleries: bool,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditPostFlairFromGateway {
|
|
pub displaySettings: SubredditDisplaySettingsFromGateway,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditDisplaySettingsFromGateway {
|
|
pub isEnabled: Option<bool>,
|
|
pub position: Option<String>,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditInfoStored {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub definition: SubredditSubredditsFromGateway,
|
|
pub about: SubredditAboutInfoFromGateway,
|
|
pub flair: SubredditPostFlairFromGateway,
|
|
}
|
|
|
|
impl SubredditInfoStored {
|
|
pub fn new(
|
|
id: String,
|
|
name: String,
|
|
definition: SubredditSubredditsFromGateway,
|
|
about: SubredditAboutInfoFromGateway,
|
|
flair: SubredditPostFlairFromGateway,
|
|
) -> Self {
|
|
Self {
|
|
id,
|
|
name,
|
|
definition,
|
|
about,
|
|
flair,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubredditInfoFromGateway {
|
|
pub fn to_stored(&self, id: String, name: String) -> SubredditInfoStored {
|
|
let definition: SubredditSubredditsFromGateway = self.subreddits[&id].clone();
|
|
let about: SubredditAboutInfoFromGateway = self.subredditAboutInfo[&id].clone();
|
|
let flair: SubredditPostFlairFromGateway = self.postFlair[&id].clone();
|
|
SubredditInfoStored::new(id, name, definition, about, flair)
|
|
}
|
|
}
|
|
|
|
// for JavaScript interoperability
|
|
static KNOWN_MAX_INT: i64 = 1 << 52;
|
|
static KNOWN_MIN_INT: i64 = 1 - KNOWN_MAX_INT;
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
|
|
pub struct SubredditPostsStore {
|
|
pub date_first: i64,
|
|
pub date_last: i64,
|
|
pub links: Vec<SubredditPostStore>,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SubredditPostStore {
|
|
pub datakey: String,
|
|
pub domain: String,
|
|
pub flair: Option<String>,
|
|
pub link: String,
|
|
pub nsfw: bool,
|
|
pub sharer: String,
|
|
pub timestamp: i64,
|
|
pub title: String,
|
|
}
|
|
|
|
impl std::hash::Hash for SubredditPostStore {
|
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
self.datakey.hash(state);
|
|
self.timestamp.hash(state);
|
|
}
|
|
}
|
|
impl PartialEq for SubredditPostStore {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.datakey == other.datakey && self.timestamp == other.timestamp
|
|
}
|
|
}
|
|
|
|
impl SubredditPostsStore {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
date_first: KNOWN_MIN_INT,
|
|
date_last: KNOWN_MAX_INT,
|
|
links: vec![],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubredditPostStore {
|
|
#[allow(clippy::too_many_arguments)]
|
|
pub fn new(
|
|
datakey: String,
|
|
domain: String,
|
|
flair: Option<String>,
|
|
link: String,
|
|
nsfw: bool,
|
|
sharer: String,
|
|
timestamp: i64,
|
|
title: String,
|
|
) -> Self {
|
|
Self {
|
|
datakey,
|
|
domain,
|
|
flair,
|
|
link,
|
|
nsfw,
|
|
sharer,
|
|
timestamp,
|
|
title,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubredditPostFromGateway {
|
|
pub fn storable(&self) -> SubredditPostStore {
|
|
SubredditPostStore::new(
|
|
self.id.clone(),
|
|
self.domain.clone().unwrap_or_else(|| String::from("")),
|
|
self.flair
|
|
.iter()
|
|
.filter(|x| x.r#type == "text")
|
|
.map(|x| x.text.clone())
|
|
.collect::<Vec<Option<String>>>()
|
|
.first()
|
|
.and_then(|x| x.clone()),
|
|
if let Some(src) = self.source.clone() {
|
|
src.url
|
|
} else if let Some(mda) = self.media.clone() {
|
|
mda.content.unwrap_or_else(|| String::from(""))
|
|
} else {
|
|
String::from("")
|
|
},
|
|
self.isNSFW,
|
|
self.author.clone(),
|
|
(self.created / 1000f64).round() as i64,
|
|
self.title.clone(),
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, new)]
|
|
pub struct LoggedStringifiedError {
|
|
error: String,
|
|
timestamp: f64,
|
|
}
|