use crate::media_content;
use crate::model::{ContentCounter, CurrencyPrices};
use crate::traits::{HasContent, HasTitle, IsAvailable};
use crate::{
media_content::ContentItem,
model::{Reactions, Tag, User},
};
use rust_decimal::Decimal;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
pub struct PostsResponse {
pub data: Vec<Post>,
pub extra: Extra,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Extra {
pub offset: String,
pub is_last: bool,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Post {
pub user: User,
pub is_pinned: bool,
pub is_blocked: bool,
pub has_access: bool,
pub data: Vec<MediaData>,
pub is_record: bool,
pub content_counters: Vec<ContentCounter>,
pub donators: Donators,
pub show_views_counter: bool,
pub created_at: i64,
pub is_published: bool,
pub is_liked: bool,
pub tags: Vec<Tag>,
pub is_comments_denied: bool,
pub count: Count,
pub publish_time: i64,
pub title: String,
pub sort_order: i64,
pub price: i32,
pub id: String,
pub comments: Comments,
pub donations: Decimal,
pub teaser: Vec<MediaData>,
pub is_waiting_video: bool,
#[serde(rename = "int_id")]
pub int_id: i64,
pub is_deleted: bool,
pub updated_at: i64,
pub signed_query: String,
pub advertiser_info: Option<serde_json::Value>,
pub currency_prices: CurrencyPrices,
pub is_showcase_visible: bool,
pub reactions_disabled: bool,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Flags {
pub show_post_donations: bool,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct VideoData {
pub url: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct OkVideoData {
pub upload_status: Option<String>,
pub width: u32,
pub status: String,
pub title: String,
pub url: String,
pub preview_id: Option<String>,
pub player_urls: Vec<PlayerUrl>,
pub id: String,
pub vid: String,
pub preview: String,
pub height: u32,
pub time_code: i32,
pub show_views_counter: bool,
pub duration: u32,
pub complete: bool,
pub views_counter: u32,
pub default_preview: String,
pub failover_host: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct AudioData {
pub show_views_counter: bool,
pub upload_status: Option<String>,
pub complete: bool,
pub time_code: u32,
pub size: u64,
pub id: String,
pub url: String,
pub artist: Option<String>,
pub album: Option<String>,
pub file_type: Option<String>,
pub title: String,
pub track: Option<String>,
pub duration: Option<u32>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ImageData {
pub url: String,
pub width: Option<u32>,
pub height: Option<u32>,
pub preview: Option<String>,
pub rendition: Option<String>,
pub id: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TextData {
pub modificator: String,
pub content: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct SmileData {
pub small_url: String,
pub medium_url: String,
pub large_url: String,
pub name: String,
pub id: String,
pub is_animated: bool,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct LinkData {
pub explicit: bool,
pub content: String,
pub url: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct FileData {
pub id: String,
pub title: String,
pub url: String,
pub complete: bool,
pub size: u64,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct PlayerUrl {
#[serde(rename = "type")]
pub type_: String,
pub url: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Donators {
pub extra: ExtraFlag,
pub data: Vec<serde_json::Value>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ExtraFlag {
pub is_last: bool,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Comments {
pub extra: ExtraFlag,
pub data: Vec<serde_json::Value>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Count {
pub comments: u32,
pub reactions: Reactions,
pub likes: u32,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListData {
pub style: String,
pub items: Vec<ListItem>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListItem {
pub data: Vec<MediaData>,
pub items: Vec<ListItem>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase", tag = "type")]
pub enum MediaData {
#[serde(rename = "video", rename_all = "camelCase")]
Video(VideoData),
#[serde(rename = "ok_video", rename_all = "camelCase")]
OkVideo(OkVideoData),
#[serde(rename = "audio_file", rename_all = "camelCase")]
Audio(AudioData),
#[serde(rename = "image", rename_all = "camelCase")]
Image(ImageData),
#[serde(rename = "text", rename_all = "camelCase")]
Text(TextData),
#[serde(rename = "smile", rename_all = "camelCase")]
Smile(SmileData),
#[serde(rename = "link", rename_all = "camelCase")]
Link(LinkData),
#[serde(rename = "file", rename_all = "camelCase")]
File(FileData),
#[serde(rename = "list", rename_all = "camelCase")]
List(ListData),
#[serde(other)]
Unknown,
}
impl IsAvailable for Post {
fn not_available(&self) -> bool {
!self.has_access || self.data.is_empty()
}
}
impl HasTitle for Post {
fn safe_title(&self) -> String {
if self.title.trim().is_empty() {
format!("untitled_{}", self.id)
} else {
self.title.clone()
}
}
}
impl HasContent for Post {
fn extract_content(&self) -> Vec<ContentItem> {
media_content::extract_content(&self.data)
}
}