noodles_vcf/io/writer/
builder.rs

1use std::{
2    fs::File,
3    io::{self, BufWriter, Write},
4    path::Path,
5};
6
7use noodles_bgzf as bgzf;
8
9use super::Writer;
10use crate::io::CompressionMethod;
11
12/// A BAM writer builder.
13#[derive(Debug, Default)]
14pub struct Builder {
15    compression_method: Option<CompressionMethod>,
16}
17
18impl Builder {
19    /// Sets the compression method.
20    ///
21    /// # Examples
22    ///
23    /// ```
24    /// use noodles_vcf::io::{writer::Builder, CompressionMethod};
25    /// let builder = Builder::default().set_compression_method(CompressionMethod::Bgzf);
26    /// ```
27    pub fn set_compression_method(mut self, compression_method: CompressionMethod) -> Self {
28        self.compression_method = Some(compression_method);
29        self
30    }
31
32    /// Builds a VCF writer from a path.
33    ///
34    /// If the compression method is not set, it is detected from the path extension.
35    ///
36    /// # Examples
37    ///
38    /// ```no_run
39    /// use noodles_vcf::io::writer::Builder;
40    /// let writer = Builder::default().build_from_path("out.vcf")?;
41    /// # Ok::<_, std::io::Error>(())
42    /// ```
43    pub fn build_from_path<P>(mut self, dst: P) -> io::Result<Writer<Box<dyn Write>>>
44    where
45        P: AsRef<Path>,
46    {
47        let dst = dst.as_ref();
48
49        if self.compression_method.is_none() {
50            self.compression_method = match dst.extension().and_then(|ext| ext.to_str()) {
51                Some("gz" | "bgz") => Some(CompressionMethod::Bgzf),
52                _ => Some(CompressionMethod::None),
53            };
54        }
55
56        let file = File::create(dst)?;
57        Ok(self.build_from_writer(file))
58    }
59
60    /// Builds a VCF writer from a writer.
61    ///
62    /// If the compression method is not set, no compression is used.
63    ///
64    /// # Examples
65    ///
66    /// ```
67    /// # use std::io;
68    /// use noodles_vcf::io::writer::Builder;
69    /// let writer = Builder::default().build_from_writer(io::sink());
70    /// ```
71    pub fn build_from_writer<'w, W>(self, writer: W) -> Writer<Box<dyn Write + 'w>>
72    where
73        W: Write + 'w,
74    {
75        let inner: Box<dyn Write> = match self.compression_method {
76            Some(CompressionMethod::Bgzf) => Box::new(bgzf::Writer::new(writer)),
77            Some(CompressionMethod::None) | None => Box::new(BufWriter::new(writer)),
78        };
79
80        Writer::new(inner)
81    }
82}