validator_rs/
url.rs

1//! URL validation functions
2
3use regex::Regex;
4use std::sync::OnceLock;
5
6static URL_REGEX: OnceLock<Regex> = OnceLock::new();
7
8fn get_url_regex() -> &'static Regex {
9    URL_REGEX.get_or_init(|| {
10        Regex::new(r"^https?://[^\s/$.?#].[^\s]*$")
11            .expect("Failed to compile URL regex")
12    })
13}
14
15/// Validates if a string is a valid URL
16///
17/// # Examples
18///
19/// ```
20/// use validator_rs::url::is_valid_url;
21///
22/// assert!(is_valid_url("https://www.example.com"));
23/// assert!(is_valid_url("http://example.com/path?query=1"));
24/// assert!(!is_valid_url("not a url"));
25/// assert!(!is_valid_url("ftp://example.com"));
26/// ```
27pub fn is_valid_url(url: &str) -> bool {
28    if url.is_empty() {
29        return false;
30    }
31
32    get_url_regex().is_match(url)
33}
34
35/// Validates if a string is a valid HTTPS URL only
36pub fn is_valid_https_url(url: &str) -> bool {
37    url.starts_with("https://") && is_valid_url(url)
38}
39
40/// Validates if a URL belongs to a specific domain
41pub fn is_url_from_domain(url: &str, domain: &str) -> bool {
42    if !is_valid_url(url) {
43        return false;
44    }
45
46    url.contains(&format!("://{}", domain)) || url.contains(&format!("://www.{}", domain))
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn test_valid_urls() {
55        assert!(is_valid_url("https://www.example.com"));
56        assert!(is_valid_url("http://example.com"));
57        assert!(is_valid_url("https://example.com/path/to/page"));
58        assert!(is_valid_url("https://example.com?query=1&other=2"));
59    }
60
61    #[test]
62    fn test_invalid_urls() {
63        assert!(!is_valid_url(""));
64        assert!(!is_valid_url("not a url"));
65        assert!(!is_valid_url("ftp://example.com"));
66        assert!(!is_valid_url("javascript:alert(1)"));
67    }
68
69    #[test]
70    fn test_https_only() {
71        assert!(is_valid_https_url("https://example.com"));
72        assert!(!is_valid_https_url("http://example.com"));
73    }
74
75    #[test]
76    fn test_url_domain() {
77        assert!(is_url_from_domain("https://example.com/path", "example.com"));
78        assert!(is_url_from_domain("https://www.example.com/path", "example.com"));
79        assert!(!is_url_from_domain("https://other.com/path", "example.com"));
80    }
81}
82