1use std::fmt::{Debug, Display, Formatter};
5use std::fs::File;
6use std::io::Write;
7use std::path::Path;
8
9use crate::{display, LIB, OBJ};
10use anyhow::{anyhow, bail, Result};
11use binrw::io::Cursor;
12use binrw::{meta::ReadMagic, BinRead, BinWrite};
13
14#[derive(Debug)]
15pub enum Type {
16 OBJ(OBJ),
17 LIB(LIB),
18}
19
20impl Display for Type {
21 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
22 match self {
23 Self::OBJ(obj) => obj as &dyn Display,
24 Self::LIB(lib) => lib as &dyn Display,
25 }
26 .fmt(f)
27 }
28}
29
30impl display::DisplayWithOptions for Type {
31 fn fmt_with_options(&self, f: &mut Formatter, options: &display::Options) -> std::fmt::Result {
32 match self {
33 Self::OBJ(obj) => obj as &dyn display::DisplayWithOptions,
34 Self::LIB(lib) => lib as &dyn display::DisplayWithOptions,
35 }
36 .fmt_with_options(f, options)
37 }
38}
39
40pub fn read_bytes(path: &Path) -> Result<Vec<u8>> {
41 if !Path::exists(path) {
42 bail!(format!("File not found: {}", path.display()));
43 }
44
45 Ok(std::fs::read(path)?)
46}
47
48pub fn read(lib_or_obj_path: &Path) -> Result<Type> {
51 let bytes = read_bytes(lib_or_obj_path)?;
52
53 if bytes.len() < 3 {
54 bail!("File too small to contain valid PSY-Q magic number");
55 }
56
57 let mut magic: [u8; 3] = [0; 3];
58 magic.clone_from_slice(&bytes[0..3]);
59 let mut data = Cursor::new(&bytes);
60
61 match magic {
62 LIB::MAGIC => Ok(Type::LIB(LIB::read(&mut data).map_err(|e| anyhow!(e))?)),
63 OBJ::MAGIC => Ok(Type::OBJ(OBJ::read(&mut data).map_err(|e| anyhow!(e))?)),
64 _ => bail!(format!("Unrecognized magic {:?}", &bytes[0..3])),
65 }
66}
67
68pub fn read_obj(obj_path: &Path) -> Result<OBJ> {
71 let bytes = read_bytes(obj_path)?;
72 let mut data = Cursor::new(&bytes);
73 OBJ::read(&mut data).map_err(|e| anyhow!(e))
74}
75
76pub fn read_lib(lib_path: &Path) -> Result<LIB> {
79 let bytes = read_bytes(lib_path)?;
80 let mut data = Cursor::new(&bytes);
81 LIB::read(&mut data).map_err(|e| anyhow!(e))
82}
83
84pub fn write_obj(obj: &OBJ, file: &mut File) -> Result<()> {
87 let mut writer = Cursor::new(Vec::new());
88 obj.write(&mut writer).map_err(|e| anyhow!(e))?;
89 let gen = writer.into_inner();
90 file.write_all(&gen)?;
91 Ok(())
92}
93
94pub fn write_lib(lib: &LIB, file: &mut File) -> Result<()> {
97 let mut writer = Cursor::new(Vec::new());
98 lib.write(&mut writer).map_err(|e| anyhow!(e))?;
99 let gen = writer.into_inner();
100 file.write_all(&gen)?;
101 Ok(())
102}