Skip to content

Commit

Permalink
Merge pull request #27 from COMBINE-lab/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
rob-p authored Mar 8, 2024
2 parents 58aba92 + 1e99e76 commit bc27a31
Show file tree
Hide file tree
Showing 14 changed files with 311 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "libradicl"
version = "0.8.1"
version = "0.8.2"
authors = [
"Avi Srivastava <[email protected]>",
"Hirak Sarkar <[email protected]>",
Expand Down
6 changes: 6 additions & 0 deletions scripts/bsd-3.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Copyright (c) ${years} ${owner}.

This file is part of ${projectname}
(see ${projecturl}).

License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
10 changes: 10 additions & 0 deletions scripts/reheader.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

if ! command -v licenseheaders &> /dev/null
then
echo "licenseheaders could not be found; please install this program to use the script (pip install licenseheaders)."
exit 1
fi


licenseheaders -d ../src -y 2020-2024 -t bsd-3.tmpl -o COMBINE-lab -n libradicl -u https://www.github.com/COMBINE-lab/libradicl -D -E rs
12 changes: 10 additions & 2 deletions src/chunk.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/*
* Copyright (c) 2020-2024 COMBINE-lab.
*
* This file is part of libradicl
* (see https://www.github.com/COMBINE-lab/libradicl).
*
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
*/
use crate::{self as libradicl};
use libradicl::record::MappedRecord;
use scroll::Pread;
Expand Down Expand Up @@ -48,12 +56,12 @@ impl<R: MappedRecord> Chunk<R> {
// think about how best to implement this, and where to store the tags
// (a) should the tags be part of the record, or stored externally (e.g. in a parallel
// Vec)?
// (b) should the tags be read into an "unparsed" structure (e.g. a binary blob) and
// (b) should the tags be read into an "unparsed" structure (e.g. a binary blob) and
// then parsed on demand, or parsed as they are read here?
// (c) What's the best mechanism to allow the user to access the tags?
todo!("Should read and store the optional tags associated with each record.");
}

/// Read the next [Chunk] from the provided reader and return it.
#[inline]
pub fn from_bytes<T: Read>(reader: &mut T, ctx: &R::ParsingContext) -> Self {
Expand Down
8 changes: 8 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
/*
* Copyright (c) 2020-2024 COMBINE-lab.
*
* This file is part of libradicl
* (see https://www.github.com/COMBINE-lab/libradicl).
*
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
*/
pub(crate) const MAX_REF_NAME_LEN: usize = 65536;
6 changes: 3 additions & 3 deletions src/exit_codes.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
* Copyright (c) 2020-2021 Rob Patro, Avi Srivastava, Hirak Sarkar, Dongze He, Mohsen Zakeri.
* Copyright (c) 2020-2024 COMBINE-lab.
*
* This file is part of alevin-fry
* (see https://github.com/COMBINE-lab/alevin-fry).
* This file is part of libradicl
* (see https://www.github.com/COMBINE-lab/libradicl).
*
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
*/
Expand Down
59 changes: 58 additions & 1 deletion src/header.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
/*
* Copyright (c) 2020-2024 COMBINE-lab.
*
* This file is part of libradicl
* (see https://www.github.com/COMBINE-lab/libradicl).
*
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
*/
use crate::{self as libradicl, constants};
use libradicl::rad_types::{TagSection, TagSectionLabel};
use libradicl::record::RecordContext;
use noodles_sam as sam;
use scroll::Pread;
use std::io::Read;
use std::io::{Read, Write};

/// The [RadPrelude] groups together the [RadHeader]
/// as well as the relevant top-level [TagSection]s of the file.
Expand Down Expand Up @@ -113,6 +121,10 @@ impl RadHeader {
tot_size
}

/// Write a summary of the current [RadHeader] to a [String]. This
/// produces an [Ok(String)] if successful. The `num_refs` argument
/// can be provided to control the number of reference names printed.
/// The default (if `None` is provided to this option) is 10.
pub fn summary(&self, num_refs: Option<usize>) -> anyhow::Result<String> {
use std::fmt::Write as _;
let mut s = String::new();
Expand All @@ -134,9 +146,54 @@ impl RadHeader {
writeln!(&mut s, "}}")?;
Ok(s)
}

/// Write this [RadHeader] to the provided writer `w`, propagating
/// any error that occurs or returing `Ok(())` on success.
pub fn write<W: Write>(&self, w: &mut W) -> anyhow::Result<()> {
// NOTE: If this RadHeader was created from a SAM
// header, this information is not meanginful because
// it's not contained in the SAM header. Think about if
// and how to address that.
w.write_all(&self.is_paired.to_le_bytes())?;

let ref_count = self.ref_count;
w.write_all(&ref_count.to_le_bytes())?;

// create longest buffer
for k in self.ref_names.iter() {
let name_size = k.len() as u16;
w.write_all(&name_size.to_le_bytes())?;
w.write_all(k.as_bytes())?;
}

let initial_num_chunks = self.num_chunks;
w.write_all(&initial_num_chunks.to_le_bytes())?;
Ok(())
}
}

impl RadPrelude {
/// Build a [RadPrelude] from the provided [RadHeader] and the
/// [TagSection]s for the file, read, and alignment tags. The header
/// and tag sections are moved, and so are no long valid after the
/// construction of the prelude. However, those fields are public
/// so they can be accessed after the prelude is returned. Unlike
/// the `from_bytes` constructor, this construction is assumed not
/// to be failable.
pub fn from_header_and_tag_sections(
hdr: RadHeader,
file_tags: TagSection,
read_tags: TagSection,
aln_tags: TagSection,
) -> Self {
Self {
hdr,
file_tags,
read_tags,
aln_tags,
}
}

/// Read a [RadPrelude] from the provided `reader`, which includes the
/// [RadHeader] as well as the relevant [TagSection]s. This function returns
/// an `std::Ok(`[RadPrelude]`)` if the prelude is parsed succesfully and an
Expand Down
8 changes: 8 additions & 0 deletions src/io.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/*
* Copyright (c) 2020-2024 COMBINE-lab.
*
* This file is part of libradicl
* (see https://www.github.com/COMBINE-lab/libradicl).
*
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
*/
use crate::libradicl::rad_types::RadIntId;
use scroll::Pread;
use std::io::Write;
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
* Copyright (c) 2020-2021 Rob Patro, Avi Srivastava, Hirak Sarkar, Dongze He, Mohsen Zakeri.
* Copyright (c) 2020-2024 COMBINE-lab.
*
* This file is part of alevin-fry
* (see https://github.com/COMBINE-lab/alevin-fry).
* This file is part of libradicl
* (see https://www.github.com/COMBINE-lab/libradicl).
*
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
*/
Expand Down
47 changes: 45 additions & 2 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// macro generalizing solution from
// https://stackoverflow.com/questions/77388769/convert-vecu8-to-vecfloat-in-rust
/*
* Copyright (c) 2020-2024 COMBINE-lab.
*
* This file is part of libradicl
* (see https://www.github.com/COMBINE-lab/libradicl).
*
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
*/
#[macro_export]
macro_rules! u8_to_vec_of {
($a:expr, $b:ty) => {
Expand All @@ -17,3 +23,40 @@ macro_rules! u8_to_vec_of_bool {
$a.iter().map(|x| *x > 0).collect::<Vec<bool>>()
};
}

#[macro_export]
macro_rules! tag_value_try_into_int {
($b:ty) => {
/// allow converting a [libradicl::rad_types::TagValue] into
/// an appropriate integer type. This fails
/// if the value contained is too big to fit
/// in the corresponidng type.
impl std::convert::TryInto<$b> for &libradicl::rad_types::TagValue {
type Error = anyhow::Error;

fn try_into(self) -> std::result::Result<$b, Self::Error> {
match *self {
TagValue::U8(x) => Ok(x as $b),
TagValue::U16(x) => Ok(x as $b),
TagValue::U32(x) => {
if x as u64 > <$b>::MAX as u64 {
bail!("Cannot convert value {x} to u16; too large")
} else {
Ok(x as $b)
}
}
TagValue::U64(x) => {
if x as u64 > <$b>::MAX as u64 {
bail!("Cannot convert value {x} to {}; too large", stringify!($b))
} else {
Ok(x as $b)
}
}
_ => {
bail!("cannot convert non-int TagValue to {}", stringify!($b))
}
}
}
}
};
}
Loading

0 comments on commit bc27a31

Please sign in to comment.