use std::ffi::{CStr, CString};
use std::fmt;
use std::os::raw::*;
use xplm_sys;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Feature {
name: String,
}
impl Feature {
pub fn name(&self) -> &str {
&self.name
}
pub fn enabled(&self) -> bool {
let name_c = CString::new(&*self.name).unwrap();
let enabled = unsafe { xplm_sys::XPLMIsFeatureEnabled(name_c.as_ptr()) };
enabled == 1
}
pub fn set_enabled(&self, enable: bool) {
let name_c = CString::new(&*self.name).unwrap();
unsafe { xplm_sys::XPLMEnableFeature(name_c.as_ptr(), enable as c_int) }
}
}
impl fmt::Display for Feature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)
}
}
pub fn find_feature<S: Into<String>>(name: S) -> Option<Feature> {
match CString::new(name.into()) {
Ok(name) => {
let has_feature = unsafe { xplm_sys::XPLMHasFeature(name.as_ptr()) };
if has_feature == 1 {
Some(Feature {
name: name.into_string().unwrap(),
})
} else {
None
}
}
Err(_) => None,
}
}
pub fn all_features() -> Vec<Feature> {
let mut features = Vec::new();
let features_ptr: *mut _ = &mut features;
unsafe {
xplm_sys::XPLMEnumerateFeatures(Some(feature_callback), features_ptr as *mut c_void);
}
features
}
unsafe extern "C" fn feature_callback(feature: *const c_char, refcon: *mut c_void) {
let features = refcon as *mut Vec<Feature>;
let name = CStr::from_ptr(feature);
if let Ok(name) = name.to_str() {
let new_feature = Feature {
name: name.to_owned(),
};
(*features).push(new_feature);
}
}