reddit-image-wall-rs/src/sync/model.rs

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,
}