1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::fmt::Display;
use std::hash::Hash;
use std::str::FromStr;
use crate::Seq;
use crate::error::ParseSymbolError;
/// A sequence element; either [`Nuc`](crate::Nuc), [`AmbiNuc`](crate::AmbiNuc),
/// [`Amino`](crate::Amino) or [`AmbiAmino`](crate::AmbiAmino).
pub trait Symbol:
'static
+ Clone
+ Copy
+ Default
+ Display
+ std::fmt::Debug
+ FromStr<Err = ParseSymbolError>
+ AsRef<Self>
+ AsMut<Self>
+ PartialEq
+ Eq
+ PartialOrd
+ Ord
+ PartialEq<Self::Concrete>
+ PartialOrd<Self::Concrete>
+ PartialEq<Self::Ambiguous>
+ PartialOrd<Self::Ambiguous>
+ Into<Self::Ambiguous>
+ TryInto<Self::Concrete>
+ Hash
+ sealed::Sealed
{
/// Concrete symbols, i.e. [`Nuc`](crate::Nuc) or [`Amino`](crate::Amino)
type Concrete: Symbol;
/// Ambiguous symbols, i.e. [`AmbiNuc`](crate::AmbiNuc) or [`AmbiAmino`](crate::AmbiAmino)
type Ambiguous: Symbol;
/// Return uppercase string representation
#[must_use]
fn to_str(self) -> &'static str;
/// Construct from (case-insensitive) ASCII representation
///
/// # Errors
///
/// Returns [`ParseSymbolError`] if the given byte isn't a valid (case-insensitive).
fn from_ascii(ascii: u8) -> Result<Self, ParseSymbolError>;
/// Return uppercase ASCII representation
#[must_use]
fn to_ascii(self) -> u8;
/// Construct array from literal without allocating.
///
/// This is just intended to be a convenience method for testing.
#[must_use]
#[track_caller]
fn arr<const N: usize>(literal: &[u8; N]) -> [Self; N];
/// Construct [`Seq`]-wrapped array from literal without allocating.
///
/// This is just intended to be a convenience method for testing.
#[must_use]
#[track_caller]
fn seq<const N: usize>(literal: &[u8; N]) -> Seq<[Self; N]>;
}
pub(crate) mod sealed {
pub trait Sealed: Sized {
const NAME: &str;
const EXPECTED: &str;
// I admit it's super icky that these exist yet aren't applicable to `Amino`s...
// I'm doing it this way so I don't need to have an additional `Sealed` trait for
// nucleotides show up in docs. These are an internal detail so that `DnaSlice`
// can have a blanket impl on `[impl Nucleotide]`, which makes trait inference
// nicer for users.
#[cfg(feature = "unsafe")]
fn as_ambi_nucs(_nucs: &[Self]) -> &[crate::AmbiNuc] {
unimplemented!()
}
#[cfg(feature = "unsafe")]
fn to_nucs(_nucs: &[Self]) -> Option<&[crate::Nuc]> {
unimplemented!()
}
#[cfg(feature = "unsafe")]
fn to_nucs_mut(_nucs: &mut [Self]) -> Option<&mut [crate::Nuc]> {
unimplemented!()
}
}
}