1
votes

I'm pretty new to Rust (and bio rust) and just learning so any guidance would be appreciated. I've read the small Read Example for how to read in a fasta sequence from stdin,

let mut records = fasta::Reader::new(io::stdin()).records();

but I can't figure out how to read in from a file. I've tried

let mut records = fasta::Reader::new(filename);

Where the filename is a slice and a string and I've found the from_file function trying that as well. While some of them appear to work, then when I try to parse through them with for or while loops, they always complain that they're of the wrong type. The from_file function seems to not make an iterator, but a Result reader, so I can't call the next() or collect() function on it,

let mut records = fasta::Reader::from_file(filename);
let mut nb_reads = 0;
let mut nb_bases = 0;



while let Some(Ok(record)) = records.next() {
    nb_reads += 1;
    nb_bases += record.seq().len();


    let sa = suffix_array(record.seq());

    println!("Here's the Suffix array: {:#?}", sa);

    nb_reads += 1;
    nb_bases += record.seq().len();
}

while the for loop seems to work, but the 'result' iterator doesn't have the right type so I can't pull sequences.

let mut reader = fasta::Reader::from_file(filename);
let mut nb_reads = 0;
let mut nb_bases = 0;



for result in reader {
    nb_reads += 1;
    nb_bases += result.seq().len();


    let sa = suffix_array(result.seq());

    println!("Here's the Suffix array: {:#?}", sa);

    nb_reads += 1;
    nb_bases += result.seq().len();
}

I'm stumped, but I feel like I'm close to getting it to work. Thanks!

1
You need to check if from_file returned an error before you can use it. Easiest is to just unwrap it: let mut reader = fasta::Reader::from_file(filename).unwrap();Jmb
When I add unwrap to the original as well as in the for loop I get an error saying that it has been moved after the first call. I tried to call the reference with & but it doesn't work let reader = fasta::Reader::from_file(filename).unwrap(); for result in reader.records() { nb_reads += 1; nb_bases += result.unwrap().seq().len(); let sa = suffix_array(result.unwrap().seq());Gives error here. When I don't unwrap I can't call the .seq() function on them.Ryguy

1 Answers

0
votes

I found something that works, although I'm not sure if it's an answer

fn main() {
    let args: Vec<String> = env::args().collect();
    let filename: &str = &args[1];

    
    let reader = fasta::Reader::from_file(filename).unwrap();
    let mut nb_reads = 0;
    let mut nb_bases = 0;


    
    for result in reader.records() {

        let result_data = &result.unwrap();

        nb_reads += 1;
        nb_bases += result_data.seq().len();

        println!("{:?}",result_data.id());

    }

    println!("Number of reads: {}", nb_reads);
    println!("Number of bases: {}", nb_bases);
}

It appears that you need to get the pointer of the unwrapped records in the fasta reader. I wish the documentation was a bit more helpful for beginners, but I'll leave this here for anyone else struggling. Also if you try to print the .seq() it may crash your terminal haha. Moral of the story is check your types and deal with Result types (I'll figure out how to properly unwrap them later, I know my code is far from optimal now)