video_url_validator/
lib.rs1pub mod error;
25pub mod utils;
26
27pub use error::ValidationError;
28pub use utils::*;
29
30use regex::Regex;
31use std::collections::HashMap;
32
33#[derive(Debug, Clone, PartialEq, Eq, Hash)]
35pub enum VideoPlatform {
36 YouTube,
37 Facebook,
38 Vimeo,
39 DailyMotion,
40 Wistia,
41}
42
43impl VideoPlatform {
44 pub fn as_str(&self) -> &'static str {
46 match self {
47 VideoPlatform::YouTube => "YouTube",
48 VideoPlatform::Facebook => "Facebook",
49 VideoPlatform::Vimeo => "Vimeo",
50 VideoPlatform::DailyMotion => "DailyMotion",
51 VideoPlatform::Wistia => "Wistia",
52 }
53 }
54}
55
56pub struct VideoUrlValidator {
58 patterns: HashMap<VideoPlatform, Regex>,
59}
60
61impl VideoUrlValidator {
62 pub fn new() -> Self {
64 let mut patterns = HashMap::new();
65
66 let youtube_pattern = Regex::new(
68 r"^https?://(www\.)?(youtube\.com/(watch\?v=|embed/|v/)|youtu\.be/)[\w-]+(&[\w=&-]*)?$",
69 )
70 .expect("Invalid YouTube regex pattern");
71 patterns.insert(VideoPlatform::YouTube, youtube_pattern);
72
73 let facebook_pattern = Regex::new(
75 r"^https?://(www\.)?facebook\.com/(.*/)?(video\.php\?v=|videos/)[\d]+/?(\?.*)?$",
76 )
77 .expect("Invalid Facebook regex pattern");
78 patterns.insert(VideoPlatform::Facebook, facebook_pattern);
79
80 let vimeo_pattern = Regex::new(r"^https?://(www\.)?vimeo\.com/[\d]+/?(\?.*)?$")
82 .expect("Invalid Vimeo regex pattern");
83 patterns.insert(VideoPlatform::Vimeo, vimeo_pattern);
84
85 let dailymotion_pattern =
87 Regex::new(r"^https?://(www\.)?(dailymotion\.com/video/|dai\.ly/)[\w-]+/?(\?.*)?$")
88 .expect("Invalid DailyMotion regex pattern");
89 patterns.insert(VideoPlatform::DailyMotion, dailymotion_pattern);
90
91 let wistia_pattern =
93 Regex::new(r"^https?://([^.]+\.)?wistia\.com/(medias|embed)/[\w-]+/?(\?.*)?$")
94 .expect("Invalid Wistia regex pattern");
95 patterns.insert(VideoPlatform::Wistia, wistia_pattern);
96
97 Self { patterns }
98 }
99
100 pub fn validate_youtube_video_url(&self, url: &str) -> bool {
102 self.patterns
103 .get(&VideoPlatform::YouTube)
104 .map(|regex| regex.is_match(url))
105 .unwrap_or(false)
106 }
107
108 pub fn validate_facebook_video_url(&self, url: &str) -> bool {
110 self.patterns
111 .get(&VideoPlatform::Facebook)
112 .map(|regex| regex.is_match(url))
113 .unwrap_or(false)
114 }
115
116 pub fn validate_vimeo_video_url(&self, url: &str) -> bool {
118 self.patterns
119 .get(&VideoPlatform::Vimeo)
120 .map(|regex| regex.is_match(url))
121 .unwrap_or(false)
122 }
123
124 pub fn validate_dailymotion_video_url(&self, url: &str) -> bool {
126 self.patterns
127 .get(&VideoPlatform::DailyMotion)
128 .map(|regex| regex.is_match(url))
129 .unwrap_or(false)
130 }
131
132 pub fn validate_wistia_video_url(&self, url: &str) -> bool {
134 self.patterns
135 .get(&VideoPlatform::Wistia)
136 .map(|regex| regex.is_match(url))
137 .unwrap_or(false)
138 }
139
140 pub fn validate_video_url(&self, url: &str) -> Option<VideoPlatform> {
142 for (platform, regex) in &self.patterns {
143 if regex.is_match(url) {
144 return Some(platform.clone());
145 }
146 }
147 None
148 }
149
150 pub fn is_valid_video_url(&self, url: &str) -> bool {
152 self.validate_video_url(url).is_some()
153 }
154
155 pub fn supported_platforms(&self) -> Vec<VideoPlatform> {
157 self.patterns.keys().cloned().collect()
158 }
159
160 pub fn validate_multiple(&self, urls: &[&str]) -> Vec<(String, Option<VideoPlatform>)> {
162 urls.iter()
163 .map(|url| (url.to_string(), self.validate_video_url(url)))
164 .collect()
165 }
166}
167
168impl Default for VideoUrlValidator {
169 fn default() -> Self {
170 Self::new()
171 }
172}