use std::{ffi::NulError, marker::PhantomData, path::Path};
use snafu::prelude::*;
use crate::{paths::PathApi, NoSendSync};
#[derive(Snafu, Debug)]
pub enum SetAircraftError {
#[snafu(display("The passed path was absolute, but not a child of the X-Plane system root!"))]
InvalidAbsolutePath,
#[snafu(display("The passed path was not an acf file!"))]
NotAcf,
#[snafu(display("An I/O error occurred!"))]
#[snafu(context(false))]
IoError {
source: std::io::Error,
},
#[snafu(display("A path contained a NUL byte."))]
#[snafu(context(false))]
Nul {
source: NulError,
},
}
pub struct PlayerApi {
pub(crate) _phantom: NoSendSync,
}
impl PlayerApi {
pub fn reload_aircraft(&mut self) -> Result<(), SetAircraftError> {
let mut path_api = PathApi {
_phantom: PhantomData,
};
let current_acf_path = path_api.acf_path(0);
self.set_aircraft(current_acf_path)?;
Ok(())
}
pub fn set_aircraft<P: AsRef<Path>>(&mut self, file: P) -> Result<(), SetAircraftError> {
let file = file.as_ref();
let file = file.canonicalize()?;
let mut path_api = PathApi {
_phantom: PhantomData,
};
if !file.is_relative() && !file.starts_with(path_api.xplane_folder()) {
return Err(SetAircraftError::InvalidAbsolutePath);
}
if file.extension().ok_or(SetAircraftError::NotAcf)? != "acf" {
return Err(SetAircraftError::NotAcf);
}
let filename_c = std::ffi::CString::new(file.as_os_str().to_string_lossy().into_owned())?;
unsafe {
xplane_sys::XPLMSetUsersAircraft(filename_c.as_ptr());
}
Ok(())
}
pub fn place_at_airport(&mut self, airport_code: &str) -> Result<(), NulError> {
let airport_code_c = std::ffi::CString::new(airport_code)?;
unsafe {
xplane_sys::XPLMPlaceUserAtAirport(airport_code_c.as_ptr());
}
Ok(())
}
}