use crate::data::{
ByteValidator,
arbitrary::{ArbitrarySpecs, ByteSet, ByteSpecs, Case, StringSpecs},
fasta::generic::{Fasta, FastaAnnot},
};
use arbitrary::{Arbitrary, Result, Unstructured};
impl<'a, S> Arbitrary<'a> for Fasta<S>
where
S: Arbitrary<'a>,
{
#[inline]
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let header = String::arbitrary(u)?.replace('>', " ");
let sequence = S::arbitrary(u)?;
Ok(Fasta { header, sequence })
}
}
impl<'a, M, S> Arbitrary<'a> for FastaAnnot<M, S>
where
M: Arbitrary<'a>,
S: Arbitrary<'a>,
{
#[inline]
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let header = String::arbitrary(u)?.replace('>', " ");
let sequence = S::arbitrary(u)?;
let annot = M::arbitrary(u)?;
Ok(FastaAnnot { header, sequence, annot })
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug, Default)]
pub struct FastaSpecs<S> {
pub header_specs: StringSpecs,
pub sequence_specs: S,
}
impl<S> FastaSpecs<S>
where
S: From<ByteSpecs>,
{
#[inline]
#[must_use]
pub fn parsable_fasta() -> Self {
const BYTE_SET: ByteSet = ByteSet::Custom(
&ByteValidator::none()
.add_range(0..=127)
.remove(b"\n>")
.generate_alphabet::<126>(),
);
Self {
header_specs: StringSpecs {
set: BYTE_SET,
case: Case::Any,
},
sequence_specs: ByteSpecs {
set: BYTE_SET,
case: Case::Any,
}
.into(),
}
}
}
impl<'a, S> ArbitrarySpecs<'a> for FastaSpecs<S>
where
S: ArbitrarySpecs<'a>,
{
type Output = Fasta<S::Output>;
#[inline]
fn make_arbitrary(&self, u: &mut Unstructured<'a>) -> Result<Self::Output> {
let header = self.header_specs.make_arbitrary(u)?;
let sequence = self.sequence_specs.make_arbitrary(u)?;
Ok(Fasta { header, sequence })
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug, Default)]
pub struct FastaAnnotSpecs<M, S> {
pub header_specs: StringSpecs,
pub sequence_specs: S,
pub metadata_specs: M,
}
impl<'a, M, S> ArbitrarySpecs<'a> for FastaAnnotSpecs<M, S>
where
S: ArbitrarySpecs<'a>,
M: ArbitrarySpecs<'a>,
{
type Output = FastaAnnot<M::Output, S::Output>;
#[inline]
fn make_arbitrary(&self, u: &mut Unstructured<'a>) -> Result<Self::Output> {
let header = self.header_specs.make_arbitrary(u)?;
let sequence = self.sequence_specs.make_arbitrary(u)?;
let annot = self.metadata_specs.make_arbitrary(u)?;
Ok(FastaAnnot { header, sequence, annot })
}
}