use std::{ fs::{self, File, OpenOptions}, io::{BufWriter, Write}, path::Path, }; use anyhow::Context; // use bgzip::{BGZFWriter, Compression}; use log::info; use crate::io::readers::get_reader; // pub fn get_gz_writer(path: &str, force: bool) -> anyhow::Result> { // if !path.ends_with(".gz") { // anyhow::bail!("The file should end with gz"); // } // // if force && Path::new(path).exists() { // fs::remove_file(path).with_context(|| anyhow::anyhow!("Failed to remove file: {path}"))?; // } // // let file = OpenOptions::new() // .write(true) // Open the file for writing // .create_new(true) // .truncate(true) // .open(path) // .with_context(|| anyhow::anyhow!("failed to open the file: {path}"))?; // // info!("Writing into {path}"); // Ok(BGZFWriter::new(file, Compression::default())) // } use noodles_bgzf as bgzf; pub fn get_gz_writer( path: &str, force: bool, ) -> anyhow::Result>> { if !path.ends_with(".gz") { anyhow::bail!("file should end with .gz: {path}"); } if force && std::path::Path::new(path).exists() { fs::remove_file(path).with_context(|| format!("failed to remove file: {path}"))?; } let file = OpenOptions::new() .write(true) .create_new(true) .open(path) .with_context(|| format!("failed to create BGZF file: {path}"))?; Ok(bgzf::io::Writer::new(BufWriter::new(file))) } pub fn get_writer(path: &str) -> anyhow::Result> { let file = OpenOptions::new() .write(true) // Open the file for writing .create_new(true) .truncate(true) .open(path) .with_context(|| anyhow::anyhow!("failed to open the file: {path}"))?; info!("Writing into {path}"); Ok(BufWriter::new(file)) } pub fn convert_bgz(input: impl AsRef, force: bool) -> anyhow::Result<()> { let input = input.as_ref(); let mut reader = get_reader(&input.to_string_lossy())?; let mut writer = get_gz_writer(&format!("{}.gz", input.display()), force)?; std::io::copy(&mut reader, &mut writer)?; writer .try_finish() .with_context(|| format!("failed finishing BGZF writer: {}", input.display()))?; let mut inner = writer .finish() .with_context(|| format!("failed returning inner BGZF writer: {}", input.display()))?; inner .flush() .with_context(|| format!("failed flushing inner writer: {}", input.display()))?; inner .into_inner() .with_context(|| format!("failed unwrapping BufWriter: {}", input.display()))? .sync_all() .with_context(|| format!("failed syncing file: {}", input.display()))?; Ok(()) } pub fn finalize_bgzf_file( writer: bgzf::io::Writer>, path: &str, ) -> anyhow::Result<()> { let mut inner = writer .finish() .with_context(|| format!("failed finishing BGZF writer: {path}"))?; inner .flush() .with_context(|| format!("failed flushing BufWriter: {path}"))?; inner .into_inner() .with_context(|| format!("failed unwrapping BufWriter: {path}"))? .sync_all() .with_context(|| format!("failed syncing file: {path}"))?; Ok(()) } #[cfg(test)] mod tests { use super::*; use crate::helpers::test_init; #[test] fn bgz_convert() -> anyhow::Result<()> { test_init(); let a = "/mnt/beegfs02/scratch/t_steimle/data/wgs/DUMCO/diag/DUMCO_diag_modkit_pileup.bed"; convert_bgz(a, true)?; let a = "/mnt/beegfs02/scratch/t_steimle/data/wgs/DUMCO/norm/DUMCO_norm_modkit_pileup.bed"; convert_bgz(a, true)?; Ok(()) } }