use std::env;
use std::fs::{self, File};
use std::io::{self};
use std::path::{Path, PathBuf};
use askama::Template;
use flate2::write::GzEncoder;
use flate2::Compression;
#[derive(Template)]
#[template(path = "index.html.txt")]
pub(crate) struct IndexTemplate<'a> {
pub(crate) script_source: &'a str,
}
#[derive(Template)]
#[template(path = "webworker.js.txt")]
pub(crate) struct WebWorkerTemplate<'a> {
pub(crate) script_source: &'a str,
}
const VIZ_VERSION: &str = "1.8.2";
#[cfg(not(feature = "telemetry_server_builtin"))]
const USE_INTERNAL_VIZ: bool = false;
#[cfg(feature = "telemetry_server_builtin")]
const USE_INTERNAL_VIZ: bool = true;
#[cfg(any(feature = "telemetry_server_cdn", feature = "telemetry_server_builtin"))]
const TELEMETRY_SERVICE: bool = true;
#[cfg(not(any(feature = "telemetry_server_cdn", feature = "telemetry_server_builtin")))]
const TELEMETRY_SERVICE: bool = false;
fn main() {
println!("cargo:warning=########### Community support needed ###########################");
println!("cargo:warning=Please Sponsor Steady_State: https://github.com/sponsors/kmf-lab");
println!("cargo:warning=################################################################");
let base_target_path = env::var("CARGO_TARGET_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| PathBuf::from("target"));
if TELEMETRY_SERVICE && USE_INTERNAL_VIZ {
gzip_encode_web_resource(
&base_target_path,
"static/telemetry/viz-lite.js",
&format!("https://unpkg.com/viz.js@{}/viz-lite.js", VIZ_VERSION),
);
}
if TELEMETRY_SERVICE {
let cdn_source = format!("https://unpkg.com/viz.js@{}/viz-lite.js", VIZ_VERSION);
let source = if USE_INTERNAL_VIZ {
"viz-lite.js" } else {
&cdn_source };
let folder_base = PathBuf::from("static/telemetry/");
let index_content = IndexTemplate { script_source: source }
.render()
.expect("Failed to render index.html template");
let index_path = folder_base.join("index.html");
let should_write = if Path::new(&index_path).exists() {
match fs::read_to_string(&index_path) {
Ok(existing_content) => existing_content != index_content,
Err(_) => true, }
} else {
true };
if should_write {
fs::write(&index_path, &index_content)
.expect("Failed to write index.html");
gzip_encode(&base_target_path, "static/telemetry/index.html", false);
}
gzip_encode(&base_target_path, "static/telemetry/index.html", true);
let webworker_content = WebWorkerTemplate { script_source: source }
.render()
.expect("Failed to render webworker.js template");
let webworker_path = folder_base.join("webworker.js");
let should_write = if Path::new(&webworker_path).exists() {
match fs::read_to_string(&webworker_path) {
Ok(existing_content) => existing_content != webworker_content,
Err(_) => true, }
} else {
true };
if should_write {
fs::write(&webworker_path, &webworker_content)
.expect("Failed to write webworker.js");
gzip_encode(&base_target_path, "static/telemetry/webworker.js", false);
}
gzip_encode(&base_target_path, "static/telemetry/webworker.js", true);
gzip_encode(&base_target_path, "static/telemetry/dot-viewer.js", true);
gzip_encode(&base_target_path, "static/telemetry/dot-viewer.css", true);
let file_path = "static/telemetry/images/spinner.gif";
simple_copy(Path::new(file_path), &base_target_path.join(file_path));
}
}
fn simple_copy(source_file: &Path, target_file: &PathBuf) -> bool {
if target_file.exists() {
println!("cargo:trace={:?} already exists, skipping copy", target_file);
return true;
}
if let Some(parent_dir) = target_file.parent() {
fs::create_dir_all(parent_dir).expect("Failed to create target directory");
}
let mut source = File::open(source_file).expect("Failed to open source file");
let mut target = File::create(target_file).expect("Failed to create target file");
io::copy(&mut source, &mut target).expect("Failed to copy file content");
println!("cargo:warning=Copied {:?} to {:?}", source_file, target_file);
false
}
fn gzip_encode_web_resource(target: &Path, file_path: &str, get_url: &str) {
let output_name = format!("{}.gz", file_path);
let target_file = target.join(&output_name);
if !target_file.exists() {
let mut response = isahc::get(get_url).expect("Failed to download viz-lite.js");
let mut file = File::create(file_path).expect("Failed to create temporary file");
io::copy(&mut response.body_mut(), &mut file)
.expect("Failed to write downloaded content");
}
gzip_encode(target, file_path, true);
if Path::new(file_path).exists() {
fs::remove_file(file_path).expect("Failed to remove temporary file");
}
}
fn gzip_encode(target: &Path, file_path: &str, skip_if_exists: bool) {
let output_name = format!("{}.gz", file_path);
let target_file = target.join(&output_name);
if let Some(parent_dir) = target_file.parent() {
fs::create_dir_all(parent_dir).expect("Failed to create output directory");
}
if skip_if_exists && target_file.exists() {
println!("cargo:trace={:?} already exists, skipping compression", target_file);
return;
}
let mut input = File::open(file_path).expect("Failed to open input file");
let output = File::create(&target_file).expect("Failed to create output file");
let mut encoder = GzEncoder::new(output, Compression::default());
io::copy(&mut input, &mut encoder).expect("Failed to compress file");
encoder.finish().expect("Failed to finalize compression");
println!("cargo:trace=Compressed {:?} to {:?}", file_path, target_file);
}