feat: add video details response model

- add paginator, impl for playlist items
- small model refactor
- add ignore_any deserializer
- removed unnecessary clones in response mapping
This commit is contained in:
ThetaDev 2022-09-19 00:08:37 +02:00
parent 17b6844eb0
commit 972288d810
32 changed files with 61791 additions and 5316 deletions

View file

@ -1,21 +1,27 @@
pub mod locale;
mod ordering;
mod paginator;
pub mod stream_filter;
pub use locale::{Country, Language};
pub use paginator::Paginator;
use std::ops::Range;
use chrono::{DateTime, Local};
use serde::{Deserialize, Serialize};
/*
#PLAYER
*/
pub trait FileFormat {
fn extension(&self) -> &str;
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct VideoPlayer {
pub info: VideoInfo,
pub details: VideoPlayerDetails,
pub video_streams: Vec<VideoStream>,
pub video_only_streams: Vec<VideoStream>,
pub audio_streams: Vec<AudioStream>,
@ -23,28 +29,14 @@ pub struct VideoPlayer {
pub expires_in_seconds: u32,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Playlist {
pub id: String,
pub name: String,
pub videos: Vec<Video>,
pub n_videos: u32,
pub ctoken: Option<String>,
pub thumbnails: Vec<Thumbnail>,
pub description: Option<String>,
pub channel: Option<Channel>,
pub last_update: Option<DateTime<Local>>,
pub last_update_txt: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct VideoInfo {
pub struct VideoPlayerDetails {
pub id: String,
pub title: String,
pub description: Option<String>,
pub length: u32,
pub thumbnails: Vec<Thumbnail>,
pub channel: Channel,
pub channel: ChannelId,
pub publish_date: Option<DateTime<Local>>,
pub view_count: u64,
pub keywords: Vec<String>,
@ -182,17 +174,81 @@ pub struct Subtitle {
pub auto_generated: bool,
}
/*
#PLAYLIST
*/
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Playlist {
pub id: String,
pub name: String,
pub videos: Paginator<PlaylistVideo>,
pub n_videos: u32,
pub thumbnails: Vec<Thumbnail>,
pub description: Option<String>,
pub channel: Option<ChannelId>,
pub last_update: Option<DateTime<Local>>,
pub last_update_txt: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Video {
pub struct PlaylistVideo {
pub id: String,
pub title: String,
pub length: u32,
pub thumbnails: Vec<Thumbnail>,
pub channel: Channel,
pub channel: ChannelId,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ChannelId {
pub id: String,
pub name: String,
}
/*
#VIDEO DETAILS
*/
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct VideoDetails {
pub id: String,
pub title: String,
pub description: String,
}
/*
@COMMENTS
*/
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Channel {
pub id: String,
pub name: String,
pub avatars: Vec<Thumbnail>,
pub verified: bool,
}
// TODO: impl popularity comparison
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Comment {
/// Unique YouTube Comment-ID (e.g. `UgynScMrsqGSL8qvePl4AaABAg`)
pub id: String,
/// Comment text
pub text: String,
/// Comment author
///
/// There may be comments with missing authors (possibly deleted users?).
pub author: Option<Channel>,
/// Number of upvotes
pub upvotes: u32,
/// Number of replies
pub n_replies: u32,
/// Paginator to fetch comment replies
pub replies: Paginator<Comment>,
/// Is the comment from the channel owner?
pub by_owner: bool,
/// Has the channel owner pinned the comment to the top?
pub pinned: bool,
/// Has the channel owner marked the comment with a ❤️ ?
pub hearted: bool,
}

54
src/model/paginator.rs Normal file
View file

@ -0,0 +1,54 @@
use serde::{Deserialize, Serialize};
/// The paginator is a wrapper around a list of items that are fetched
/// in pages from the YouTube API (e.g. playlist items,
/// video recommendations or comments).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Paginator<T> {
/*
/// Total number of items if finite and known.
///
/// Note that this number may not be 100% accurate, as this is the
/// number returned by the YouTube API at the initial fetch.
///
/// It is intended to be shown to the user (e.g. 1261 comments,
/// 18 Videos) and for progress estimation.
///
/// Don't use this number to check if all items were fetched or for
/// iterating over the items.
pub count: Option<u32>,
*/
/// Content of the paginator
pub items: Vec<T>,
/// The continuation token is passed to the YouTube API to fetch
/// more items.
///
/// If it is None, it means that no more items can be fetched.
pub ctoken: Option<String>,
}
impl<T> Default for Paginator<T> {
fn default() -> Self {
Self {
items: Vec::new(),
ctoken: None,
}
}
}
impl<T> Paginator<T> {
/// Check if the paginator is exhausted, meaning that no more
/// items can be fetched.
///
/// Equivalent to `paginator.ctoken.is_none()`.
pub fn is_exhausted(&self) -> bool {
self.ctoken.is_none()
}
/// Check if the paginator does not contain any data, meaning that it
/// is exhausted and does not contain any items.
pub fn is_empty(&self) -> bool {
self.items.is_empty() && self.is_exhausted()
}
}