1use url::Url;
2use reqwest;
3use serde_json::Value;
4use std::collections::HashMap;
5
6pub(crate) fn get_youtube_id(value: &str) -> Option<String> {
7 let parsed_url = Url::parse(value).ok()?;
8
9 match parsed_url.host_str()? {
10 "youtu.be" => Some(parsed_url.path()[1..].to_string()),
11
12 "www.youtube.com" | "youtube.com" => {
13 let path = parsed_url.path();
14
15 if path == "/watch" {
16 let query_pairs: HashMap<_, _> = parsed_url.query_pairs().into_owned().collect();
17 if let Some(video_id) = query_pairs.get("v") {
18 return Some(video_id.to_string());
19 }
20 } else if path.starts_with("/embed/") || path.starts_with("/v/") {
21 let segments: Vec<&str> = path.split('/').collect();
22 if segments.len() > 2 {
23 return Some(segments[2].to_string());
24 }
25 }
26
27 None
28 }
29
30 _ => None,
31 }
32}
33
34pub(crate) fn get_twitter_embed(tweet_url: &str) -> Option<String> {
35 let parsed_url = Url::parse(tweet_url).ok()?;
36
37 match parsed_url.host_str()? {
38 "twitter.com" | "x.com" => {
39 let api_url = format!("https://publish.twitter.com/oembed?url={}", tweet_url);
41
42 let response = reqwest::blocking::get(&api_url).ok()?;
44
45 let json: Value = response.json().ok()?;
47
48 if let Some(html) = json.get("html") {
50 return html.as_str().map(|s| s.to_string());
51 }
52 None
53 }
54 _ => None, }
56}
57
58
59pub(crate) fn get_gyazo_img_src(url: &str) -> Option<String> {
60 let parsed_url = Url::parse(url).ok()?;
61
62 match parsed_url.host_str()? {
63 "gyazo.com" => Some(format!("https://i.gyazo.com/{}.png", parsed_url.path()[1..].to_string())),
64 _ => None,
65 }
66}