molconv 0.2.0

Convert between several molecular structure and trajectory file formats.
Documentation
extern crate molconv;
#[macro_use]
extern crate clap;
extern crate failure;

mod cli;

use cli::parse_args;
use failure::Error;
use std::rc::Rc;
use molconv::{Frame,TrajectoryError};
use molconv::trajectory::{Trajectory,FileMode};

fn main() -> Result<(), Error> {
    let config = parse_args()?;
    

    for (input_idx, path) in config.input.iter().enumerate() {
        print!("Reading from {}... ", path.to_str().unwrap());

        // Keep statistics on read and written frames
        let mut frames_read = 0;
        let mut frames_written = 0;

        // Create an iterator over the trajectory and filter it according to
        // cli arguments
        let traj = Trajectory::open(path.as_path(), FileMode::Read)?;
        let frame_iter = traj.into_iter()
            .filter_map(Result::ok)
            .inspect(|_| frames_read += 1)
            .skip(config.first)
            .take(config.last - config.first + 1)
            .step_by(config.stride)
            .map(|mut frame| {
                if config.indeces.len() > 0 {
                    let mut f: Frame = Rc::make_mut(&mut frame).clone();
                    f.filter_coords(&config.indeces);
                    Rc::new(f)
                } else {
                    frame
                }
            });

        // If user specified an output file, write filtered trajectories.
        // Otherwise, force iterator evaluation to collect trajectory statistics
        match &config.output {
            Some(out_path) => {
                let file_mode = if input_idx == 0 {
                    FileMode::Write
                } else {
                    FileMode::Append
                };
                let out_traj = Trajectory::open(out_path.as_path(), file_mode)?;
                frame_iter.map(|frame| {
                    frames_written += 1;
                    out_traj.write(&frame)
                }).collect::<Result<(), TrajectoryError>>()?;
                println!("{} frames.\n{} frames written.", frames_read, frames_written);
            }
            None => {
                frame_iter.for_each(drop);
                println!("{} frames.", frames_read);
            }
        }
    } 

    Ok(())
}