rsbullet 0.3.10

Compiles bullet3 and exposes rust bindings to the C API
Documentation
use anyhow::Result;
use std::fs::File;
use std::io::{BufRead, BufReader, Read};
use std::path::PathBuf;
use structopt::StructOpt;

/// A tool to view logging files created by RuBullet, PyBullet or Bullet3.
#[derive(StructOpt, Debug)]
#[structopt(name = "dump_log")]
struct Arguments {
    /// Logging file
    #[structopt(parse(from_os_str))]
    file: PathBuf,
}
fn calc_size<'a>(fmt: &str) -> usize {
    let mut size = 0;
    for c in fmt.chars() {
        size += match c {
            'I' | 'i' | 'f' => 4,
            'B' => 1,
            _ => {
                panic!("can not determine data type")
            }
        };
    }
    size
}
fn main() -> Result<()> {
    let args: Arguments = Arguments::from_args();
    let file = File::open(args.file.clone())?;
    println!("Opened");
    println!("{:?}", args.file);
    let mut reader = BufReader::new(file);
    let mut key_buf = String::new();
    reader
        .read_line(&mut key_buf)
        .expect("error while reading file");
    let keys: Vec<&str> = key_buf.strip_suffix("\n").unwrap().split(",").collect();
    let mut fmt_buf = String::new();
    reader
        .read_line(&mut fmt_buf)
        .expect("error while reading file");
    let fmt = fmt_buf.strip_suffix("\n").unwrap();
    let sz = calc_size(fmt);
    let ncols = fmt.len();

    let verbose = true;
    if verbose {
        println!("Keys:");
        println!("{:?}", keys);
        println!("Format:");
        println!("{}", fmt);
        println!("Size:");
        println!("{:?}", sz);
        println!("Columns:");
        println!("{}", ncols);
    }
    let mut chunk_index = 0;
    loop {
        let mut check_buf = [0_u8; 2];
        match reader.read_exact(&mut check_buf) {
            Ok(_) => {}
            Err(_) => {
                return Ok(());
            }
        }
        assert_eq!(
            &check_buf,
            &[170_u8, 187_u8],
            "Error, expected aabb terminal"
        );
        println!("chunk # {}", chunk_index);
        chunk_index += 1;
        for (index, data_type) in fmt.chars().enumerate() {
            match data_type {
                'I' => {
                    let mut integer_buf = [0_u8; 4];
                    reader.read_exact(&mut integer_buf).unwrap();
                    let integer = u32::from_le_bytes(integer_buf);
                    if verbose {
                        println!("    {} = {}", keys[index], integer);
                    }
                }
                'i' => {
                    let mut integer_buf = [0_u8; 4];
                    reader.read_exact(&mut integer_buf).unwrap();
                    let integer = i32::from_le_bytes(integer_buf);
                    if verbose {
                        println!("    {} = {}", keys[index], integer);
                    }
                }
                'f' => {
                    let mut float_buf = [0_u8; 4];
                    reader.read_exact(&mut float_buf).unwrap();
                    let float = f32::from_le_bytes(float_buf);
                    if verbose {
                        println!("    {} = {}", keys[index], float);
                    }
                }
                'B' => {
                    let mut char_buf = [0_u8; 1];
                    reader.read_exact(&mut char_buf).unwrap();
                    let char = i8::from_le_bytes(char_buf);
                    if verbose {
                        println!("    {} = {}", keys[index], char);
                    }
                }

                _ => {
                    panic!("can not determine data type")
                }
            }
        }
    }
}