gfatk/
trim.rs

1use std::path::PathBuf;
2
3use crate::gfa::gfa::GFAtk;
4use crate::gfa::gfa_string;
5use crate::gfa::graph::segments_subgraph;
6use crate::load::{load_gfa, load_gfa_stdin};
7use crate::utils;
8use anyhow::{bail, Result};
9
10/// Trim a GFA file of segments which are connected only to one other segment.
11///
12/// For example:
13/// ```bash
14/// gfatk trim in.gfa > out.gfa
15/// ```
16pub fn trim(matches: &clap::ArgMatches) -> Result<()> {
17    // read in path and parse gfa
18    let gfa_file = matches.get_one::<PathBuf>("GFA");
19
20    let gfa: GFAtk = match gfa_file {
21        Some(f) => {
22            let ext = f.extension();
23            match ext {
24                Some(e) => {
25                    if e == "gfa" {
26                        GFAtk(load_gfa(f)?)
27                    } else {
28                        bail!("Input is not a GFA.")
29                    }
30                }
31                None => bail!("Could not read file."),
32            }
33        }
34        None => match utils::is_stdin() {
35            true => GFAtk(load_gfa_stdin(std::io::stdin().lock())?),
36            false => bail!("No input from STDIN. Run `gfatk extract -h` for help."),
37        },
38    };
39
40    let (graph_indices, gfa_graph) = gfa.into_digraph()?;
41
42    let trimmed = gfa_graph.trim(graph_indices);
43
44    let subgraph = segments_subgraph(&gfa.0, trimmed);
45
46    println!("{}", gfa_string(&subgraph));
47
48    Ok(())
49}