1#![doc = include_str!("../README.md")]
7#![warn(clippy::pedantic)]
8use bitvec::prelude::*;
14
15type Order = Lsb0;
16type Bs = BitSlice<usize, Order>;
17type Bv = BitVec<usize, Order>;
18type Ba<const W: usize> = BitArray<[usize; W], Order>;
19
20mod hash;
21
22pub mod codec;
23pub mod error;
24#[macro_use]
25pub mod kmer;
26pub mod seq;
27
28pub use bio_seq_derive::{dna, iupac};
29
30#[doc(hidden)]
31pub use bitvec::bitarr as __bio_seq_bitarr;
32
33#[doc(hidden)]
34pub use bitvec::prelude::Lsb0 as __bio_seq_Lsb0;
35
36#[cfg(feature = "translation")]
37pub mod translation;
38
39pub mod prelude {
40 pub use crate::codec::Codec;
41 pub use crate::codec::amino::Amino;
42 pub use crate::codec::dna::Dna;
43 pub use crate::codec::iupac::Iupac;
44 pub use crate::{
45 Complement, ComplementMut, Maskable, MaskableMut, Reverse, ReverseComplement,
46 ReverseComplementMut, ReverseMut,
47 };
48
49 pub use crate::kmer::Kmer;
50 pub use crate::seq::{Seq, SeqArray, SeqSlice};
51
52 #[cfg(feature = "translation")]
53 pub use crate::translation;
54
55 pub use core::str::FromStr;
56
57 pub use crate::error::ParseBioError;
58
59 pub use crate::{dna, iupac, kmer};
60
61 #[doc(hidden)]
62 pub use crate::__bio_seq_Lsb0;
63 #[doc(hidden)]
64 pub use crate::__bio_seq_bitarr;
65 #[doc(hidden)]
66 pub use crate::__bio_seq_count_words;
67}
68
69pub trait ComplementMut {
71 fn comp(&mut self);
72}
73
74pub trait Complement: ComplementMut + ToOwned
75where
76 <Self as ToOwned>::Owned: ComplementMut,
77{
78 #[must_use]
83 fn to_comp(&self) -> <Self as ToOwned>::Owned {
84 let mut owned = self.to_owned();
85 owned.comp();
86 owned
87 }
88}
89
90pub trait ReverseMut {
94 fn rev(&mut self);
96}
97
98pub trait Reverse: ReverseMut + ToOwned
99where
100 <Self as ToOwned>::Owned: ReverseMut,
101{
102 #[must_use]
103 fn to_rev(&self) -> <Self as ToOwned>::Owned {
104 let mut owned = self.to_owned();
105 owned.rev();
106 owned
107 }
108}
109
110pub trait ReverseComplementMut: ComplementMut + ReverseMut {
114 fn revcomp(&mut self) {
116 self.comp();
117 self.rev();
118 }
119}
120
121pub trait ReverseComplement: ReverseComplementMut + ToOwned
124where
125 <Self as ToOwned>::Owned: ReverseComplementMut,
126{
127 #[must_use]
128 fn to_revcomp(&self) -> <Self as ToOwned>::Owned {
129 let mut owned = self.to_owned();
130 owned.revcomp();
131 owned
132 }
133}
134
135pub trait MaskableMut {
143 fn mask(&mut self);
144 fn unmask(&mut self);
145}
146
147pub trait Maskable: MaskableMut + ToOwned
148where
149 <Self as ToOwned>::Owned: MaskableMut,
150{
151 #[must_use]
152 fn to_mask(&self) -> <Self as ToOwned>::Owned {
153 let mut owned = self.to_owned();
154 owned.mask();
155 owned
156 }
157 #[must_use]
158 fn to_unmask(&self) -> <Self as ToOwned>::Owned {
159 let mut owned = self.to_owned();
160 owned.unmask();
161 owned
162 }
163}
164
165#[macro_export]
168macro_rules! __bio_seq_count_words {
169 ($len:expr) => {{ $len.div_ceil(usize::BITS) as usize }};
170}
171
172#[cfg(test)]
173mod tests {
174 use crate::codec::dna::Dna::{A, C, G, T};
175 use crate::prelude::*;
176 use std::hash::{DefaultHasher, Hash, Hasher};
177
178 #[test]
179 fn alt_repr() {
180 assert_eq!(iupac!("-").nth(0), Iupac::X);
181 }
182
183 #[test]
184 fn into_usize() {
185 let bits: usize = dna!("ACGT").to_owned().into_raw()[0];
186 assert_eq!(bits, 0b11_10_01_00);
187
188 let bits: usize = dna!("CGCG").to_owned().into_raw()[0];
189 assert_eq!(bits, 0b10_01_10_01);
190
191 let bits: usize = Seq::from(&vec![T, T]).into();
192 assert_eq!(bits, 0b11_11);
193
194 let bits: usize = Seq::<Dna>::from_str("TCA").unwrap().into();
195 assert_eq!(bits, 0b00_01_11);
196
197 let bits: usize = Seq::<Dna>::from_str("TGA").unwrap().into();
198 assert_eq!(bits, 0b00_10_11);
199
200 let bits: usize = Seq::from(&vec![C, G, T, A, C, G, A, T]).into();
201 assert_eq!(bits, 0b11_00_10_01_00_11_10_01);
202
203 let bits: usize = Seq::from(&vec![A]).into();
204 assert_eq!(bits, 0b00);
205 }
206
207 #[test]
208 fn test_display_aminos() {
209 let a: Seq<Amino> = Seq::from_str("DCMNLKG*HI").unwrap();
210 assert_eq!(format!("{a}"), "DCMNLKG*HI");
211 }
212 #[test]
213 fn test_display_dna() {
214 let seq = Seq::from(&vec![A, C, G, T, T, A, T, C]);
215 assert_eq!(format!("{seq}"), "ACGTTATC");
216 assert_eq!(format!("{}", dna!("ACGT")), "ACGT");
217 }
218
219 #[test]
220 fn iterate_bases() {
221 let seq = dna!("ACGTACGT");
222 assert_eq!(
223 seq.into_iter().collect::<Vec<Dna>>(),
224 vec![A, C, G, T, A, C, G, T]
225 );
226 }
227
228 #[test]
229 fn from_string() {
230 let seq = Seq::<Dna>::from_str("ACGTACGT").unwrap();
231 assert_eq!(
232 seq.into_iter().collect::<Vec<Dna>>(),
233 vec![A, C, G, T, A, C, G, T]
234 );
235 }
236 #[test]
237 fn rev_seq() {
238 let seq = dna!("ACGTACGT");
239 assert_eq!(
240 seq.rev_iter().collect::<Vec<Dna>>(),
241 vec![T, G, C, A, T, G, C, A]
242 );
243 assert_eq!(
244 seq.to_rev().into_iter().collect::<Vec<Dna>>(),
245 vec![T, G, C, A, T, G, C, A]
246 );
247 assert_eq!(
248 iupac!("GN-").rev_iter().collect::<Vec<Iupac>>(),
249 vec![Iupac::X, Iupac::N, Iupac::G]
250 );
251
252 assert_eq!(
253 Seq::<Amino>::try_from("DCMNLKGHI")
254 .unwrap()
255 .to_rev()
256 .into_iter()
257 .collect::<Vec<Amino>>(),
258 vec![
259 Amino::I,
260 Amino::H,
261 Amino::G,
262 Amino::K,
263 Amino::L,
264 Amino::N,
265 Amino::M,
266 Amino::C,
267 Amino::D
268 ]
269 );
270 }
271 #[test]
272 fn iterate_kmers() {
273 let seq = dna!("ACGTAAGGGG");
274 for (kmer, answer) in seq
275 .kmers::<4>()
276 .zip(["ACGT", "CGTA", "GTAA", "TAAG", "AAGG", "AGGG", "GGGG"])
277 {
278 assert_eq!(format!("{kmer}"), answer);
279 }
280 }
281
282 #[test]
283 fn iterate_kmer8() {
284 let seq = dna!("AAAACCCCGGGG");
285 for (kmer, answer) in seq
286 .kmers::<8>()
287 .zip(["AAAACCCC", "AAACCCCG", "AACCCCGG", "ACCCCGGG", "CCCCGGGG"])
288 {
289 assert_eq!(format!("{kmer}"), answer);
290 }
291 }
292
293 #[test]
294 fn iterate_kmer4() {
295 let seq = dna!("AAAACCCCGGGGTTTT");
296 for (kmer, answer) in seq.kmers::<4>().zip([
297 "AAAA", "AAAC", "AACC", "ACCC", "CCCC", "CCCG", "CCGG", "CGGG", "GGGG", "GGGT", "GGTT",
298 "GTTT", "TTTT",
299 ]) {
300 assert_eq!(format!("{kmer}"), answer);
301 }
302 }
303
304 #[test]
305 fn iupac_bitwise_ops() {
306 let s1: &SeqSlice<Iupac> = iupac!("AS-GYTNA");
307 let s2: &SeqSlice<Iupac> = iupac!("ANTGCAT-");
308
309 let s3: &SeqSlice<Iupac> = iupac!("ACGTSWKM");
310 let s4: &SeqSlice<Iupac> = iupac!("WKMSTNNA");
311
312 assert_eq!(s1 | s2, iupac!("ANTGYWNA"));
313 assert_eq!(s3 & s4, iupac!("A----WKA"));
314 }
315 #[test]
316 fn min_sequence() {
317 let seq = dna!("GCTCGATCGTAAAAAATCGTATT");
318
319 let minimised = seq.kmers::<8>().min().unwrap();
320 assert_eq!(minimised, Kmer::try_from(dna!("GTAAAAAA")).unwrap());
321 }
322
323 #[test]
324 fn hash_minimiser() {
325 use core::cmp::min;
326
327 fn hash(seq: &SeqSlice<Dna>) -> u64 {
328 u64::from(seq != dna!("GGCTCTCTCTCCTCCA"))
329 }
330
331 let seq =
332 dna!("AGCGCTAGTCGTACTGCCGCATCGCTAGCGCTAAAAAAAAAAAAAAAAGGGGTGTGTGGGTTGTGGAGGAGAGAGAGCC");
333
334 let (minimiser_rc, min_hash_rc) = seq
337 .to_revcomp()
338 .kmers::<16>()
339 .map(|kmer| (kmer, hash(&kmer)))
340 .min_by_key(|&(_, hash)| hash)
341 .unwrap();
342
343 let (minimiser, min_hash) = seq
344 .kmers::<16>()
345 .map(|kmer| (kmer, hash(&kmer)))
346 .min_by_key(|&(_, hash)| hash)
347 .unwrap();
348
349 let (canonical_minimiser, canonical_hash) = seq
352 .kmers::<16>()
353 .map(|kmer| {
354 let canonical_hash = min(hash(&kmer), hash(&kmer.to_revcomp()));
355 (kmer, canonical_hash)
356 })
357 .min_by_key(|&(_, hash)| hash)
358 .unwrap();
359
360 println!(
361 "{minimiser_rc} {min_hash_rc}\n{minimiser} {min_hash}\n{canonical_minimiser} {canonical_hash}"
362 );
363 assert_eq!(min_hash_rc, canonical_hash);
364 assert_ne!(min_hash, canonical_hash);
365 assert_eq!(minimiser_rc, canonical_minimiser.to_revcomp());
366 }
367
368 #[test]
369 #[expect(
370 clippy::needless_borrows_for_generic_args,
371 reason = "exercise hashing both values and references"
372 )]
373 fn hash_characteristics() {
374 fn hash<T: Hash>(chunk: T) -> u64 {
375 let mut hasher = DefaultHasher::new();
376 chunk.hash(&mut hasher);
377 hasher.finish()
378 }
379
380 let s1 = dna!("AGCGCTAGTCGTACTGCCGCATCGCTAGCGCT");
381 let s2 = dna!("AGCGCTAGTCGTACTGCCGCATCGCTAGCGCTA");
382
383 let q1: Seq<Dna> = dna!("AGCGCTAGTCGTACTGCCGCATCGCTAGCGCT").into();
384 let q2: Seq<Dna> = dna!("AGCGCTAGTCGTACTGCCGCATCGCTAGCGCTA").into();
385
386 let s3 = dna!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
387 let s4 = dna!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
388
389 let q3 = dna!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
390 let q4 = dna!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
391
392 let l3: &SeqSlice<Dna> = q3;
393 let l3_a: &SeqSlice<Dna> = &q4[1..];
394 let l3_b: &SeqSlice<Dna> = &q4[..32];
395 let l4: &SeqSlice<Dna> = q4;
396
397 let k1: Kmer<Dna, 32, u64> = s1.try_into().unwrap();
398 let k1_a: Kmer<Dna, 32, u64> = s1.try_into().unwrap();
399
400 let k3: Kmer<Dna, 32, u64> = s3.try_into().unwrap();
401
402 assert_eq!(hash(&l3), hash(q3));
403 assert_eq!(hash(&l3), hash(&l3_a));
404 assert_eq!(hash(&l3_a), hash(&l3_b));
405
406 assert_eq!(hash(&s2), hash(&q2));
407
408 assert_eq!(hash(&s1), hash(s1));
409 assert_eq!(hash(s2), hash(&s2));
410 assert_ne!(hash(&s4), hash(&s3));
411
412 assert_ne!(hash(&l3), hash(&l4));
413 assert_ne!(hash(&l3_a), hash(&l4));
414
415 assert_ne!(hash(&q2), hash(&q1));
416
417 assert_eq!(hash(q3), hash(s3));
418 assert_eq!(hash(s1), hash(&q1));
419 assert_ne!(hash(s3), hash(s4));
420
421 assert_ne!(hash(&k3), hash(&k1));
422 assert_eq!(hash(&k1_a), hash(&k1));
423 assert_eq!(hash(s1), hash(&k1));
424 }
425
426 #[test]
427 fn sequence_type_hashes() {
428 fn hash<T: Hash>(chunk: &T) -> u64 {
429 let mut hasher = DefaultHasher::new();
430 chunk.hash(&mut hasher);
431 hasher.finish()
432 }
433
434 let seq_arr: &SeqSlice<Dna> = dna!("AGCGCTAGTCGTACTGCCGCATCGCTAGCGCT");
435 let seq: Seq<Dna> = seq_arr.into();
436 let seq_slice: &SeqSlice<Dna> = &seq;
437 let kmer: Kmer<Dna, 32, u64> = seq_arr.try_into().unwrap();
438
439 assert_eq!(hash(&seq_arr), hash(&seq));
440 assert_eq!(hash(&seq), hash(&seq_slice));
441 assert_eq!(hash(&seq_slice), hash(&kmer));
442 }
443
444 #[test]
445 fn nth_chars() {
446 assert_eq!(iupac!("ACGTRYSWKMBDHVN-").nth(0), Iupac::A);
447 assert_ne!(iupac!("ACGTRYSWKMBDHVN-").nth(0), Iupac::C);
448 assert_eq!(iupac!("ACGTRYSWKMBDHVN-").nth(15), Iupac::X);
449 assert_eq!(iupac!("ACGTRYSWKMBDHVN-").nth(3), Iupac::from(Dna::T));
450 assert_ne!(iupac!("ACGTRYSWKMBDHVN-").nth(3), Iupac::from(Dna::G));
451
452 assert_eq!(
453 Seq::<Amino>::try_from("DCMNLKGHI").unwrap().nth(1),
454 Amino::C
455 );
456 assert_ne!(
457 Seq::<Amino>::try_from("DCMNLKGHI").unwrap().nth(7),
458 Amino::I
459 );
460 }
461
462 #[test]
463 fn colexicographic_order() {
464 for (i, e) in ["AA", "CA", "GA", "TA", "AC", "CC", "GC", "TC"]
465 .iter()
466 .enumerate()
467 {
468 assert_eq!(format!("{}", Kmer::<Dna, 2>::from(i)), e.to_string());
469 assert_eq!(Kmer::<Dna, 2>::from(i), *e);
470 }
471 }
472
473 #[test]
474 #[expect(
475 clippy::redundant_slicing,
476 reason = "exercise equality with full-range indexing"
477 )]
478 #[expect(
479 clippy::similar_names,
480 reason = "names identify sequence variants and k-mer storage widths"
481 )]
482 fn sequence_type_equality() {
483 let raw_a = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAA";
484 let raw_b = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA";
485 let raw_c = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA";
486 let raw_d = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAAA";
487
488 assert_eq!(raw_a.len(), 63);
489 assert_eq!(raw_b.len(), 64);
490 assert_eq!(raw_d.len(), 65);
491
492 assert_eq!(raw_c, raw_b);
493 assert_eq!(raw_c, &raw_b[..]);
494
495 assert_ne!(raw_b, raw_d);
496 assert_ne!(raw_a, raw_b);
497
498 let seq_a: Seq<Dna> = raw_a.try_into().unwrap();
501 let seq_b: Seq<Dna> = raw_b.try_into().unwrap();
502 let seq_c: Seq<Dna> = raw_c.try_into().unwrap();
503 let seq_d: Seq<Dna> = raw_d.try_into().unwrap();
504
505 assert_eq!(seq_a.len(), raw_a.len());
506 assert_eq!(seq_d.len(), raw_d.len());
507
508 assert_eq!(seq_c, seq_b);
509 assert_eq!(seq_c, &seq_b);
510
511 assert_ne!(seq_a, &seq_b);
512 assert_ne!(seq_a, seq_b);
513 assert_ne!(seq_c, seq_d);
514
515 let slice_a: &SeqSlice<Dna> = &seq_a;
518 let slice_b: &SeqSlice<Dna> = &seq_b;
519 let slice_c: &SeqSlice<Dna> = &seq_c;
520 let slice_d: &SeqSlice<Dna> = &seq_d;
521
522 assert_eq!(slice_a.len(), raw_a.len());
523 assert_eq!(slice_d.len(), raw_d.len());
524
525 assert_eq!(slice_c, slice_b);
526 assert_eq!(slice_c, &slice_b[..]);
527
528 assert_ne!(slice_a, slice_b);
529 assert_ne!(slice_c, slice_d);
530 assert_ne!(slice_c, &slice_d[..]);
531
532 let array_a = dna!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAA");
535 let array_b = dna!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA");
536 let array_c: &'static SeqSlice<Dna> =
537 dna!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA");
538 let array_d: &'static SeqSlice<Dna> =
539 dna!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAAA");
540
541 assert_eq!(array_a.len(), raw_a.len());
542 assert_eq!(array_d.len(), raw_d.len());
543
544 assert_eq!(array_c, array_b);
545
546 assert_ne!(array_a, array_b);
547 assert_ne!(array_c, array_d);
548
549 let kmer_ax_32: Kmer<Dna, 32, u64> = kmer!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAG", u64);
552 let kmer_bx_32 = Kmer::<Dna, 32, u64>::from_str(&raw_b[..32]).unwrap();
553
554 let kmer_x_32: Kmer<Dna, 32, u64> = kmer!("AATTGTGGGTTCGTCTGCGCCTCCGCCCTTAG", u64);
555
556 assert_eq!(kmer_ax_32.len(), 32);
557
558 assert_eq!(kmer_ax_32, kmer_bx_32);
559 assert_ne!(kmer_ax_32, kmer_x_32);
560
561 let kmer_b_64 = Kmer::<Dna, 64, u128>::from_str(raw_b).unwrap();
562 let kmer_cx_64 = Kmer::<Dna, 64, u128>::from_str(&raw_d[..64]).unwrap();
563 let kmer_dx_64 = Kmer::<Dna, 64, u128>::from_str(&raw_d[1..]).unwrap();
564
565 assert_eq!(kmer_cx_64.len(), 64);
566
567 assert_eq!(kmer_b_64, kmer_cx_64);
568 assert_ne!(kmer_b_64, kmer_dx_64);
569
570 assert_eq!(seq_c, slice_b);
573 assert_eq!(seq_c, *array_b);
574 assert_eq!(&seq_c, slice_b);
577 assert_eq!(&seq_c, array_b);
578 assert_eq!(slice_c, seq_b);
581 assert_eq!(slice_c, &seq_b);
582 assert_eq!(&slice_c, array_b);
583 assert_eq!(array_c, &seq_b);
586 assert_eq!(array_c, seq_b);
587 assert_eq!(array_c, slice_b);
588 assert_ne!(&seq_a, slice_b);
598 assert_ne!(&seq_a, array_b);
599 assert_ne!(seq_a, slice_b);
600 assert_ne!(seq_a, array_b);
601 assert_ne!(slice_a, &seq_b);
605 assert_ne!(slice_a, seq_b);
606 assert_ne!(&slice_a, array_b);
607 assert_ne!(array_a, &seq_b);
610 assert_ne!(array_a, seq_b);
611 assert_ne!(array_a, slice_b);
612 assert_ne!(seq_d, slice_b);
622 assert_ne!(seq_d, array_b);
623 assert_ne!(&seq_d, slice_b);
625 assert_ne!(&seq_d, array_b);
626 assert_ne!(slice_d, &seq_b);
629 assert_ne!(slice_d, seq_b);
630 assert_ne!(&slice_d, array_b);
631 assert_ne!(array_d, &seq_b);
634 assert_ne!(array_d, seq_b);
635
636 assert_ne!(slice_b, array_d);
637 assert_ne!(array_d, slice_b);
638 }
645}
646
647#[cfg(test)]
648#[cfg(target_arch = "wasm32")]
649mod wasm_tests {
650 use crate::prelude::*;
651 use wasm_bindgen_test::*;
652
653 #[wasm_bindgen_test]
654 fn sequence_type_equality() {
655 let raw_a = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAA";
656 let raw_b = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA";
657 let raw_c = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA";
658 let raw_d = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAAA";
659
660 assert_eq!(raw_a.len(), 63);
661 assert_eq!(raw_b.len(), 64);
662 assert_eq!(raw_d.len(), 65);
663
664 assert_eq!(raw_c, raw_b);
665 assert_eq!(raw_c, &raw_b[..]);
666
667 assert_ne!(raw_b, raw_d);
668 assert_ne!(raw_a, raw_b);
669
670 let seq_a: Seq<Dna> = raw_a.try_into().unwrap();
673 let seq_b: Seq<Dna> = raw_b.try_into().unwrap();
674 let seq_c: Seq<Dna> = raw_c.try_into().unwrap();
675 let seq_d: Seq<Dna> = raw_d.try_into().unwrap();
676
677 assert_eq!(seq_a.len(), raw_a.len());
678 assert_eq!(seq_d.len(), raw_d.len());
679
680 assert_eq!(seq_c, seq_b);
681 assert_eq!(seq_c, &seq_b);
682
683 assert_ne!(seq_a, &seq_b);
684 assert_ne!(seq_a, seq_b);
685 assert_ne!(seq_c, seq_d);
686
687 let slice_a: &SeqSlice<Dna> = &seq_a;
690 let slice_b: &SeqSlice<Dna> = &seq_b;
691 let slice_c: &SeqSlice<Dna> = &seq_c;
692 let slice_d: &SeqSlice<Dna> = &seq_d;
693
694 assert_eq!(slice_a.len(), raw_a.len());
695 assert_eq!(slice_d.len(), raw_d.len());
696
697 assert_eq!(slice_c, slice_b);
698 assert_eq!(slice_c, &slice_b[..]);
699
700 assert_ne!(slice_a, slice_b);
701 assert_ne!(slice_c, slice_d);
702 assert_ne!(slice_c, &slice_d[..]);
703
704 let array_a = dna!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAA");
707 let array_b = dna!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA");
708 let array_c: &'static SeqSlice<Dna> =
709 dna!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA");
710 let array_d: &'static SeqSlice<Dna> =
711 dna!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAAA");
712
713 assert_eq!(array_a.len(), raw_a.len());
714 assert_eq!(array_d.len(), raw_d.len());
715
716 assert_eq!(array_c, array_b);
717
718 assert_ne!(array_a, array_b);
719 assert_ne!(array_c, array_d);
720
721 assert_eq!(seq_c, slice_b);
722 assert_eq!(seq_c, *array_b);
723
724 assert_eq!(&seq_c, slice_b);
725 assert_eq!(&seq_c, array_b);
726
727 assert_eq!(slice_c, seq_b);
728 assert_eq!(slice_c, &seq_b);
729 assert_eq!(&slice_c, array_b);
730
731 assert_eq!(array_c, &seq_b);
732 assert_eq!(array_c, seq_b);
733 assert_eq!(array_c, slice_b);
734 assert_ne!(&seq_a, slice_b);
737 assert_ne!(&seq_a, array_b);
738 assert_ne!(seq_a, slice_b);
739 assert_ne!(seq_a, array_b);
740 assert_ne!(slice_a, &seq_b);
741 assert_ne!(slice_a, seq_b);
742 assert_ne!(&slice_a, array_b);
743
744 assert_ne!(array_a, &seq_b);
745 assert_ne!(array_a, seq_b);
746 assert_ne!(array_a, slice_b);
747 assert_ne!(seq_d, slice_b);
750 assert_ne!(seq_d, array_b);
751 assert_ne!(&seq_d, slice_b);
752 assert_ne!(&seq_d, array_b);
753
754 assert_ne!(slice_d, &seq_b);
755 assert_ne!(slice_d, seq_b);
756 assert_ne!(&slice_d, array_b);
757
758 assert_ne!(array_d, &seq_b);
759 assert_ne!(array_d, seq_b);
760
761 assert_ne!(slice_b, array_d);
762 assert_ne!(array_d, slice_b);
763 }
764
765 #[wasm_bindgen_test]
766 fn wasm_kmers() {
767 let raw_b = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAA";
769 let raw_d = "AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAGTACTATAGGACGATCAGCACCATAAGAACAAAA";
771
772 let kmer_ax_32: Kmer<Dna, 32, u64> = kmer!("AATTGTGGGTTCGTCTGCGGCTCCGCCCTTAG", u64);
773 let kmer_bx_32 = Kmer::<Dna, 32, u64>::from_str(&raw_b[..32]).unwrap();
774
775 let kmer_x_32: Kmer<Dna, 32, u64> = kmer!("AATTGTGGGTTCGTCTGCGCCTCCGCCCTTAG", u64);
776
777 assert_eq!(kmer_ax_32.len(), 32);
778
779 assert_eq!(kmer_ax_32, kmer_bx_32);
780 assert_ne!(kmer_ax_32, kmer_x_32);
781
782 let kmer_b_64 = Kmer::<Dna, 64, u128>::from_str(&raw_b).unwrap();
783 let kmer_cx_64 = Kmer::<Dna, 64, u128>::from_str(&raw_d[..64]).unwrap();
784 let kmer_dx_64 = Kmer::<Dna, 64, u128>::from_str(&raw_d[1..]).unwrap();
785
786 assert_eq!(kmer_cx_64.len(), 64);
787
788 assert_eq!(kmer_b_64, kmer_cx_64);
789 assert_ne!(kmer_b_64, kmer_dx_64);
790 }
791
792 }