pub const PIXELFLOW_ABI_VERSION: u32 = 1;
pub const PIXELFLOW_PLUGIN_ENTRY_SYMBOL: &[u8] = b"pixelflow_plugin_entry_v1\0";
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PixelflowStringView {
pub ptr: *const u8,
pub len: usize,
}
impl PixelflowStringView {
#[must_use]
pub const fn from_rust_str(value: &str) -> Self {
Self {
ptr: value.as_ptr(),
len: value.len(),
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PixelflowErrorCategory {
None = 0,
Plugin = 1,
Internal = 2,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PixelflowMetadataKind {
Bool = 1,
Int = 2,
Float = 3,
String = 4,
Array = 5,
Rational = 6,
Blob = 7,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PixelflowStatus {
pub size: u32,
pub version: u32,
pub status_code: i32,
pub category: PixelflowErrorCategory,
pub error_code: PixelflowStringView,
pub message: PixelflowStringView,
pub reserved: [usize; 4],
}
impl PixelflowStatus {
#[must_use]
pub const fn ok() -> Self {
Self {
size: std::mem::size_of::<Self>() as u32,
version: PIXELFLOW_ABI_VERSION,
status_code: 0,
category: PixelflowErrorCategory::None,
error_code: PixelflowStringView::from_rust_str(""),
message: PixelflowStringView::from_rust_str(""),
reserved: [0; 4],
}
}
#[must_use]
pub const fn plugin_error(code: &'static str, message: &'static str) -> Self {
Self {
status_code: 1,
category: PixelflowErrorCategory::Plugin,
error_code: PixelflowStringView::from_rust_str(code),
message: PixelflowStringView::from_rust_str(message),
..Self::ok()
}
}
#[must_use]
pub const fn is_ok(self) -> bool {
self.status_code == 0
}
}
#[repr(C)]
pub struct PixelflowRegistrar {
_private: [u8; 0],
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct PixelflowFilterDescriptorV1 {
pub size: u32,
pub version: u32,
pub name: PixelflowStringView,
pub publisher: PixelflowStringView,
pub plugin: PixelflowStringView,
pub reserved: [usize; 4],
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PixelflowHostApiV1 {
pub size: u32,
pub version: u32,
pub register_filter: unsafe extern "C" fn(
*mut PixelflowRegistrar,
*const PixelflowFilterDescriptorV1,
) -> PixelflowStatus,
pub register_metadata_key: unsafe extern "C" fn(
*mut PixelflowRegistrar,
PixelflowStringView,
PixelflowMetadataKind,
) -> PixelflowStatus,
pub log: unsafe extern "C" fn(*mut PixelflowRegistrar, u32, PixelflowStringView),
pub reserved: [usize; 4],
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PixelflowPluginApiV1 {
pub size: u32,
pub version: u32,
pub plugin_name: unsafe extern "C" fn() -> PixelflowStringView,
pub register:
unsafe extern "C" fn(*const PixelflowHostApiV1, *mut PixelflowRegistrar) -> PixelflowStatus,
pub reserved: [usize; 5],
}
pub type PixelflowPluginEntryV1 =
unsafe extern "C" fn(*const PixelflowHostApiV1, *mut PixelflowPluginApiV1) -> PixelflowStatus;
#[cfg(test)]
mod tests {
use std::mem::{align_of, size_of};
use super::{PIXELFLOW_ABI_VERSION, PixelflowPluginApiV1, PixelflowStatus};
#[test]
fn abi_version_is_one() {
assert_eq!(PIXELFLOW_ABI_VERSION, 1);
}
#[test]
fn status_success_has_zero_code() {
assert_eq!(PixelflowStatus::ok().status_code, 0);
}
#[test]
fn plugin_api_layout_has_stable_size_and_alignment() {
assert_eq!(size_of::<PixelflowPluginApiV1>(), 64);
assert_eq!(align_of::<PixelflowPluginApiV1>(), 8);
}
}