use std::io::{self, Read};
use std::mem;
use std::slice;

#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
struct Configuration {
    item1: u8,
    item2: u16,
    item3: i32,
    item4: [char; 8],
}

const CONFIG_DATA: &[u8] = &[
    0xfd, // u8
    0xb4, 0x50, // u16
    0x45, 0xcd, 0x3c, 0x15, // i32
    0x71, 0x3c, 0x87, 0xff, // char
    0xe8, 0x5d, 0x20, 0xe7, // char
    0x5f, 0x38, 0x05, 0x4a, // char
    0xc4, 0x58, 0x8f, 0xdc, // char
    0x67, 0x1d, 0xb4, 0x64, // char
    0xf2, 0xc5, 0x2c, 0x15, // char
    0xd8, 0x9a, 0xae, 0x23, // char
    0x7d, 0xce, 0x4b, 0xeb, // char
];

fn read_struct<T, R: Read>(mut read: R) -> io::Result<T> {
    let num_bytes = ::std::mem::size_of::<T>();
    unsafe {
        let mut s = mem::zeroed();//mem::uninitialized();
        let buffer = slice::from_raw_parts_mut(&mut s as *mut T as *mut u8, num_bytes);
        match read.read_exact(buffer) {
            Ok(()) => Ok(s),
            Err(e) => {
                ::std::mem::forget(s);
                Err(e)
            }
        }
    }
}

//// Here is a function that can read a struct (of a POD type) from a file:
// fn read_structs<T, P: AsRef<std::path::Path>>(path: P) -> io::Result<Vec<T>> {
//     let path = path.as_ref();
//     let struct_size = ::std::mem::size_of::<T>();
//     let num_bytes = std::fs::metadata(path)?.len() as usize;
//     let num_structs = num_bytes / struct_size;
//     let mut reader = std::io::BufReader::new(std::fs::File::open(path)?);
//     let mut r = Vec::<T>::with_capacity(num_structs);
//     unsafe {
//         let buffer = slice::from_raw_parts_mut(r.as_mut_ptr() as *mut u8, num_bytes);
//         reader.read_exact(buffer)?;
//         r.set_len(num_structs);
//     }
//     Ok(r)
// }

//// If you want to read a sequence of structs from a file, you can execute read_struct multiple times or read all the file at once:
// fn read_structs<T, P: AsRef<std::path::Path>>(path: P) -> io::Result<Vec<T>> {
//     let path = path.as_ref();
//     let struct_size = ::std::mem::size_of::<T>();
//     let num_bytes = std::fs::metadata(path)?.len() as usize;
//     let num_structs = num_bytes / struct_size;
//     let mut reader = std::io::BufReader::new(std::fs::File::open(path)?);
//     let mut r = Vec::<T>::with_capacity(num_structs);
//     unsafe {
//         let buffer = slice::from_raw_parts_mut(r.as_mut_ptr() as *mut u8, num_bytes);
//         reader.read_exact(buffer)?;
//         r.set_len(num_structs);
//     }
//     Ok(r)
// }


pub fn run_main() {
    let c: io::Result<Configuration> = read_struct(CONFIG_DATA);

    println!("{:#?}", c.unwrap());
}