use std::env; use std::fs; use std::path::PathBuf; struct ProviderDef { id: &'static str, module: &'static str, ty: &'static str, } const PROVIDERS: &[ProviderDef] = &[ ProviderDef { id: "all", module: "all", ty: "AllProvider", }, ProviderDef { id: "perverzija", module: "perverzija", ty: "PerverzijaProvider", }, ProviderDef { id: "hanime", module: "hanime", ty: "HanimeProvider", }, ProviderDef { id: "pornhub", module: "pornhub", ty: "PornhubProvider", }, ProviderDef { id: "spankbang", module: "spankbang", ty: "SpankbangProvider", }, ProviderDef { id: "rule34video", module: "rule34video", ty: "Rule34videoProvider", }, ProviderDef { id: "redtube", module: "redtube", ty: "RedtubeProvider", }, ProviderDef { id: "okporn", module: "okporn", ty: "OkpornProvider", }, ProviderDef { id: "pornhat", module: "pornhat", ty: "PornhatProvider", }, ProviderDef { id: "perfectgirls", module: "perfectgirls", ty: "PerfectgirlsProvider", }, ProviderDef { id: "okxxx", module: "okxxx", ty: "OkxxxProvider", }, ProviderDef { id: "homoxxx", module: "homoxxx", ty: "HomoxxxProvider", }, ProviderDef { id: "missav", module: "missav", ty: "MissavProvider", }, ProviderDef { id: "xxthots", module: "xxthots", ty: "XxthotsProvider", }, ProviderDef { id: "yesporn", module: "yesporn", ty: "YespornProvider", }, ProviderDef { id: "sxyprn", module: "sxyprn", ty: "SxyprnProvider", }, ProviderDef { id: "porn00", module: "porn00", ty: "Porn00Provider", }, ProviderDef { id: "youjizz", module: "youjizz", ty: "YoujizzProvider", }, ProviderDef { id: "paradisehill", module: "paradisehill", ty: "ParadisehillProvider", }, ProviderDef { id: "porn4fans", module: "porn4fans", ty: "Porn4fansProvider", }, ProviderDef { id: "porndish", module: "porndish", ty: "PorndishProvider", }, ProviderDef { id: "shooshtime", module: "shooshtime", ty: "ShooshtimeProvider", }, ProviderDef { id: "pornzog", module: "pornzog", ty: "PornzogProvider", }, ProviderDef { id: "omgxxx", module: "omgxxx", ty: "OmgxxxProvider", }, ProviderDef { id: "beeg", module: "beeg", ty: "BeegProvider", }, ProviderDef { id: "tnaflix", module: "tnaflix", ty: "TnaflixProvider", }, ProviderDef { id: "tokyomotion", module: "tokyomotion", ty: "TokyomotionProvider", }, ProviderDef { id: "viralxxxporn", module: "viralxxxporn", ty: "ViralxxxpornProvider", }, ProviderDef { id: "vrporn", module: "vrporn", ty: "VrpornProvider", }, ProviderDef { id: "rule34gen", module: "rule34gen", ty: "Rule34genProvider", }, ProviderDef { id: "xxdbx", module: "xxdbx", ty: "XxdbxProvider", }, ProviderDef { id: "xfree", module: "xfree", ty: "XfreeProvider", }, ProviderDef { id: "hqporner", module: "hqporner", ty: "HqpornerProvider", }, ProviderDef { id: "pmvhaven", module: "pmvhaven", ty: "PmvhavenProvider", }, ProviderDef { id: "noodlemagazine", module: "noodlemagazine", ty: "NoodlemagazineProvider", }, ProviderDef { id: "pimpbunny", module: "pimpbunny", ty: "PimpbunnyProvider", }, ProviderDef { id: "javtiful", module: "javtiful", ty: "JavtifulProvider", }, ProviderDef { id: "hypnotube", module: "hypnotube", ty: "HypnotubeProvider", }, ProviderDef { id: "freepornvideosxxx", module: "freepornvideosxxx", ty: "FreepornvideosxxxProvider", }, ProviderDef { id: "heavyfetish", module: "heavyfetish", ty: "HeavyfetishProvider", }, ProviderDef { id: "hsex", module: "hsex", ty: "HsexProvider", }, ProviderDef { id: "hentaihaven", module: "hentaihaven", ty: "HentaihavenProvider", }, ProviderDef { id: "chaturbate", module: "chaturbate", ty: "ChaturbateProvider", }, ]; fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-env-changed=HOT_TUB_PROVIDER"); println!("cargo:rerun-if-env-changed=HOTTUB_PROVIDER"); println!("cargo:rustc-check-cfg=cfg(hottub_single_provider)"); let selected = env::var("HOT_TUB_PROVIDER") .or_else(|_| env::var("HOTTUB_PROVIDER")) .ok() .map(|value| value.trim().to_string()) .filter(|value| !value.is_empty()); let providers = match selected.as_deref() { Some(selected_id) => { let provider = PROVIDERS .iter() .find(|provider| provider.id == selected_id) .unwrap_or_else(|| { panic!("Unknown provider `{selected_id}` from HOT_TUB_PROVIDER/HOTTUB_PROVIDER") }); println!("cargo:rustc-cfg=hottub_single_provider"); vec![provider] } None => PROVIDERS.iter().collect(), }; let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR")); let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR")); let modules = providers .iter() .map(|provider| { let module_path = manifest_dir .join("src/providers") .join(format!("{}.rs", provider.module)); format!( "#[path = r#\"{}\"#]\npub mod {};", module_path.display(), provider.module ) }) .collect::>() .join("\n"); fs::write(out_dir.join("provider_modules.rs"), format!("{modules}\n")) .expect("write provider_modules.rs"); let registry = providers .iter() .map(|provider| { format!( "m.insert(\"{id}\", Arc::new({module}::{ty}::new()) as DynProvider);", id = provider.id, module = provider.module, ty = provider.ty ) }) .collect::>() .join("\n"); fs::write( out_dir.join("provider_registry.rs"), format!("{{\n{registry}\n}}\n"), ) .expect("write provider_registry.rs"); let metadata_arms = providers .iter() .map(|provider| { if provider.id == "all" { format!( "\"all\" | \"hottub\" => Some({module}::CHANNEL_METADATA),", module = provider.module ) } else { format!( "\"{id}\" => Some({module}::CHANNEL_METADATA),", id = provider.id, module = provider.module ) } }) .collect::>() .join("\n"); fs::write( out_dir.join("provider_metadata_fn.rs"), format!("match id {{\n{metadata_arms}\n_ => None,\n}}\n"), ) .expect("write provider_metadata_fn.rs"); let selection = match selected.as_deref() { Some(selected_id) => format!( "pub const COMPILE_TIME_SELECTED_PROVIDER: Option<&str> = Some(\"{selected_id}\");" ), None => "pub const COMPILE_TIME_SELECTED_PROVIDER: Option<&str> = None;".to_string(), }; fs::write( out_dir.join("provider_selection.rs"), format!("{selection}\n"), ) .expect("write provider_selection.rs"); }