use super::{QueryMethod, StrandMethod};
use crate::traits::{ChromBounds, IntervalBounds, SetError, ValueBounds};
#[derive(Debug, Default, Clone, Copy)]
pub struct Query<T: ValueBounds> {
predicate: QueryMethod<T>,
strandedness: StrandMethod,
}
impl<T> Query<T>
where
T: ValueBounds,
{
#[must_use]
pub fn new(predicate: QueryMethod<T>, strandedness: StrandMethod) -> Self {
Self {
predicate,
strandedness,
}
}
#[must_use]
pub fn new_predicate(predicate: QueryMethod<T>) -> Self {
Self {
predicate,
strandedness: StrandMethod::default(),
}
}
#[must_use]
pub fn new_strandedness(strandedness: StrandMethod) -> Self {
Self {
predicate: QueryMethod::default(),
strandedness,
}
}
pub fn validate(&self) -> Result<(), SetError> {
self.predicate.validate()
}
pub fn predicate<I, Iv, C>(&self, target: &I, query: &Iv) -> bool
where
I: IntervalBounds<C, T>,
Iv: IntervalBounds<C, T>,
C: ChromBounds,
{
match self.strandedness {
StrandMethod::Ignore => self.ignored_strand(target, query),
StrandMethod::MatchStrand => self.bounded_strand(target, query),
StrandMethod::OppositeStrand => self.unbounded_strand(target, query),
}
}
fn ignored_strand<I, Iv, C>(&self, target: &I, query: &Iv) -> bool
where
I: IntervalBounds<C, T>,
Iv: IntervalBounds<C, T>,
C: ChromBounds,
{
match self.predicate {
QueryMethod::Compare => target.overlaps(query),
QueryMethod::CompareBy(val) => target.overlaps_by(query, val),
QueryMethod::CompareExact(val) => target.overlaps_by_exactly(query, val),
QueryMethod::CompareByQueryFraction(frac) => {
let min_overlap = query.f_len(frac);
target.overlaps_by(query, min_overlap)
}
QueryMethod::CompareByTargetFraction(frac) => {
let min_overlap = target.f_len(frac);
target.overlaps_by(query, min_overlap)
}
QueryMethod::CompareReciprocalFractionAnd(f_query, f_target) => {
let query_min_overlap = query.f_len(f_query);
let target_min_overlap = target.f_len(f_target);
if let Some(ix) = target.overlap_size(query) {
query_min_overlap <= ix && target_min_overlap <= ix
} else {
false
}
}
QueryMethod::CompareReciprocalFractionOr(f_query, f_target) => {
let query_min_overlap = query.f_len(f_query);
let target_min_overlap = target.f_len(f_target);
if let Some(ix) = target.overlap_size(query) {
query_min_overlap <= ix || target_min_overlap <= ix
} else {
false
}
}
}
}
fn bounded_strand<I, Iv, C>(&self, target: &I, query: &Iv) -> bool
where
I: IntervalBounds<C, T>,
Iv: IntervalBounds<C, T>,
C: ChromBounds,
{
match self.predicate {
QueryMethod::Compare => target.stranded_overlaps(query),
QueryMethod::CompareBy(val) => target.stranded_overlaps_by(query, val),
QueryMethod::CompareExact(val) => target.stranded_overlaps_by_exactly(query, val),
QueryMethod::CompareByQueryFraction(frac) => {
let min_overlap = query.f_len(frac);
target.stranded_overlaps_by(query, min_overlap)
}
QueryMethod::CompareByTargetFraction(frac) => {
let min_overlap = target.f_len(frac);
target.stranded_overlaps_by(query, min_overlap)
}
QueryMethod::CompareReciprocalFractionAnd(f_query, f_target) => {
let query_min_overlap = query.f_len(f_query);
let target_min_overlap = target.f_len(f_target);
if let Some(ix) = target.stranded_overlap_size(query) {
query_min_overlap <= ix && target_min_overlap <= ix
} else {
false
}
}
QueryMethod::CompareReciprocalFractionOr(f_query, f_target) => {
let query_min_overlap = query.f_len(f_query);
let target_min_overlap = target.f_len(f_target);
if let Some(ix) = target.stranded_overlap_size(query) {
query_min_overlap <= ix || target_min_overlap <= ix
} else {
false
}
}
}
}
fn unbounded_strand<I, Iv, C>(&self, target: &I, query: &Iv) -> bool
where
I: IntervalBounds<C, T>,
Iv: IntervalBounds<C, T>,
C: ChromBounds,
{
match self.predicate {
QueryMethod::Compare => target.unstranded_overlaps(query),
QueryMethod::CompareBy(val) => target.unstranded_overlaps_by(query, val),
QueryMethod::CompareExact(val) => target.unstranded_overlaps_by_exactly(query, val),
QueryMethod::CompareByQueryFraction(frac) => {
let min_overlap = query.f_len(frac);
target.unstranded_overlaps_by(query, min_overlap)
}
QueryMethod::CompareByTargetFraction(frac) => {
let min_overlap = target.f_len(frac);
target.unstranded_overlaps_by(query, min_overlap)
}
QueryMethod::CompareReciprocalFractionAnd(f_query, f_target) => {
let query_min_overlap = query.f_len(f_query);
let target_min_overlap = target.f_len(f_target);
if let Some(ix) = target.unstranded_overlap_size(query) {
query_min_overlap <= ix && target_min_overlap <= ix
} else {
false
}
}
QueryMethod::CompareReciprocalFractionOr(f_query, f_target) => {
let query_min_overlap = query.f_len(f_query);
let target_min_overlap = target.f_len(f_target);
if let Some(ix) = target.unstranded_overlap_size(query) {
query_min_overlap <= ix || target_min_overlap <= ix
} else {
false
}
}
}
}
}
#[cfg(test)]
mod testing {
use super::*;
use crate::{Strand, StrandedBed3};
const STRAND_METHODS: [StrandMethod; 3] = [
StrandMethod::Ignore,
StrandMethod::MatchStrand,
StrandMethod::OppositeStrand,
];
#[test]
fn validate_query_compare() {
for sm in &STRAND_METHODS {
let query: Query<usize> = Query::new(QueryMethod::Compare, *sm);
assert!(query.validate().is_ok());
}
}
#[test]
fn validate_query_compare_by() {
for sm in &STRAND_METHODS {
let query: Query<usize> = Query::new(QueryMethod::CompareBy(10), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> = Query::new(QueryMethod::CompareBy(0), *sm);
assert!(query.validate().is_err());
}
}
#[test]
fn validate_query_compare_exact() {
for sm in &STRAND_METHODS {
let query: Query<usize> = Query::new(QueryMethod::CompareExact(10), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> = Query::new(QueryMethod::CompareExact(0), *sm);
assert!(query.validate().is_err());
}
}
#[test]
fn validate_query_compare_by_query_fraction() {
for sm in &STRAND_METHODS {
let query: Query<usize> = Query::new(QueryMethod::CompareByQueryFraction(0.5), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> = Query::new(QueryMethod::CompareByQueryFraction(1.0), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> = Query::new(QueryMethod::CompareByQueryFraction(0.0), *sm);
assert!(query.validate().is_err());
let query: Query<usize> = Query::new(QueryMethod::CompareByQueryFraction(-0.1), *sm);
assert!(query.validate().is_err());
let query: Query<usize> = Query::new(QueryMethod::CompareByQueryFraction(2.0), *sm);
assert!(query.validate().is_err());
}
}
#[test]
fn validate_query_compare_by_target_fraction() {
for sm in &STRAND_METHODS {
let query: Query<usize> = Query::new(QueryMethod::CompareByTargetFraction(0.5), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> = Query::new(QueryMethod::CompareByTargetFraction(1.0), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> = Query::new(QueryMethod::CompareByTargetFraction(0.0), *sm);
assert!(query.validate().is_err());
let query: Query<usize> = Query::new(QueryMethod::CompareByTargetFraction(-0.1), *sm);
assert!(query.validate().is_err());
let query: Query<usize> = Query::new(QueryMethod::CompareByTargetFraction(2.0), *sm);
assert!(query.validate().is_err());
}
}
#[test]
fn validate_query_compare_reciprocal_fraction_and() {
for sm in &STRAND_METHODS {
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(0.5, 0.5), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(1.0, 1.0), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(0.0, 0.0), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(-0.1, -0.1), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(2.0, 2.0), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(0.5, 0.0), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(0.0, 0.5), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(-0.1, 0.5), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(0.5, -0.1), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(2.0, 0.5), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionAnd(0.5, 2.0), *sm);
assert!(query.validate().is_err());
}
}
#[test]
fn validate_query_compare_reciprocal_fraction_or() {
for sm in &STRAND_METHODS {
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(0.5, 0.5), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(1.0, 1.0), *sm);
assert!(query.validate().is_ok());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(0.0, 0.0), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(-0.1, -0.1), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(2.0, 2.0), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(0.5, 0.0), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(0.0, 0.5), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(-0.1, 0.5), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(0.5, -0.1), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(2.0, 0.5), *sm);
assert!(query.validate().is_err());
let query: Query<usize> =
Query::new(QueryMethod::CompareReciprocalFractionOr(0.5, 2.0), *sm);
assert!(query.validate().is_err());
}
}
#[test]
fn strand_ignore_compare() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 30, 40, Strand::Forward);
let iv_e = StrandedBed3::new(1, 30, 40, Strand::Reverse);
let query = Query::new(QueryMethod::Compare, StrandMethod::Ignore);
assert!(query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_match_compare() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 30, 40, Strand::Forward);
let iv_e = StrandedBed3::new(1, 30, 40, Strand::Reverse);
let query = Query::new(QueryMethod::Compare, StrandMethod::MatchStrand);
assert!(query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_opposite_compare() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 30, 40, Strand::Forward);
let iv_e = StrandedBed3::new(1, 30, 40, Strand::Reverse);
let query = Query::new(QueryMethod::Compare, StrandMethod::OppositeStrand);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_ignore_compare_by() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 12, 22, Strand::Forward);
let iv_e = StrandedBed3::new(1, 12, 22, Strand::Reverse);
let query = Query::new(QueryMethod::CompareBy(7), StrandMethod::Ignore);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(query.predicate(&iv_a, &iv_d));
assert!(query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_match_compare_by() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 12, 22, Strand::Forward);
let iv_e = StrandedBed3::new(1, 12, 22, Strand::Reverse);
let query = Query::new(QueryMethod::CompareBy(7), StrandMethod::MatchStrand);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_opposite_compare_by() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 12, 22, Strand::Forward);
let iv_e = StrandedBed3::new(1, 12, 22, Strand::Reverse);
let query = Query::new(QueryMethod::CompareBy(7), StrandMethod::OppositeStrand);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_ignore_compare_exact() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 12, 22, Strand::Forward);
let iv_e = StrandedBed3::new(1, 12, 22, Strand::Reverse);
let query = Query::new(QueryMethod::CompareExact(5), StrandMethod::Ignore);
assert!(query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_match_compare_exact() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 12, 22, Strand::Forward);
let iv_e = StrandedBed3::new(1, 12, 22, Strand::Reverse);
let query = Query::new(QueryMethod::CompareExact(5), StrandMethod::MatchStrand);
assert!(query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_opposite_compare_exact() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 12, 22, Strand::Forward);
let iv_e = StrandedBed3::new(1, 12, 22, Strand::Reverse);
let query = Query::new(QueryMethod::CompareExact(5), StrandMethod::OppositeStrand);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_ignore_compare_by_query_fraction() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_e = StrandedBed3::new(1, 10, 100, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareByQueryFraction(0.5),
StrandMethod::Ignore,
);
assert!(query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_match_compare_by_query_fraction() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_e = StrandedBed3::new(1, 10, 100, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareByQueryFraction(0.5),
StrandMethod::MatchStrand,
);
assert!(query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_opposite_compare_by_query_fraction() {
let iv_a = StrandedBed3::new(1, 10, 20, Strand::Forward);
let iv_b = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_c = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_e = StrandedBed3::new(1, 10, 100, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareByQueryFraction(0.5),
StrandMethod::OppositeStrand,
);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_ignore_compare_by_target_fraction() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareByTargetFraction(0.5),
StrandMethod::Ignore,
);
assert!(query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_match_compare_by_target_fraction() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareByTargetFraction(0.5),
StrandMethod::MatchStrand,
);
assert!(query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_opposite_compare_by_target_fraction() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareByTargetFraction(0.5),
StrandMethod::OppositeStrand,
);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_ignore_compare_reciprocal_fraction_and() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareReciprocalFractionAnd(0.5, 0.5),
StrandMethod::Ignore,
);
assert!(query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_match_compare_reciprocal_fraction_and() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareReciprocalFractionAnd(0.5, 0.5),
StrandMethod::MatchStrand,
);
assert!(query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_opposite_compare_reciprocal_fraction_and() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareReciprocalFractionAnd(0.5, 0.5),
StrandMethod::OppositeStrand,
);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_ignore_compare_reciprocal_fraction_or() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareReciprocalFractionOr(0.5, 0.5),
StrandMethod::Ignore,
);
assert!(query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(query.predicate(&iv_a, &iv_d));
assert!(query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_match_compare_reciprocal_fraction_or() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareReciprocalFractionOr(0.5, 0.5),
StrandMethod::MatchStrand,
);
assert!(query.predicate(&iv_a, &iv_b));
assert!(!query.predicate(&iv_a, &iv_c));
assert!(query.predicate(&iv_a, &iv_d));
assert!(!query.predicate(&iv_a, &iv_e));
}
#[test]
fn strand_opposite_compare_reciprocal_fraction_or() {
let iv_a = StrandedBed3::new(1, 10, 100, Strand::Forward);
let iv_b = StrandedBed3::new(1, 50, 150, Strand::Forward);
let iv_c = StrandedBed3::new(1, 50, 150, Strand::Reverse);
let iv_d = StrandedBed3::new(1, 15, 25, Strand::Forward);
let iv_e = StrandedBed3::new(1, 15, 25, Strand::Reverse);
let query = Query::new(
QueryMethod::CompareReciprocalFractionOr(0.5, 0.5),
StrandMethod::OppositeStrand,
);
assert!(!query.predicate(&iv_a, &iv_b));
assert!(query.predicate(&iv_a, &iv_c));
assert!(!query.predicate(&iv_a, &iv_d));
assert!(query.predicate(&iv_a, &iv_e));
}
}