Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to htslib 1.10.2 #184

Merged
merged 81 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
d3db4fd
Pull 1.10.2 submodule. Initial pass on i32->i64 type conversion, will…
brainstorm Feb 3, 2020
bb34638
Fixes issue #109 while I'm at it, long hanging fruit fix
brainstorm Feb 3, 2020
1636ef5
Fix compression levels
juliangehring Feb 3, 2020
18e8e57
Merge pull request #1 from juliangehring/fix-compression
brainstorm Feb 3, 2020
9c2a6d6
Going through https://github.com/samtools/htslib/blob/develop/README.…
brainstorm Feb 4, 2020
115c634
Repoint submodule to upstream release tag
brainstorm Feb 4, 2020
6bf1760
Switch from rust-bio hosted htslib to upstream's samtools htslib.
brainstorm Feb 4, 2020
83c0656
Try to amend submodule
brainstorm Feb 4, 2020
2173a9e
Handle submodules manually on TravisCI, since it is failing now: http…
brainstorm Feb 4, 2020
d7c5355
Odd balls that would need review marked with XXX. New htslib seems to…
brainstorm Feb 4, 2020
dac8565
Add curl-sys crate for hplugin_curl, aws s3 et al
brainstorm Feb 4, 2020
5678f70
Add conditional libcurl compilation flags
brainstorm Feb 4, 2020
bad400b
Be nice with cargo fmt [ci skip]
brainstorm Feb 4, 2020
9e1a315
Try installing libcurl meta-package instead of the openssl dependent …
brainstorm Feb 4, 2020
4c9fddf
Does not work with libcurl-dev metapackage: https://travis-ci.org/rus…
brainstorm Feb 4, 2020
417b672
Add matrix compile support for TravisCI, I would like to know why it …
brainstorm Feb 4, 2020
22fae28
PPA source no longer needed for ubuntu bionic? [ci skip]
brainstorm Feb 4, 2020
1a19c69
Bionic packages htslib with gnutls instead of openssl: https://packag…
brainstorm Feb 4, 2020
6eb623a
sed is not gsed on OSX... not entirely sure this substitution is 100%…
brainstorm Feb 4, 2020
5c31eb8
Add libssl-dev to the mix for the openssl-sys: https://travis-ci.org/…
brainstorm Feb 4, 2020
d3eba71
Add build-essential in hopes to fix libcurl issue, incorporate https:…
brainstorm Feb 4, 2020
eb2ae94
Add curl on default features for hts-sys
brainstorm Feb 4, 2020
92df799
Point to the right htslib upstream repo, thanks @dlaehnemann [skip ci]
brainstorm Feb 5, 2020
4389e3f
Appease OSX musl-cross toolchain requirements: https://travis-ci.org/…
brainstorm Feb 8, 2020
4f64d69
TravisCI timesout installing brew deps: https://travis-ci.org/rust-bi…
brainstorm Feb 8, 2020
39010b1
Try workaround for https://twitter.com/braincode/status/1226103002550…
brainstorm Feb 8, 2020
9fe358b
Do not update homebrew (time intensive), switch from travis_wait to v…
brainstorm Feb 8, 2020
9d2f381
brew install --verbose is not verbose enough for travis, reverting tr…
brainstorm Feb 8, 2020
949499f
Explicitly install system libcurl on linux and osx
brainstorm Feb 8, 2020
850011e
This .cargo/config makes it test right locally: https://github.com/ru…
brainstorm Feb 8, 2020
db42104
Cargo.toml missing quote misshap
brainstorm Feb 8, 2020
89608c6
Same linker flags should apply for Linux builds? build-essential not …
brainstorm Feb 8, 2020
e534df6
tid is i64 now, CRAM vs BAM test l_data is off by 3 and m_data is off…
brainstorm Feb 9, 2020
bbe490f
There should be no need for travis_wait with -v
brainstorm Feb 10, 2020
a741700
Debugging htslib structs with @jkbonfield guidance...
brainstorm Feb 20, 2020
29747e5
Disable osx and musl-cross homebrew on the TravisCI matrix since it t…
brainstorm Feb 21, 2020
77d4765
Mystery solved for test_read_cram, testing some of the struct fields,…
brainstorm Feb 24, 2020
4f2c90c
Extract selective CRAM/BAM field comparison to test helper function
brainstorm Feb 24, 2020
6bd85e0
Formatting
brainstorm Feb 24, 2020
de35991
Temporarily commenting the hfile format category detection makes .bed…
brainstorm Feb 24, 2020
d89c216
Format detection seems to be broken upstream on htslib, see https://g…
brainstorm Feb 25, 2020
f5dd07f
Merge branch 'master' into htslib-1.10.2
brainstorm Feb 25, 2020
f6d3679
Revert to libcurl4-openssl-dev instead of gnutls. All TravisCI script…
brainstorm Feb 25, 2020
4ffb8fe
Merge github.com:brainstorm/rust-htslib into htslib-1.10.2
brainstorm Feb 25, 2020
6e92156
Bump up curl-sys version
brainstorm Feb 26, 2020
6c9454b
Experimenting musl cross-compilation with rustembedded cross. Ideally…
brainstorm Feb 26, 2020
642ceba
Remove assert_ne since cannot guarantee that l_data is different on a…
brainstorm Feb 26, 2020
7cf834f
Add minimum deps needed for rustembedded cross docker container
brainstorm Feb 26, 2020
e6d0131
Run docker in TravisCI, even if it is only supported on linux jobs :/
brainstorm Feb 26, 2020
c0dde9a
Add CFLAGS suggested by @nlhepler
brainstorm Feb 26, 2020
571b457
Separate musl from GNU toolchains on Rust cross
brainstorm Feb 27, 2020
b10c48f
Bump up bindgen, vendorize openssl, further experimentation with comp…
brainstorm Feb 27, 2020
81ab53c
Deprecate the mixed GNU/MUSL container
brainstorm Feb 27, 2020
7f87d97
Add minimal explanation on how to use the new docker files [ci skip]
brainstorm Feb 27, 2020
20f6fb1
cross 0.2.0 with openssl vendored. Progress but more htslib compile t…
brainstorm Feb 27, 2020
77d06f9
Make sure libzma is present in both containers [ci skip]
brainstorm Feb 27, 2020
47fee89
Focusing on LLVMv8 GNU cross build first, musl will come later on (if…
brainstorm Feb 28, 2020
78c41d2
Two more usize that should be u64
brainstorm Feb 28, 2020
6b79b72
Amend and settle BED header debate
brainstorm Feb 28, 2020
116c3dd
Rename test name accordingly
brainstorm Feb 28, 2020
f6f2f64
Transition to cross instead of cargo for builds and tests
brainstorm Feb 28, 2020
8127679
All GNU/clang/llvm8 builds and tests seem to succeed, transitioning t…
brainstorm Feb 28, 2020
2f14727
Remove stray (repeated) musl build
brainstorm Feb 28, 2020
0ca9400
Remove @filoSottile musl-cross homebrew formula since it takes too lo…
brainstorm Feb 28, 2020
d0837cf
Experiment with toolchain setup in https://gitlab.com/rust_musl_docke…
brainstorm Feb 28, 2020
d218b27
Remove build.rs flags noise and different tests, containers should ha…
brainstorm Feb 28, 2020
e293ad3
Indicate dependencies and build flags required for OSX [ci skip].
brainstorm Mar 1, 2020
ebd1d2e
enable musl builds
johanneskoester Mar 10, 2020
fcbbafc
add libclang
johanneskoester Mar 10, 2020
6882797
minor
johanneskoester Mar 10, 2020
e0d1edb
dbg
johanneskoester Mar 10, 2020
e97d47a
revert
johanneskoester Mar 10, 2020
cecbd4a
dbg
johanneskoester Mar 10, 2020
e065263
dbg
johanneskoester Mar 10, 2020
8505cfe
Revert cross/docker madness, bottled up musl-cross myself over here: …
brainstorm Mar 11, 2020
665a38e
Remove .travis.yml
brainstorm Mar 11, 2020
999fa0f
Merge branch 'htslib-1.10.2' of github.com:brainstorm/rust-htslib int…
brainstorm Mar 11, 2020
09aec34
Add in openssl to hts-sys
brainstorm Mar 13, 2020
6042c05
Make clippy boolean logic happy
brainstorm Mar 13, 2020
fc84cff
Remove homebrew OSX check since we'll just use rustembedded cross
brainstorm Mar 13, 2020
24f694f
Merge branch 'musl-action' of https://github.com/rust-bio/rust-htslib…
brainstorm Mar 13, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.vscode/
.idea
*~
target
Cargo.lock
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "htslib"]
path = hts-sys/htslib
url = https://github.com/rust-bio/htslib.git
url = https://github.com/samtools/htslib.git
28 changes: 25 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,42 @@
dist: bionic
language: rust

rust:
- stable
- nightly

os:
- linux
- osx

matrix:
fast_finish: true
allow_failures:
- rust: nightly
include:
- os: linux
dist: bionic
- os: osx
osx_image: xcode11

cache:
directories:
- /home/travis/.cargo
before_cache:
- rm -rf /home/travis/.cargo/registry

# Manually handle git submodules
git:
submodules: false

before_install:
- git submodule update --init --recursive

addons:
apt:
packages:
- libcurl4-openssl-dev
- build-essential
- libssl-dev
- libelf-dev
- libdw-dev
- libbz2-dev
Expand All @@ -22,8 +46,6 @@ addons:
- musl
- musl-dev
- musl-tools
sources:
- kalakris-cmake

before_script:
- export PATH=$HOME/.cargo/bin:$PATH
Expand Down
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ serde_base = { version = "^1", optional = true, package = "serde" }
serde_bytes = { version = "0.11", optional = true }
bio-types = ">=0.5.1"
snafu = ">= 0.5.0, <= 0.6.0"
hts-sys = { version = "^1.9", path = "hts-sys" }
hts-sys = { version = "^1.9", path = "hts-sys", default-features = false }

[features]
default = ["bzip2", "lzma"]
default = ["bzip2", "lzma", "curl"]
bzip2 = ["hts-sys/bzip2"]
lzma = ["hts-sys/lzma"]
curl = ["hts-sys/curl"]
serde = ["serde_base", "serde_bytes"]

[dev-dependencies]
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ If you only want to use the library, there is no need to clone the repository. G

## Requirements

To compile this crate you need the development headers of zlib, bzip2 and xz.
To compile this crate you need the development headers of zlib, bzip2 and xz. For instance, in Debian systems one needs the following dependencies:

```shell
$ sudo apt-get install zlib1g-dev libbz2-dev liblzma-dev clang
```

## Usage

Expand Down
6 changes: 4 additions & 2 deletions hts-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description = "This library provides HTSlib bindings."
readme = "README.md"
keywords = ["htslib", "bam", "bioinformatics", "pileup", "sequencing"]
license = "MIT"
repository = "https://github.com/rust-bio/rust-htslib.git"
repository = "https://github.com/samtools/rust-htslib.git"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That line now points to the wrong repo, I'm afraid :)

Suggested change
repository = "https://github.com/samtools/rust-htslib.git"
repository = "https://github.com/rust-bio/rust-htslib.git"

Copy link
Member Author

@brainstorm brainstorm Feb 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jch-13 for the quick insight but as I pointed out earlier I think that rust-htslib should avoid this antipattern, for the following reasons:

  1. Keeping a local, rust-bio org, htslib fork might encourage small tweaks to that package, making it diverge from upstream and making future rust-htslib upgrades painful.
  2. Any required change to htslib should be upstreamed anyway, so there's no need to keep a local (outdated) fork that needs to be updated periodically.
  3. Since we use submodules to point to htslib, we might as well just point to specific tags and commits from upstream as I'm doing here since I'm pointing to version 1.10.2 of htslib from the samtools repo.

Hope those make sense? I would definitely like to hear more opinions, perhaps I'm missing very valid reasons to keep that htslib repo/fork around?

Cheers!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's some confusion here. The repository = entry in the package section of the Cargo.toml merely points to a place, where more information / documentation can be found about this package. Thus, to accurately reflect how hts-sys currently points to the rust-bio fork of htslib, it should actually read:

repository =  "https://github.com/rust-bio/htslib.git"

However, I think we can revert to actually pointing to the original htslib repo (see below for the history of this). Thus, this submodule import should be changed to point to the htslib 1.10.2 release you are updating the wrapper to and the pointer here should be changed to:

repository = "https://github.com/samtools/htslib.git"

However, the current suggested change (repository = "https://github.com/samtools/rust-htslib.git") simply doesn't exist (with the rust-prefix remaining in the repo name).

As to the history of this, I did a bit of digging:

This was originally introduced to have a commit applied that was not part of the htslib releases at the time. See for example PR #121 and especially the commit that introduced this. However, if you go over to the htslib repo, you will find that the respective commit 52368d672ce4b33a607688fc987ff396bdce68a1 has been released as of htslib 1.10, see e.g. the 1.10 release notes and the responsible htslib pull request 766 which contains this commit. Thus, as part of this update of rust-htslib to htslib 1.10.2, it should be OK to revert to pointing to the original samtools/htslib.git repo in its release 1.10.2 state.

Hope, I cleared this up a bit?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S.: I see that the submodule obviously already points to the correct upstream release tag, so just correct the repository entry with the rust-prefix released. And we can now all feel safe about doing this, knowing the history of it all... :D

Copy link
Member Author

@brainstorm brainstorm Feb 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argh, you are absolutely right, thanks @dlaehnemann, sorry @jch-13 for the misunderstanding. I'll amend that right now ;)

documentation = "https://docs.rs/rust-htslib"
edition = "2018"

Expand All @@ -21,11 +21,13 @@ libc = "0.2"
libz-sys = "1.0"
bzip2-sys = { version = "0.1", optional = true }
lzma-sys = { version = "0.1", optional = true }
curl-sys = { version = "0.4.25", optional = true }

[features]
default = ["bzip2", "lzma"]
default = ["bzip2", "lzma", "curl"]
bzip2 = ["bzip2-sys"]
lzma = ["lzma-sys"]
curl = ["curl-sys"]

[build-dependencies]
fs-utils = "1.1"
Expand Down
8 changes: 8 additions & 0 deletions hts-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ fn main() {
cfg.include(inc);
}

let use_curl = env::var("CARGO_FEATURE_CURL").is_ok();
if !use_curl {
let curl_patterns = vec!["s/ -lcurl//", "/#define HAVE_LIBCURL/d"];
sed_htslib_makefile(&out, &curl_patterns, "curl");
} else if let Ok(inc) = env::var("DEP_CURL_INCLUDE").map(PathBuf::from) {
cfg.include(inc);
}

let tool = cfg.get_compiler();
let (cc_path, cflags_env) = (tool.path(), tool.cflags_env());
let cc_cflags = cflags_env.to_string_lossy().replace("-O0", "");
Expand Down
2 changes: 1 addition & 1 deletion hts-sys/htslib
Submodule htslib updated 200 files
4 changes: 2 additions & 2 deletions src/bam/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl RecordBuffer {
let to_remove = self
.inner
.iter()
.take_while(|rec| rec.pos() < window_start as i32)
.take_while(|rec| rec.pos() < window_start as i64)
.count();
for _ in 0..to_remove {
self.inner.pop_front();
Expand All @@ -111,7 +111,7 @@ impl RecordBuffer {
record.cache_cigar();
}

if pos >= end as i32 {
if pos >= end as i64 {
self.overflow = Some(record);
break;
} else {
Expand Down
80 changes: 40 additions & 40 deletions src/bam/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,30 @@ pub trait BamRecordExtensions {
/// this happens on insertions.
///
/// pysam: blocks
fn aligned_blocks(&self) -> Vec<[i32; 2]>;
fn aligned_blocks(&self) -> Vec<[i64; 2]>;

/// find intron positions (start, stop)
///
/// This scans the CIGAR for reference skips
/// and reports their positions.
///
/// pysam: get_introns
fn introns(&self) -> Vec<[i32; 2]>;
fn introns(&self) -> Vec<[i64; 2]>;

/// a list of aligned read and reference positions
///
/// No entry for insertions, deletions or skipped pairs
///
/// pysam: get_aligned_pairs(matches_only = True)
fn aligned_pairs(&self) -> Vec<[i32; 2]>;
fn aligned_pairs(&self) -> Vec<[i64; 2]>;

/// a list of aligned read and reference positions
///
/// None in either the read positions or the reference position
/// for insertions, deletions or skipped pairs
///
/// pysam: aligned_pairs(matches_only = False)
fn aligned_pairs_full(&self) -> Vec<[Option<i32>; 2]>;
fn aligned_pairs_full(&self) -> Vec<[Option<i64>; 2]>;

/// the number of nucleotides covered by each Cigar:: possibility
///
Expand All @@ -67,19 +67,19 @@ pub trait BamRecordExtensions {
/// or unaligned positions within the read
///
/// pysam: get_reference_positions(full_length=False)
fn reference_positions(&self) -> Vec<i32>;
fn reference_positions(&self) -> Vec<i64>;
///
/// a Vec of reference positions that this read aligns to
///
/// include soft-clipped or skipped positions as None
///
/// pysam: get_reference_positions(full_length=True)
fn reference_positions_full(&self) -> Vec<Option<i32>>;
fn reference_positions_full(&self) -> Vec<Option<i64>>;

/// left most aligned reference position of the read on the reference genome.
fn reference_start(&self) -> i32;
fn reference_start(&self) -> i64;
/// right most aligned reference position of the read on the reference genome.
fn reference_end(&self) -> i32;
fn reference_end(&self) -> i64;

/// infer the query length from the cigar string, optionally include hard clipped bases
///
Expand All @@ -91,34 +91,34 @@ pub trait BamRecordExtensions {
}

impl BamRecordExtensions for bam::Record {
fn aligned_blocks(&self) -> Vec<[i32; 2]> {
fn aligned_blocks(&self) -> Vec<[i64; 2]> {
let mut result = Vec::new();
let mut pos = self.pos();
for entry in self.cigar().iter() {
match entry {
Cigar::Match(len) => {
result.push([pos, pos + *len as i32]);
pos += *len as i32;
result.push([pos, pos + *len as i64]);
pos += *len as i64;
}
Cigar::Del(len) => pos += *len as i32,
Cigar::RefSkip(len) => pos += *len as i32,
Cigar::Del(len) => pos += *len as i64,
Cigar::RefSkip(len) => pos += *len as i64,
_ => (),
}
}
result
}

fn introns(&self) -> Vec<[i32; 2]> {
fn introns(&self) -> Vec<[i64; 2]> {
let mut base_position = self.pos();
let mut result = Vec::new();
for entry in self.cigar().iter() {
match entry {
Cigar::Match(len) | Cigar::Del(len) | Cigar::Equal(len) | Cigar::Diff(len) => {
base_position += *len as i32
base_position += *len as i64
}
Cigar::RefSkip(len) => {
let junc_start = base_position;
base_position += *len as i32;
base_position += *len as i64;
result.push([junc_start, base_position]);
}
_ => {}
Expand All @@ -127,25 +127,25 @@ impl BamRecordExtensions for bam::Record {
result
}

fn aligned_pairs(&self) -> Vec<[i32; 2]> {
fn aligned_pairs(&self) -> Vec<[i64; 2]> {
let mut result = Vec::new();

let mut pos: i32 = self.pos();
let mut qpos: i32 = 0;
let mut pos: i64 = self.pos();
let mut qpos: i64 = 0;
for entry in self.cigar().iter() {
match entry {
Cigar::Match(len) | Cigar::Equal(len) | Cigar::Diff(len) => {
for i in pos..(pos + *len as i32) {
for i in pos..(pos + *len as i64) {
result.push([qpos, i]);
qpos += 1;
}
pos += *len as i32;
pos += *len as i64;
}
Cigar::Ins(len) | Cigar::SoftClip(len) => {
qpos += *len as i32;
qpos += *len as i64;
}
Cigar::Del(len) | Cigar::RefSkip(len) => {
pos += *len as i32;
pos += *len as i64;
}
Cigar::HardClip(_) => {} // no advance
Cigar::Pad(_) => panic!("Padding (Cigar::Pad) is not supported."), //padding is only used for multiple sequence alignment
Expand All @@ -154,31 +154,31 @@ impl BamRecordExtensions for bam::Record {
result
}

fn aligned_pairs_full(&self) -> Vec<[Option<i32>; 2]> {
fn aligned_pairs_full(&self) -> Vec<[Option<i64>; 2]> {
let mut result = Vec::new();

let mut pos: i32 = self.pos();
let mut qpos: i32 = 0;
let mut pos: i64 = self.pos();
let mut qpos: i64 = 0;
for entry in self.cigar().iter() {
match entry {
Cigar::Match(len) | Cigar::Equal(len) | Cigar::Diff(len) => {
for i in pos..(pos + *len as i32) {
for i in pos..(pos + *len as i64) {
result.push([Some(qpos), Some(i)]);
qpos += 1;
}
pos += *len as i32;
pos += *len as i64;
}
Cigar::Ins(len) | Cigar::SoftClip(len) => {
for i in qpos..(qpos + *len as i32) {
for i in qpos..(qpos + *len as i64) {
result.push([Some(i), None]);
}
qpos += *len as i32;
qpos += *len as i64;
}
Cigar::Del(len) | Cigar::RefSkip(len) => {
for i in pos..(pos + *len as i32) {
for i in pos..(pos + *len as i64) {
result.push([None, Some(i)]);
}
pos += *len as i32;
pos += *len as i64;
}
Cigar::HardClip(_) => {} // no advance
Cigar::Pad(_) => panic!("Padding (Cigar::Pad) is not supported."), //padding is only used for multiple sequence alignment
Expand Down Expand Up @@ -244,21 +244,21 @@ impl BamRecordExtensions for bam::Record {
result
}

fn reference_positions(&self) -> Vec<i32> {
fn reference_positions(&self) -> Vec<i64> {
self.aligned_pairs().iter().map(|x| x[1]).collect()
}

fn reference_positions_full(&self) -> Vec<Option<i32>> {
fn reference_positions_full(&self) -> Vec<Option<i64>> {
self.aligned_pairs_full()
.iter()
.filter(|x| x[0].is_some())
.map(|x| x[1])
.collect()
}
fn reference_start(&self) -> i32 {
fn reference_start(&self) -> i64 {
self.pos()
}
fn reference_end(&self) -> i32 {
fn reference_end(&self) -> i64 {
unsafe { htslib::bam_endpos(self.inner_ptr()) }
}

Expand Down Expand Up @@ -4304,11 +4304,11 @@ mod tests {

//
//for the rest, we just verify that they have the expected amount of None in each position
fn some_count(pairs: &Vec<[Option<i32>; 2]>, pos: usize) -> i32 {
pairs.iter().filter(|x| x[pos].is_some()).count() as i32
fn some_count(pairs: &Vec<[Option<i64>; 2]>, pos: usize) -> i64 {
pairs.iter().filter(|x| x[pos].is_some()).count() as i64
}
fn none_count(pairs: &Vec<[Option<i32>; 2]>, pos: usize) -> i32 {
pairs.iter().filter(|x| x[pos].is_none()).count() as i32
fn none_count(pairs: &Vec<[Option<i64>; 2]>, pos: usize) -> i64 {
pairs.iter().filter(|x| x[pos].is_none()).count() as i64
}

let pairs = it.next().unwrap().unwrap().aligned_pairs_full();
Expand Down
Loading