Skip to main content

chaintools/
lib.rs

1// Copyright (c) 2026 Alejandro Gonzales-Irribarren <alejandrxgzi@gmail.com>
2// Distributed under the terms of the Apache License, Version 2.0.
3
4//! # chaintools
5//!
6//! A high-performance library for parsing chain files, which describe pairwise alignments
7//! between sequences commonly used in genomics. The library provides zero-copy parsing
8//! to minimize memory allocations and maximize performance when working with large
9//! alignment datasets.
10//!
11//! ## Features
12//!
13//! - **Zero-copy parsing**: All string data is referenced without allocation for maximum performance
14//! - **Memory mapping**: Optional `mmap` support for efficient handling of large files  
15//! - **Parallel processing**: Multi-threaded parsing with the `rayon` feature
16//! - **Streaming**: Low-memory streaming parser suitable for stdin and pipes
17//! - **Indexing**: Random access to individual chains with the `index` feature
18//! - **Compression**: Built-in gzip support with the `gzip` feature
19//! - **Writing**: Chain and metadata writers available without sequence support
20//! - **Feature-gated dependencies**: Minimal footprint by enabling only needed features
21//!
22//! ## Quick Start
23//!
24//! ```no_run
25//! use chaintools::Reader;
26//!
27//! // Load a chain file (automatically uses mmap when available)
28//! let reader = Reader::<chaintools::Chain>::from_path("example.chain")?;
29//!
30//! // Iterate over all chains
31//! for chain in reader.chains() {
32//!     println!("Chain {}: score={}", chain.id, chain.score);
33//! }
34//! # Ok::<(), Box<dyn std::error::Error>>(())
35//! ```
36//!
37//! ## Examples
38//!
39//! ### Streaming large files
40//!
41//! ```no_run
42//! use chaintools::io::stream::StreamingReader;
43//!
44//! // Stream from a file (low memory usage)
45//! let mut reader = StreamingReader::from_path("large.chain")?;
46//!
47//! while let Some(chain) = reader.next_chain()? {
48//!     println!("Processing chain with score: {}", chain.score);
49//!     // Process chain without loading entire file into memory
50//! }
51//! # Ok::<(), Box<dyn std::error::Error>>(())
52//! ```
53//!
54//! ### Parallel processing (`parallel` feature)
55//!
56//! ```no_run
57//! # #[cfg(feature = "parallel")] {
58//! use chaintools::Reader;
59//!
60//! // Parse large files faster using multiple threads
61//! let reader = Reader::<chaintools::Chain>::from_path_parallel("huge.chain")?;
62//!
63//! println!("Parsed {} chains in parallel", reader.len());
64//! # }
65//! # Ok::<(), Box<dyn std::error::Error>>(())
66//! ```
67//!
68//! ### Random access with indexing (`index` feature)
69//!
70//! ```no_run
71//! # #[cfg(feature = "index")] {
72//! use chaintools::ChainIndex;
73//!
74//! // Build an index for fast random access
75//! let index = ChainIndex::from_path("example.chain")?;
76//!
77//! // Access specific chains without parsing the entire file
78//! if let Some(chain_bytes) = index.chain_bytes(0) {
79//!     println!("First chain is {} bytes", chain_bytes.len());
80//! }
81//!
82//! println!("Index contains {} chains", index.len());
83//! # }
84//! # Ok::<(), Box<dyn std::error::Error>>(())
85//! ```
86//!
87//! ## Feature flags
88//!
89//! - `mmap`: Memory mapping support for efficient handling of large files
90//! - `gzip`: Built-in gzip compression support
91//! - `index`: Random access indexing for chains
92//! - `parallel`: Multi-threaded parsing with rayon
93//! - `write`: Marker feature for writer-only dependents; writers are exported unconditionally
94//! - `sequence`: Sequence loading and scoring support
95//! - `default`: Enables `mmap`
96//!
97//! ## Installation
98//!
99//! Add this to your `Cargo.toml`:
100//!
101//! ```toml
102//! [dependencies]
103//! chaintools = { version = "0.0.2", features = ["mmap", "gzip"] }
104//! ```
105
106pub mod io;
107pub mod model;
108pub mod parser;
109#[cfg(feature = "sequence")]
110pub mod seq;
111
112pub use model::block::{AbsoluteBlock, Block, BlockSlice, absolute_to_dense_blocks};
113pub use model::chain::{Chain, Strand};
114pub use model::error::ChainError;
115
116#[cfg(feature = "index")]
117pub use io::index::{ChainIndex, ChainSpan};
118pub use io::reader::{MetadataIter, Reader};
119pub use io::storage::ByteSlice;
120pub use io::stream::{OwnedChain, OwnedChainHeader, OwnedChainParts, StreamItem, StreamingReader};
121pub use io::writer::{
122    write_chain_dense, write_chain_dense_with_id, write_chain_header, write_chain_header_with_id,
123    write_dense_blocks, write_metadata_line, write_metadata_lines,
124};
125
126#[cfg(feature = "sequence")]
127pub use seq::score::chainscore::{
128    ChainScorer, ScoreConfig, score_absolute_block, score_absolute_blocks, score_ungapped_slices,
129};
130#[cfg(feature = "sequence")]
131pub use seq::score::gapcalc::GapCalc;
132#[cfg(feature = "sequence")]
133pub use seq::score::scoring::{CompactMatrix, ScoreMatrix};