falco_plugin 0.5.1

High level bindings for the Falco plugin API
Documentation
use crate::FailureReason;
use falco_plugin_api::ss_plugin_rc;
use std::ffi::CString;

#[doc(hidden)]
pub trait FfiResult {
    fn status_code(&self) -> ss_plugin_rc;
    fn set_last_error(&self, lasterr: &mut CString);

    fn rc(&self, lasterr: &mut CString) -> ss_plugin_rc {
        self.set_last_error(lasterr);
        self.status_code()
    }
}

impl FfiResult for anyhow::Error {
    fn status_code(&self) -> ss_plugin_rc {
        match self.downcast_ref::<FailureReason>() {
            Some(reason) => ss_plugin_rc::from(*reason),
            None => falco_plugin_api::ss_plugin_rc_SS_PLUGIN_FAILURE,
        }
    }

    fn set_last_error(&self, lasterr: &mut CString) {
        let msg = self.to_string();

        #[cfg(debug_assertions)]
        match self.status_code() {
            falco_plugin_api::ss_plugin_rc_SS_PLUGIN_EOF => {
                log::debug!("EOF from plugin: {self}")
            }
            falco_plugin_api::ss_plugin_rc_SS_PLUGIN_TIMEOUT => {
                log::trace!("Plugin timeout: {self}")
            }
            _ => log::warn!("Plugin error: {self:#}"),
        }

        if let Ok(mut msg) = CString::new(msg.into_bytes()) {
            std::mem::swap(lasterr, &mut msg);
        }
    }
}

impl<T> FfiResult for Result<T, anyhow::Error> {
    fn status_code(&self) -> ss_plugin_rc {
        match self {
            Ok(_) => falco_plugin_api::ss_plugin_rc_SS_PLUGIN_SUCCESS,
            Err(e) => e.status_code(),
        }
    }

    fn set_last_error(&self, lasterr: &mut CString) {
        if let Err(e) = self {
            e.set_last_error(lasterr)
        }
    }
}