This is what I have until now:

//!
//! 'chaintools' is a library for serializing and working with genomic chain files in Rust.
//!
//! This crate provides two main entries:
//!
//! 1. `Reader` and `Writer` for reading and writing encoded chain files.
//! 2.  'ChainMap' and inner structs for performing basic operations (filter, sort, etc) on chain files.
//!
//! ## Reading
//!
//! The entrypoint for reading genomic chain files in the 'chaintools' Rust library is through
//! the Reader struct, offering methods like [`Reader::from_file`] to create a reader from a file path
//! and return a [`Result`] with a [`ChainMap`], [`Reader::from_bytes`] to create a reader from a byte slice,
//! [`Reader::from_bin`] to create a reader from a binary file path, and [`Reader::load_chain`] to load a
//! specific chain from a binary file using a chain ID. Internally, the Reader struct handles file
//! operations, parsing byte data efficiently, and utilizes Rust's standard library for file I/O
//! and parallel processing for parsing and filtering chain data, providing a comprehensive interface
//! for working with genomic chain files in various formats within Rust.
//!
//! # Examples
//! ```rust
//! use chaintools::cmap::ChainMap;
//! use chaintools::Reader;
//!
//! let reader: ChainMap = Reader::from_file("path/to/chainfile.chain")?;
//! ```
//!
//! ## Operations
//!
//! The ChainMap struct provides a variety of methods for performing operations on chain files, 

Please help me completing the Operations part. Here is the code to facilitate your knowledge about the code's logic:

/// A map of chains
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChainMap {
    pub map: FxHashMap<u32, Chain>,
}

impl ChainMap {
    /// Create a new ChainMap
    ///
    /// # Returns
    /// * ChainMap
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    ///
    /// let chains = ChainMap::new();
    /// ```
    pub fn new() -> Self {
        Self {
            map: FxHashMap::default(),
        }
    }

    /// Get a chain from the map
    ///
    /// # Arguments
    /// * `key` - A chain id
    ///
    /// # Returns
    /// * Option<&Chain>
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// let chain = chains.get(&123);
    /// println!("{:?}", chain);
    ///
    /// >>> Some(Chain { score: 0, refs: ChainHead { size: 0, start: 0, end: 0, strand: 0 },
    /// query: ChainHead { size: 0, start: 0, end: 0, strand: 0 }, alinment: [], id: 123 })
    /// ```
    pub fn get(&self, key: &u32) -> Option<&Chain> {
        self.map.get(key)
    }

    /// Get a mutable chain from the map
    ///
    /// # Arguments
    /// * `key` - A chain id
    ///
    /// # Returns
    /// * Option<&mut Chain>
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// let chain = chains.get_mut(&123);
    /// println!("{:?}", chain);
    ///
    /// >>> Some(Chain { score: 0, refs: ChainHead { size: 0, start: 0, end: 0, strand: 0 },
    /// query: ChainHead { size: 0, start: 0, end: 0, strand: 0 }, alinment: [], id: 123 })
    /// ```
    pub fn get_mut(&mut self, key: &u32) -> Option<&mut Chain> {
        self.map.get_mut(key)
    }

    /// Generalized filtering function
    ///
    /// # Arguments
    /// * `fc` - A closure that takes a reference to a Chain and returns a boolean
    ///
    /// # Returns
    /// * ChainMap
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::cmap::chain::Chain;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// let filt_chains = chains.filter(|chain| chain.score > 100);
    /// ```
    pub fn filter<F>(&self, fc: F) -> Self
    where
        F: Fn(&Chain) -> bool,
    {
        let fmap: FxHashMap<u32, Chain> = self
            .map
            .iter()
            .filter(|(_, chain)| fc(chain))
            .map(|(id, chain)| (*id, chain.clone()))
            .collect();

        Self { map: fmap }
    }

    /// Insert a chain into a ChainMap
    ///
    /// # Arguments
    /// * `key` - A chain id
    /// * `value` - A Chain
    ///
    /// # Returns
    /// * &mut ChainMap
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// chains.insert(123, Chain{ score: 0, refs: ChainHead { size: 0, start: 0, end: 0, strand: 0 }, ..., id: 123});
    /// ```
    pub fn insert(&mut self, key: u32, value: Chain) -> &mut ChainMap {
        self.map.insert(key, value);
        self
    }

    /// Remove a chain from a ChainMap
    ///
    /// # Arguments
    /// * `key` - A chain id
    ///
    /// # Returns
    /// * &mut ChainMap
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// chains.remove(&123);
    /// ```
    pub fn remove(&mut self, key: &u32) -> &mut ChainMap {
        self.map.remove(key);
        self
    }

    /// Sort the ChainMap by chain ids
    ///
    /// # Returns
    /// * usize
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// println!("Number of chains: {:?}", chains.len());
    ///
    /// >>> 100
    /// ```
    pub fn len(&self) -> usize {
        self.map.len()
    }

    /// Iterate over the ChainMap
    ///
    /// # Returns
    /// * Iterator<Item = (&u32, &Chain)>
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// for (key, chain) in chains.iter() {
    ///   println!("{:?} {:?}", key, chain);
    ///   break;
    /// }
    /// ```
    pub fn iter(&self) -> impl Iterator<Item = (&u32, &Chain)> {
        self.map.iter()
    }

    /// Iterate over mut ChainMap
    ///
    /// # Returns
    /// * Iterator<Item = (&u32, &mut Chain)>
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// for (key, chain) in chains.iter_mut() {
    ///  println!("{:?} {:?}", key, chain);
    ///  break;
    /// }
    /// ```
    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&u32, &mut Chain)> {
        self.map.iter_mut()
    }

    /// Iterate over the keys of the ChainMap
    ///
    /// # Returns
    /// * Iterator<Item = &u32>
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// for key in chains.keys() {
    ///    println!("{:?}", key);
    /// }
    /// ```
    pub fn keys(&self) -> impl Iterator<Item = &u32> {
        self.map.keys()
    }

    /// Iterate over the values of the ChainMap
    ///
    /// # Returns
    /// * Iterator<Item = &Chain>
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// for chain in chains.values() {
    ///   println!("{:?}", chain);
    /// }
    /// ```
    pub fn values(&self) -> impl Iterator<Item = &Chain> {
        self.map.values()
    }

    /// Iterate over mut values of the ChainMap
    ///
    /// # Returns
    /// * Iterator<Item = &mut Chain>
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// for chain in chains.values_mut() {
    ///     println!("{:?}", chain);
    ///     chain.score = 100;
    ///     println!("{:?}", chain);
    ///     break;
    ///  }
    /// ```
    pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Chain> {
        self.map.values_mut()
    }

    /// Filter the ChainMap by score
    ///
    /// # Arguments
    /// * `score` - An i64
    ///
    /// # Returns
    /// * ChainMap
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// let score = 1000;
    /// let filt_chains = chains.filter_by_score(score);
    /// ```
    pub fn filter_by_score(&self, score: i64) -> Self {
        let map = self
            .map
            .par_iter()
            .filter(|(_, v)| v.score >= score)
            .map(|(k, v)| (*k, v.clone()))
            .collect();
        Self { map }
    }

    /// Filter the ChainMap by reference size
    ///
    /// # Arguments
    /// * `size` - A u64
    ///
    /// # Returns
    /// * ChainMap
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// let size = 1000;
    /// let filt_chains = chains.filter_query_by_size(size);
    /// ```
    pub fn filter_ref_by_size(&self, size: u64) -> Self {
        let map = self
            .map
            .par_iter()
            .filter(|(_, v)| v.refs.size >= size)
            .map(|(k, v)| (*k, v.clone()))
            .collect();
        Self { map }
    }

    /// Filter the ChainMap by query size
    ///
    /// # Arguments
    /// * `size` - A u64
    ///
    /// # Returns
    /// * ChainMap
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// let size = 1000;
    /// let filt_chains = chains.filter_query_by_size(size);
    /// ```
    pub fn filter_query_by_size(&self, size: u64) -> Self {
        let map = self
            .map
            .par_iter()
            .filter(|(_, v)| v.query.size >= size)
            .map(|(k, v)| (*k, v.clone()))
            .collect();
        Self { map }
    }

    /// Filter the ChainMap by chain ids
    ///
    /// # Arguments
    /// * `ids` - A vector of chain ids
    ///
    /// # Returns
    /// * ChainMap
    ///
    /// # Example
    /// ```
    /// use chaintools::cmap::ChainMap;
    /// use chaintools::io::reader::Reader;
    ///
    /// let chains = Reader::from_file("file.chain").unwrap();
    /// let ids = vec![123, 456];
    /// let filt_chains = chains.filter(ids).len();
    /// println!("{:?}", filt_chains);
    ///
    /// >>> 2
    pub fn filter_id(&self, ids: Vec<u32>) -> Self {
        let map = self
            .map
            .par_iter()
            .filter(|(k, _)| ids.contains(k))
            .map(|(k, v)| (*k, v.clone()))
            .collect();
        Self { map }
    }
}

/// A discrete representation of a genomic chain.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Chain {
    pub score: i64,
    pub refs: ChainHead,
    pub query: ChainHead,
    pub alignment: Vec<AlignmentRecord>,
    pub id: u32,
}

impl Chain {
    /// Create a new chain object from a chain block (header, alignment).
    ///
    /// # Arguments
    /// * `head` - A byte array containing the header of the chain block
    /// * `block` - A byte array containing the alignment of the chain block
    ///
    /// # Returns
    /// * Option<(u32, Self)>
    /// * None if the block is empty
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let head = b"chain 4900 chrY 58368225 + 25985403 25985638 chr5 151006098 - 43257292 43257528 1\n";
    /// let block = b"9\t1\t0\n";
    /// let data = chain::Chain::from(head, block);
    /// println!("{:?}", data);
    ///
    /// > Some((1, Chain { score: 4900, refs: ChainHead { chr: "chrY", size: 58368225, strand: '+', start: 25985403, end: 25985638 },
    /// query: ChainHead { chr: "chr5", size: 151006098, strand: '-', start: 43257292, end: 43257528 },
    /// alignment: [AlignmentRecord { size: 9, dt: 1, dq: 0 }], id: 1 }));
    /// ```
    pub fn from(head: &[u8], block: &[u8]) -> Result<(u32, Self)> {
        let (score, refs, query, id) = Self::head(head)?;
        let alignment = AlignmentRecord::parse(block);

        Ok((
            id,
            Self {
                score,
                refs,
                query,
                alignment,
                id,
            },
        ))
    }

    /// Get the chain object as a string.
    ///
    /// # Arguments
    /// * `self` - A chain object
    ///
    /// # Returns
    /// * String
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::Reader::from_file("/path/to/chainfile")?;
    /// let line = data.get(&12).unwrap().to_string();
    /// println!("{:?}", line);
    ///
    /// > "chain 4900 chrY 58368225 + 25985403 25985638 chr5 151006098 - 43257292 43257528 12\n9\t1\t0\n\n";
    /// ```
    pub fn to_string(&self) -> String {
        format!("{}\n{}", self.header(), self.alignment())
    }

    /// Get the header of a chain object as a string.
    ///
    /// # Arguments
    /// * `self` - A chain object
    ///
    /// # Returns
    /// * String
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::Reader::from_file("/path/to/chainfile")?;
    /// let line = data.get(&12).unwrap().header();
    /// println!("{:?}", line);
    ///
    /// > "chain 4900 chrY 58368225 + 25985403 25985638 chr5 151006098 - 43257292 43257528 12";
    /// ```
    pub fn header(&self) -> String {
        format!(
            "chain {} {} {} {}",
            self.score,
            self.refs.to_string(),
            self.query.to_string(),
            self.id
        )
    }

    /// Get the header of a chain object as a vector of strings.
    /// The vector contains the score, refs, query, and id values.
    ///
    /// # Arguments
    /// * `self` - A chain object
    ///
    /// # Returns
    /// * Vec<String>
    ///
    /// # Example
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::Reader::from_file("/path/to/chainfile")?;
    /// let line = data.get(&12).unwrap().header_vec();
    /// println!("{:?}", line);
    ///
    /// > ["4900", "chrY", "58368225", "+", "25985403", "25985638", "chr5", "151006098", "-", "43257292", "43257528", "12"];
    /// ```
    pub fn header_vec(&self) -> Vec<String> {
        let mut hv = vec![String::from("chain"), self.score.to_string()];
        hv.extend(self.refs.to_vec());
        hv.extend(self.query.to_vec());
        hv.push(self.id.to_string());
        hv
    }

    /// Get the alignment of a chain object as a string.
    ///
    /// # Arguments
    /// * `self` - A chain object
    ///
    /// # Returns
    /// * String
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::Reader::from_file("/path/to/chainfile")?;
    /// let line = data.get(&12).unwrap().alignment();
    /// println!("{:?}", line);
    ///
    /// > "9\t1\t0\n\n";
    /// ```
    pub fn alignment(&self) -> String {
        let len = self.alignment.len();
        self.alignment
            .iter()
            .enumerate()
            .map(|(i, a)| {
                if i == len - 1 {
                    format!("{}\n\n", a.size.to_string())
                } else {
                    format!("{}\n", a.to_string())
                }
            })
            .collect::<String>()
    }

    /// Get the alignment of a chain object as a vector of vectors.
    /// The inner vector contains the size, dt, and dq values.
    ///
    /// # Arguments
    /// * `self` - A chain object
    ///
    /// # Returns
    /// * Vec<Vec<u32>>
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::Reader::from_file("/path/to/chainfile")?;
    /// let line = data.get(&12).unwrap().alignment_vec();
    /// println!("{:?}", line);
    ///
    /// > [[9, 1, 0]];
    /// ```
    pub fn alignment_vec(&self) -> Vec<Vec<u32>> {
        self.alignment
            .iter()
            .map(|a| vec![a.size, a.dt, a.dq])
            .collect()
    }

    /// Get the alignment of a chain object as a vector of vectors.
    /// The inner vector contains the size, dt, and dq values.
    ///
    /// # Arguments
    /// * `self` - A chain object
    ///
    /// # Returns
    /// * Vec<Vec<String>>
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::Reader::from_file("/path/to/chainfile")?;
    /// let line = data.get(&12).unwrap().alignment_vec_str();
    /// println!("{:?}", line);
    ///
    /// > [["9", "1", "0"]];
    /// ```
    pub fn alignment_vec_str(&self) -> Vec<Vec<String>> {
        self.alignment
            .iter()
            .map(|a| vec![a.size.to_string(), a.dt.to_string(), a.dq.to_string()])
            .collect()
    }

    /// Get the chain object as a byte array.
    ///
    /// # Arguments
    /// * `self` - A chain object
    ///
    /// # Returns
    /// * Vec<u8>
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::Reader::from_file("/path/to/chainfile")?;
    /// let line = data.get(&12).unwrap().to_bytes();
    /// println!("{:?}", line);
    ///
    /// > [99, 104, 97, 105, 110, 32, 52, 57, 48, 48, 32, 99, 104, 114, 89, 32, 53, 56, 51,
    /// 54, 56, 50, 50, 53, 32, 43, 32, 50, 53, 57, 56, 53, 52, 48, 51, 32, 50, 53, 57, 56,
    /// 53, 54, 51, 56, 32, 99, 104, 114, 53, 32, 49, 53, 49, 48, 48, 54, 48, 57, 56, 32,
    /// 45, 32, 52, 51, 49, 54, 52, 48, 51, 50, 57, 50, 32, 52, 51, 49, 54, 52, 48, 51, 53,
    /// 50, 56, 32, 49, 50, 10, 57, 9, 49, 9, 48, 10];
    /// ```
    pub fn to_bytes(&self) -> Vec<u8> {
        self.to_string().into_bytes()
    }

    /// Get the chain object as a vector of vectors.
    /// The inner vector contains the header and alignment values.
    /// The header vector contains the score, refs, query, and id values.
    /// The alignment vector contains the size, dt, and dq values.
    ///
    /// # Arguments
    /// * `self` - A chain object
    ///
    /// # Returns
    /// * Vec<Vec<String>>
    ///
    /// # Example
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::Reader::from_file("/path/to/chainfile")?;
    /// let line = data.get(&12).unwrap().to_vec();
    /// println!("{:?}", line);
    ///
    /// > [["chain", "4900", "chrY", "58368225", "+", "25985403", "25985638",
    /// "chr5", "151006098", "-", "43257292", "43257528", "12"], ["9", "1", "0"]];
    /// ```
    pub fn to_vec(&self) -> Vec<Vec<String>> {
        let mut v = self.alignment_vec_str();
        v.insert(0, self.header_vec());
        v
    }

    /// Process a chain header into a chainer compatible pre-processing format.
    ///
    /// # Arguments
    /// * `header` - A byte array containing the header of the chain block
    ///
    /// # Returns
    /// * (i64, ChainHead, ChainHead, u32)
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let head = b"chain 4900 chrY 58368225 + 25985403 25985638 chr5 151006098 - 43257292 43257528 1\n";
    /// let data = chain::Chain::head(head);
    /// println!("{:?}", data);
    ///
    /// > (4900, ChainHead { chr: "chrY", size: 58368225, strand: '+', start: 25985403, end: 25985638 },
    /// ChainHead { chr: "chr5", size: 151006098, strand: '-', start: 43257292, end: 43257528 }, 1);
    /// ```
    pub fn head(header: &[u8]) -> Result<(i64, ChainHead, ChainHead, u32)> {
        let mut acc = vec![];
        let mut header = &header[..];
        loop {
            let Some(sep) = memchr(b' ', header) else {
                acc.push(header);
                break;
            };
            acc.push(&header[..sep]);
            header = &header[sep + 1..];
        }

        let refs = ChainHead::from(&acc[2..7])?;
        let query = ChainHead::from(&acc[7..12])?;

        let score = from_utf8(&acc[1])
            .unwrap()
            .parse::<i64>()
            .with_context(|| {
                format!(
                    "Failed to parse score in: {:?}. Bad formatted line!",
                    String::from_utf8_lossy(header)
                )
            })?;

        let id = from_utf8(&acc.last().unwrap())
            .unwrap()
            .parse::<u32>()
            .with_context(|| {
                format!(
                    "Failed to parse id in: {:?}. Bad formatted line!",
                    String::from_utf8_lossy(header)
                )
            })?;

        Ok((score, refs, query, id))
    }
}

/// A ref/query chain head object.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChainHead {
    pub chr: String,
    pub size: u64,
    pub strand: char,
    pub start: u64,
    pub end: u64,
}

impl ChainHead {
    /// Create a new chain head object from a byte array representing a ref or query header.
    ///
    /// # Arguments
    /// * `header` - A byte array containing the header of the chain block
    ///
    /// # Returns
    /// * Result<ChainHead>
    /// * An error if the header is not well formatted
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let head = b"chrY 58368225 + 25985403 25985638";
    /// let data = chain::ChainHead::from(head);
    /// println!("{:?}", data);
    ///
    /// > Ok(ChainHead { chr: "chrY", size: 58368225, strand: '+', start: 25985403, end: 25985638 });
    pub fn from(header: &[&[u8]]) -> Result<Self> {
        Ok(Self {
            chr: from_utf8(header[0])
                .context("Failed to decode chr data as UTF-8")?
                .to_string(),

            size: from_utf8(header[1])?.parse::<u64>().with_context(|| {
                format!(
                    "Failed to parse size in: {:?}. Bad formatted line!",
                    String::from_utf8_lossy(header[1])
                )
            })?,

            strand: from_utf8(header[2])?.chars().next().with_context(|| {
                format!(
                    "Failed to parse strand in: {:?}. Bad formatted line!",
                    String::from_utf8_lossy(header[2])
                )
            })?,

            start: from_utf8(header[3])?.parse::<u64>().with_context(|| {
                format!(
                    "Failed to parse start in: {:?}. Bad formatted line!",
                    String::from_utf8_lossy(header[3])
                )
            })?,

            end: from_utf8(header[4])?.parse::<u64>().with_context(|| {
                format!(
                    "Failed to parse end in: {:?}. Bad formatted line!",
                    String::from_utf8_lossy(header[4])
                )
            })?,
        })
    }

    /// Get the chain head object as a string.
    ///
    /// # Arguments
    /// * `self` - A chain head object
    ///
    /// # Returns
    /// * String
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let head = b"chrY 58368225 + 25985403 25985638";
    /// let data = chain::ChainHead::from(head).unwrap().to_string();
    /// println!("{:?}", data);
    ///
    /// > "chrY 58368225 + 25985403 25985638";
    pub fn to_string(&self) -> String {
        format!(
            "{} {} {} {} {}",
            self.chr, self.size, self.strand, self.start, self.end
        )
    }

    /// Get the chain head object as a vector of strings.
    ///
    /// # Arguments
    /// * `self` - A chain head object
    ///
    /// # Returns
    /// * Vec<String>
    ///
    /// # Example
    /// ```
    /// use chaintools as chain;
    ///
    /// let head = b"chrY 58368225 + 25985403 25985638";
    /// let data = chain::ChainHead::from(head).unwrap().to_vec();
    /// println!("{:?}", data);
    ///
    /// > ["chrY", "58368225", "+", "25985403", "25985638"];
    pub fn to_vec(&self) -> Vec<String> {
        vec![
            self.chr.to_string(),
            self.size.to_string(),
            self.strand.to_string(),
            self.start.to_string(),
            self.end.to_string(),
        ]
    }
}
/// A structure to represent an alignment record.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AlignmentRecord {
    pub size: u32,
    pub dt: u32,
    pub dq: u32,
}

impl AlignmentRecord {
    /// Parse a byte array into a vector of alignment records.
    ///
    /// # Arguments
    /// * `align` - A byte array
    ///
    /// # Returns
    /// * Vec<AlignmentRecord>
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let line = b"9\t1\t0\n";
    /// let data = chain::AlignmentRecord::parse(line);
    /// println!("{:?}", data);
    ///
    /// > [AlignmentRecord { size: 9, dt: 1, dq: 0 }];
    /// ```
    pub fn parse(align: &[u8]) -> Vec<AlignmentRecord> {
        Self::parse_byte(align).expect("ERROR: Failed to parse alignment record")
    }

    /// Parse a byte array from a single alignment line into an alignment record.    
    ///
    /// # Arguments
    /// * `align` - A byte array
    ///
    /// # Returns
    /// * Option<AlignmentRecord>
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let line = b"9\t1\t0\n";
    /// let data = chain::AlignmentRecord::from(line);
    /// println!("{:?}", data);
    ///
    /// > Some(AlignmentRecord { size: 9, dt: 1, dq: 0 });
    /// ```
    pub fn from(align: &[u8]) -> Option<Self> {
        Self::parse_byte(align)
            .expect("Failed to parse alignment record")
            .first()
            .cloned()
    }

    /// Create a new alignment record.
    ///
    /// # Arguments
    /// * `size` - The size of the ungapped alignment
    /// * `dt` -  The difference between the end of this block and the beginning of the next block (reference/target sequence)
    /// * `dq` - The difference between the end of this block and the beginning of the next block (query sequence)
    ///
    /// # Returns
    /// * AlignmentRecord
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::AlignmentRecord::new(9, 1, 0);
    /// println!("{:?}", data);
    ///
    /// > AlignmentRecord { size: 9, dt: 1, dq: 0 };
    /// ```
    pub fn new(size: u32, dt: u32, dq: u32) -> Self {
        Self { size, dt, dq }
    }

    /// Dummy getter for the size of the ungapped alignment.
    ///
    /// # Arguments
    /// * `self` - An alignment record
    ///
    /// # Returns
    /// * u32
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::AlignmentRecord::new(9, 1, 0);
    /// let line = data.size();
    /// println!("{:?}", line);
    ///
    /// > 9
    /// ```
    pub fn size(&self) -> u32 {
        self.size
    }

    /// Dummy getter for dt
    ///
    /// # Arguments
    /// * `self` - An alignment record
    ///
    /// # Returns
    /// * u32
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::AlignmentRecord::new(9, 1, 0);
    /// let line = data.dt();
    /// println!("{:?}", line);
    ///
    /// > 1
    /// ```
    pub fn dt(&self) -> u32 {
        self.dt
    }

    /// Dummy getter for dq
    ///
    /// # Arguments
    /// * `self` - An alignment record
    ///
    /// # Returns
    /// * u32
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::AlignmentRecord::new(9, 1, 0);
    /// let line = data.dq();
    /// println!("{:?}", line);
    ///
    /// > 0
    /// ```
    pub fn dq(&self) -> u32 {
        self.dq
    }

    /// Get the alignment record as a string.
    ///
    /// # Arguments
    /// * `self` - An alignment record
    ///
    /// # Returns
    /// * String
    ///
    /// # Example
    ///
    /// ```
    /// use chaintools as chain;
    ///
    /// let data = chain::AlignmentRecord::new(9, 1, 0);
    /// let line = data.to_string();
    /// println!("{:?}", line);
    ///
    /// > "9\t1\t0"
    /// ```
    pub fn to_string(&self) -> String {
        format!("{}\t{}\t{}", self.size, self.dt, self.dq)
    }

    /// Parse a byte array into a vector of alignment records.
    ///
    /// # Arguments
    /// * `align` - A byte array
    ///
    /// # Returns
    /// * Result<Vec<AlignmentRecord>, Box<dyn std::error::Error>>
    ///
    /// # Example
    /// ```
    /// use chaintools as chain;
    ///
    /// let line = b"9\t1\t0\n";
    /// let data = chain::AlignmentRecord::parse_byte(line);
    /// println!("{:?}", data);
    ///
    /// > Ok([AlignmentRecord { size: 9, dt: 1, dq: 0 }]);
    /// ```
    fn parse_byte(align: &[u8]) -> Result<Vec<AlignmentRecord>> {
        let mut acc = vec![];
        let mut align = &align[..];

        loop {
            let Some(sep) = memchr(b'\t', align) else {
                if align.len() < 2 {
                    break;
                }

                let end = memchr(b'\n', &align[..]).with_context(|| {
                    format!(
                        "Failed to find separator in: {:?}. Bad formatted line!",
                        String::from_utf8_lossy(align)
                    )
                })?;

                let size = from_utf8(&align[..end])
                    .context("Failed to parse size")
                    .and_then(|s| s.parse::<u32>().context("Failed to parse size"))?;

                acc.push(AlignmentRecord {
                    size: size,
                    dt: 0,
                    dq: 0,
                });
                break;
            };

            let end = memchr(b'\n', &align[sep..]).unwrap();
            let mid = memchr(b'\t', &align[sep + 1..]).unwrap();

            let size = from_utf8(&align[..sep])?.parse::<u32>().with_context(|| {
                format!("Failed to parse size: {:?}", String::from_utf8_lossy(align))
            })?;

            let dt = from_utf8(&align[sep + 1..sep + mid + 1])?
                .parse::<u32>()
                .with_context(|| {
                    format!(
                        "Failed to parse dt from slice: {:?}",
                        String::from_utf8_lossy(&align[sep + 1..])
                    )
                })?;
            let dq = from_utf8(&align[sep + mid + 2..sep + end])?
                .parse::<u32>()
                .with_context(|| {
                    format!(
                        "Failed to parse dq: {:?}",
                        String::from_utf8_lossy(&align[sep + mid + 2..])
                    )
                })?;

            acc.push(AlignmentRecord {
                size: size,
                dt: dt,
                dq: dq,
            });

            align = &align[sep + end + 1..];
        }

        Ok(acc)
    }
}