reddit-rs 0.1.1

A wrapper around the Reddit API.
Documentation
use iri_string::types::{IriAbsoluteString, IriString};
use serde::{Deserialize, Serialize};

mod oembed;

use crate::models::media::oembed::OEmbed;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct MediaEmbed {
    content: String,
    width: u16,
    scrolling: bool,
    media_domain_url: Option<IriString>,
    height: u16,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum Media {
    OEmbed(OEmbed),
    RedditVideo { reddit_video: RedditVideo },
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub struct RedditVideo {
    pub bitrate_kbps: u32,
    pub fallback_url: IriAbsoluteString,
    pub height: u32,
    pub width: u32,
    pub scrubber_media_url: IriAbsoluteString,
    pub dash_url: IriAbsoluteString,
    pub duration: u32,
    pub hls_url: IriAbsoluteString,
    pub is_gif: bool,
    pub transcoding_status: TranscodingStatus,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct MediaThumbnail {
    #[serde(rename = "thumbnail_width")]
    width: u16,
    #[serde(rename = "thumbnail_height")]
    height: u16,
    #[serde(rename = "thumbnail_url")]
    url: IriAbsoluteString,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TranscodingStatus {
    Completed,
}

#[cfg(test)]
mod test_media {
    #![allow(clippy::pedantic)]

    use super::*;
    use crate::models::media::oembed::{
        streamable, OEmbedData, OEmbedProvider, OEmbedType, OEmbedVersion,
    };

    #[test]
    fn test_youtube() {
        let media = Media::OEmbed(OEmbed::YouTube(OEmbedData {
            height: Default::default(),
            width: Default::default(),
            html: Default::default(),
            provider: OEmbedProvider {
                name: Default::default(),
                url: "https://www.reddit.com/".parse().unwrap(),
            },
            version: OEmbedVersion::V1_0,
            thumbnail: Some(MediaThumbnail {
                width: Default::default(),
                url: "https://www.reddit.com/".parse().unwrap(),
                height: Default::default(),
            }),
            ty: OEmbedType::Video,
            vendor_specific_data: oembed::youtube::YouTube {
                title: Default::default(),
                author_name: Default::default(),
                author_url: "https://www.reddit.com/".parse().unwrap(),
            },
        }));

        let _json = serde_json::to_string_pretty(&media).unwrap();
    }

    #[test]
    fn test_streamable() {
        let media = Media::OEmbed(OEmbed::Streamable(OEmbedData {
            height: Default::default(),
            width: Default::default(),
            html: Default::default(),
            provider: OEmbedProvider {
                name: Default::default(),
                url: "https://www.reddit.com/".parse().unwrap(),
            },
            version: OEmbedVersion::V1_0,
            thumbnail: Some(MediaThumbnail {
                width: Default::default(),
                url: "https://www.reddit.com/".parse().unwrap(),
                height: Default::default(),
            }),
            ty: OEmbedType::Video,
            vendor_specific_data: streamable::Streamable {
                title: Default::default(),
                description: Default::default(),
            },
        }));

        let json = serde_json::to_string_pretty(&media).unwrap();

        // println!("{}", json);

        let json = r#"
        {
            "oembed": {
              "provider_url": "https://streamable.com",
              "description": "Watch this video on Streamable.",
              "title": "Streamable Video",
              "thumbnail_width": 1280,
              "height": 338,
              "width": 600,
              "html": "<iframe class=\"embedly-embed\" src=\"https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fstreamable.com%2Fo%2Fgixxf0&display_name=Streamable&url=https%3A%2F%2Fstreamable.com%2Fgixxf0&image=https%3A%2F%2Fcdn-cf-east.streamable.com%2Fimage%2Fgixxf0.jpg%3FExpires%3D1634216820%26Signature%3DdoMgebEgi-eHwDrMcGIUyMTfOSBbA5tjLo9PtT4D4tjPPL3oLGzOGEEaro3kGUhP6L-0PplxBbHiuNBoFGDiKMJv0KWMBQ4VEdLSIQ0wB78%7EPe4kYENxS3gDtYk%7EUjUktnu3fFLeTCLCYTFVNm7e1mEqpIrB0yB6b9RAQ9igkaa2jhpRHceh0yOvQgXe-a-yg4VaDMPHHE4XAYHwzhO68s7066cWtvgj-Uci1PA%7E5W5qt7FqFDPT3FAmLgGbKopfQq-y8mKfTHu7KOfWVQgwEuEnHGe9I10cVW7e%7EMyfO9PY5oDzczhH7ffGU1fnDRXTQ2GGjhdkV2joVOgQ4CuX2Q__%26Key-Pair-Id%3DAPKAIEYUVEN4EVB2OKEQ&key=ed8fa8699ce04833838e66ce79ba05f1&type=text%2Fhtml&schema=streamable\" width=\"600\" height=\"338\" scrolling=\"no\" title=\"Streamable embed\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen=\"true\"></iframe>",
              "version": "1.0",
              "provider_name": "Streamable",
              "thumbnail_url": "https://cdn-cf-east.streamable.com/image/gixxf0.jpg?Expires=1634216820&Signature=doMgebEgi-eHwDrMcGIUyMTfOSBbA5tjLo9PtT4D4tjPPL3oLGzOGEEaro3kGUhP6L-0PplxBbHiuNBoFGDiKMJv0KWMBQ4VEdLSIQ0wB78~Pe4kYENxS3gDtYk~UjUktnu3fFLeTCLCYTFVNm7e1mEqpIrB0yB6b9RAQ9igkaa2jhpRHceh0yOvQgXe-a-yg4VaDMPHHE4XAYHwzhO68s7066cWtvgj-Uci1PA~5W5qt7FqFDPT3FAmLgGbKopfQq-y8mKfTHu7KOfWVQgwEuEnHGe9I10cVW7e~MyfO9PY5oDzczhH7ffGU1fnDRXTQ2GGjhdkV2joVOgQ4CuX2Q__&Key-Pair-Id=APKAIEYUVEN4EVB2OKEQ",
              "type": "video",
              "thumbnail_height": 720
            },
            "type": "streamable.com"
          }"#;

        dbg!(serde_json::from_str::<Media>(json).unwrap());
    }

    #[test]
    fn test_twitter() {
        let json = r##"
        {
            "type": "twitter.com",
            "oembed": {
                "version": "1.0",
                "url": "https://twitter.com/LordKebun/status/1447420243010281473",
                "author_name": "Kebun",
                "height": null,
                "width": 350,
                "html": "\u003Cblockquote class=\"twitter-video\"\u003E\u003Cp lang=\"en\" dir=\"ltr\"\u003ERate my Ramee RP Impersonation. \u003Ca href=\"https://t.co/vipSaqsrDe\"\u003Epic.twitter.com/vipSaqsrDe\u003C/a\u003E\u003C/p\u003E\u0026mdash; Kebun (@LordKebun) \u003Ca href=\"https://twitter.com/LordKebun/status/1447420243010281473?ref_src=twsrc%5Etfw\"\u003EOctober 11, 2021\u003C/a\u003E\u003C/blockquote\u003E\n\u003Cscript async src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"\u003E\u003C/script\u003E\n",
                "author_url": "https://twitter.com/LordKebun",
                "cache_age": 3153600000,
                "type": "rich",
                "provider_url": "https://twitter.com",
                "provider_name": "Twitter"
            }
        }"##;

        dbg!(serde_json::from_str::<Media>(json).unwrap());
    }

    #[test]
    fn test_oembed_bandcamp() {
        let json = r##"{
            "type": "futurespiritualman.bandcamp.com",
            "oembed": {
              "provider_url": "http://bandcamp.com",
              "description": "beaf by futurespiritualman, released 01 January 2021 1. b-horn ft._Lil Peter_&amp;_Frank.mp3 2. funk_part_2._ft_FUNKEYMAN_supreme.mp3 3. the_toop_ft._Lil_Peter.mp3 4. i_eat_rocks.mp3 5. dog_walker_ft._Gizzer_NP_.mp3 6. beefstew_ft._SuizideDeth.mp3 7. going_to_jail_part_II.mp3 8. breats_ft._Lil_Peter.mp3 9. my_truck_ft._BigK2000.mp3 10. balls2man.mp3 11. FIVE_thefourtyninerswinin2075.mp3 12. good_he.mp3 13. i_eat_rocks.mp3 14. truck_(_truck_truck_truck_truck_).mp3 15. my_truck_part_2._ft._Frank(version_1_).mp3 16. cum)lord__.mp3 17. joe.mp3 18. truck_4_(version2).mp3 19. i_love_youft.__Frank.mp3 20. RAP_ft._thelegendsupreme.mp3 21.",
              "title": "beaf, by futurespiritualman",
              "type": "rich",
              "thumbnail_width": 700,
              "height": 467,
              "width": 350,
              "html": "<iframe class=\"embedly-embed\" src=\"https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fbandcamp.com%2FEmbeddedPlayer%2Fv%3D2%2Falbum%3D1766047770%2Fsize%3Dlarge%2Flinkcol%3D0084B4%2Fnotracklist%3Dtrue%2Ftwittercard%3Dtrue%2F&display_name=BandCamp&url=https%3A%2F%2Ffuturespiritualman.bandcamp.com%2Falbum%2Fbeaf&image=https%3A%2F%2Ff4.bcbits.com%2Fimg%2Fa2778328046_5.jpg&key=ed8fa8699ce04833838e66ce79ba05f1&type=text%2Fhtml&schema=bandcamp\" width=\"350\" height=\"467\" scrolling=\"no\" title=\"BandCamp embed\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen=\"true\"></iframe>",
              "version": "1.0",
              "provider_name": "BandCamp",
              "thumbnail_url": "https://f4.bcbits.com/img/a2778328046_5.jpg",
              "thumbnail_height": 700
            }
          }"##;

        dbg!(serde_json::from_str::<Media>(json).unwrap());
    }
}