Skip to main content

blast_example/
blast_parse.rs

1use anyhow::{Context, Result};
2use async_compression::tokio::bufread::GzipDecoder as AsyncGzDecoder;
3use clap::Parser;
4use quick_xml::events::Event;
5use quick_xml::reader::Reader;
6use quick_xml::escape::unescape;
7use serde::Serialize;
8use serde_json::ser::Serializer as JsonSerializer;
9use microBioRust::blast::*;
10use std::io::Cursor;
11use tokio::io::{self, AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncWriteExt, BufReader};
12
13#[derive(Parser, Debug)]
14#[command(name = "blast-parsers", author, version, about = "async microBioRust BLAST parsers: for outfmt6 (single line tabular) and outfmt5 (xml)")]
15struct Cli {
16    ///Use .gz for gzip-compressed files.
17    #[arg(short, long, default_value = "-")]
18    input: String,
19    /// Format: '6' (tabular) or '5' (xml). If omitted we try to infer by file suffix only
20    #[arg(short, long)]
21    format: Option<String>,
22    /// Output newline-delimited JSON (one JSON object per record/iteration)
23    #[arg(long)]
24    json: bool,
25}
26
27#[tokio::main]
28async fn main() -> Result<()> {
29    let args = Cli::parse();
30    let fmt = infer_format(&args.input, &args.format);
31    let reader_box = open_async_reader(&args.input).await?;
32    if fmt == "6" {
33        stream_outfmt6_to_json(reader_box).await?;
34    } else {
35        // Build AsyncBlastXmlIter from reader_box
36        let iter_reader = reader_box;
37        let mut iter = AsyncBlastXmlIter::from_reader(iter_reader);
38        while let Some(res) = iter.next_iteration().await {
39            match res {
40                Ok(iter_rec) => {
41                    if args.json {
42                        let mut buf = Vec::new();
43                        serde_json::to_writer(&mut buf, &iter_rec)?;
44                        buf.push(b'\n');
45                        tokio::io::stdout().write_all(&buf).await?;
46                    } else {
47                        println!("query {:?} hits {}", iter_rec.query_def, iter_rec.hits.len());
48                    }
49                }
50                Err(e) => eprintln!("xml parse error: {}", e),
51            }
52        }
53    }
54
55    Ok(())
56}