#![cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] pub(crate) trait Replacer { fn replace(&mut self, original: &str) -> Result; } #[derive(Debug)] pub(crate) enum AbstractReplacer { GenericReplacer(GenericReplacer), GenericCdnReplacer(GenericCdnReplacer), } #[derive(Debug)] pub(crate) struct GenericReplacer { pub(crate) regex: regex::Regex, pub(crate) replacement: String, pub(crate) force_http: bool, } #[derive(Debug)] pub(crate) struct GenericCdnReplacer { pub(crate) regex: regex::Regex, pub(crate) replacement: Vec, pub(crate) force_http: bool, pub(crate) url_index: u8, } impl Replacer for AbstractReplacer { fn replace(&mut self, original: &str) -> Result { match self { AbstractReplacer::GenericReplacer(replacer) => replacer.replace(original), AbstractReplacer::GenericCdnReplacer(replacer) => replacer.replace(original) } } } impl Replacer for GenericReplacer { fn replace(&mut self, original: &str) -> Result { // Prepare output array let mut results: Vec = vec![]; // Perform the capture over input for (_, [scheme, path]) in self.regex.captures_iter(original).map(|c| c.extract()) { results.push(format!( "{}://{}/{}", if self.force_http { "http" } else { scheme }, self.replacement, path )); } // We are supposed to only parse one entry from text if 1 == results.len() { Ok(results.remove(0)) } else if results.is_empty() { Err("No valid url match found so returning original url".to_string()) } else { Err(format!("Invalid number of entries parsed, expected 1, obtained {:?}", results.len())) } } } impl Replacer for GenericCdnReplacer { fn replace(&mut self, original: &str) -> Result { // Prepare output array let mut results: Vec = vec![]; // Perform the capture over input for (_, [scheme, path]) in self.regex.captures_iter(original).map(|c| c.extract()) { results.push(format!( "{}://{}/{}", if self.force_http { "http" } else { scheme }, self.replacement[self.url_index as usize], path )); } // We are supposed to only parse one entry from text if 1 == results.len() { self.url_index = (self.url_index + 1) % self.replacement.len() as u8; Ok(results.remove(0)) } else if results.is_empty() { Err("No valid url match found".to_string()) } else { Err(format!("Invalid number of entries parsed, expected 1, obtained {:?}", results.len())) } } }