Skip to content

Commit

Permalink
vcf/async/io/reader: Add an async header reader adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
zaeleus committed Dec 19, 2024
1 parent a0bbb54 commit a8f8e72
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
40 changes: 39 additions & 1 deletion noodles-vcf/src/async/io/reader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod header;
pub mod header;
mod query;
mod record;

Expand Down Expand Up @@ -116,6 +116,44 @@ where
}
}

/// Returns an async VCF header reader.
///
/// This creates an adapter that reads at most the length of the header, i.e., all lines
/// prefixed with a `#` (number sign).
///
/// It is more ergonomic to read and parse the header using [`Self::read_header`], but using
/// this adapter allows for control of how the header is read, e.g., to read the raw VCF
/// header.
///
/// The position of the stream is expected to be at the start.
///
/// # Examples
///
/// ```
/// # #[tokio::main]
/// # async fn main() -> tokio::io::Result<()> {
/// use noodles_vcf as vcf;
/// use tokio::io::AsyncReadExt;
///
/// let data = b"##fileformat=VCFv4.3
/// #CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO
/// sq0\t1\t.\tA\t.\t.\tPASS\t.
/// ";
///
/// let mut reader = vcf::r#async::io::Reader::new(&data[..]);
/// let mut header_reader = reader.header_reader();
///
/// let mut raw_header = String::new();
/// header_reader.read_to_string(&mut raw_header).await?;
///
/// assert_eq!(raw_header, "##fileformat=VCFv4.3\n#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\n");
/// # Ok(())
/// # }
/// ```
pub fn header_reader(&mut self) -> header::Reader<&mut R> {
header::Reader::new(&mut self.inner)
}

/// Reads the VCF header.
///
/// This reads all header lines prefixed with a `#` (number sign), which includes the header
Expand Down
9 changes: 7 additions & 2 deletions noodles-vcf/src/async/io/reader/header.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Async VCF header reader.
use std::{
pin::Pin,
task::{ready, Context, Poll},
Expand All @@ -9,14 +11,17 @@ use tokio::io::{self, AsyncBufRead, AsyncBufReadExt, AsyncRead, ReadBuf};
use crate::{header, Header};

pin_project! {
struct Reader<R> {
/// An async VCF header reader.
///
/// This is created by calling [`super::Reader::header_reader`].
pub struct Reader<R> {
inner: R,
is_eol: bool,
}
}

impl<R> Reader<R> {
fn new(inner: R) -> Self {
pub(super) fn new(inner: R) -> Self {
Self {
inner,
is_eol: true,
Expand Down

0 comments on commit a8f8e72

Please sign in to comment.