From 09774007965a1fcd9cfeef7eeb83f9c8117dd81b Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 13:19:30 +0800 Subject: [PATCH 01/12] feat: better ffi error impl --- float-pigment-css/src/ffi.rs | 543 ++++++++++++++++++++------------ float-pigment-forest/src/ffi.rs | 4 +- 2 files changed, 341 insertions(+), 206 deletions(-) diff --git a/float-pigment-css/src/ffi.rs b/float-pigment-css/src/ffi.rs index f0159dd..8bf2c2a 100644 --- a/float-pigment-css/src/ffi.rs +++ b/float-pigment-css/src/ffi.rs @@ -8,10 +8,8 @@ use alloc::{ vec::Vec, }; use bit_set::BitSet; -use core::{ - ffi::{c_char, CStr}, - ptr::null, -}; +use core::ffi::{c_char, CStr}; +use core::ptr::null; use hashbrown::HashMap; use crate::parser::parse_color_to_rgba; @@ -19,11 +17,13 @@ use crate::property::{Property, PropertyMeta}; use crate::sheet::borrow::{InlineRule, Selector}; use crate::typing::ImportantBitSet; +use crate::group; +use crate::parser; use crate::parser::property_value::var::{ CustomPropertyContext, CustomPropertyGetter, CustomPropertySetter, }; - -use super::{group::drop_css_extension, *}; +use crate::sheet; +use group::drop_css_extension; use parser::Warning; use sheet::borrow::{Array, StyleSheet}; use sheet::str_store::StrRef; @@ -31,120 +31,176 @@ use sheet::str_store::StrRef; #[cfg(feature = "deserialize")] use sheet::borrow::de_static_ref_zero_copy_env; +macro_rules! check_null { + (($($arg:expr),+ $(,)?), $default: expr) => { + if $( $arg.is_null() )||+ { + return FfiResult::error(FfiErrorCode::NullPointer, $default); + } + }; +} + +macro_rules! raw_ptr_as_mut_ref { + ($from:expr, $type:ty) => { + unsafe { &mut *($from as *mut $type) } + }; +} + +type RawMutPtr = *mut (); + +pub type NullPtr = *const (); + +pub type StyleSheetResourcePtr = RawMutPtr; + +pub type BufferPtr = *mut u8; +#[repr(C)] +pub enum FfiErrorCode { + None, + NullPointer, + InvalidPath, + Unknown, +} + #[repr(C)] -pub struct StyleSheetResourcePtr { - ptr: *mut (), +pub struct FfiResult { + value: T, + err: FfiErrorCode, } + +impl FfiResult { + fn ok(value: T) -> Self { + Self { + err: FfiErrorCode::None, + value, + } + } + fn error(err: FfiErrorCode, default: T) -> Self { + Self { + err, + value: default, + } + } +} + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn style_sheet_resource_new() -> StyleSheetResourcePtr { - let res = Box::into_raw(Box::new(group::StyleSheetResource::new())); - StyleSheetResourcePtr { - ptr: res as *mut (), - } +#[export_name = "FPStyleSheetResourceNew"] +pub unsafe extern "C" fn style_sheet_resource_new() -> FfiResult { + FfiResult::ok(Box::into_raw(Box::new(group::StyleSheetResource::new())) as StyleSheetResourcePtr) } /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn style_sheet_resource_free(this: &mut StyleSheetResourcePtr) { - drop(Box::from_raw(this.ptr as *mut StyleSheetResource)); - this.ptr = core::ptr::null_mut(); +#[export_name = "FPStyleSheetResourceFree"] +pub unsafe extern "C" fn style_sheet_resource_free( + this: StyleSheetResourcePtr, +) -> FfiResult { + check_null!((this), null()); + drop(Box::from_raw(this as *mut group::StyleSheetResource)); + FfiResult::ok(null()) } /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetResourceAddTagNamePrefix"] pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( - this: &mut StyleSheetResourcePtr, + this: StyleSheetResourcePtr, path: *const c_char, prefix: *const c_char, -) { - let res = &mut *(this.ptr as *mut StyleSheetResource); +) -> FfiResult { + check_null!((this, path, prefix), null()); + let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let prefix = CStr::from_ptr(prefix).to_string_lossy(); res.add_tag_name_prefix(&path, &prefix); + FfiResult::ok(null()) } /// # Safety /// #[cfg(all(feature = "serialize", feature = "serialize_json"))] -#[no_mangle] +#[export_name = "FPStyleSheetResourceSerializeJson"] pub unsafe extern "C" fn style_sheet_resource_serialize_json( - this: &mut StyleSheetResourcePtr, + this: StyleSheetResourcePtr, path: *const c_char, ret_buffer_len: &mut usize, -) -> *mut u8 { - let res = &mut *(this.ptr as *mut StyleSheetResource); +) -> FfiResult { + check_null!((this, path), core::ptr::null_mut()); + let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let serial = res.serialize_json(&path).unwrap_or_default(); *ret_buffer_len = serial.len(); let ret = Box::into_raw(serial.into_boxed_str()); - ret as *mut u8 + FfiResult::ok(ret as BufferPtr) } /// # Safety /// #[cfg(feature = "serialize")] -#[no_mangle] +#[export_name = "FPStyleSheetResourceSerializeBincode"] pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( - this: &mut StyleSheetResourcePtr, + this: StyleSheetResourcePtr, path: *const c_char, ret_buffer_len: &mut usize, -) -> *mut u8 { - let res = &mut *(this.ptr as *mut StyleSheetResource); +) -> FfiResult { + check_null!((this, path), core::ptr::null_mut()); + let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let serial = res.serialize_bincode(&path).unwrap_or_default(); *ret_buffer_len = serial.len(); let ret = Box::into_raw(serial.into_boxed_slice()); - ret as *mut u8 + FfiResult::ok(ret as BufferPtr) } /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetResourceAddSource"] pub unsafe extern "C" fn style_sheet_resource_add_source( - this: &mut StyleSheetResourcePtr, + this: StyleSheetResourcePtr, path: *const c_char, source: *const c_char, warnings: *mut *mut Array, -) { - let res = &mut *(this.ptr as *mut StyleSheetResource); +) -> FfiResult { + check_null!((this, path, source), null()); + let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let source = CStr::from_ptr(source).to_string_lossy(); let w = res.add_source(&path, &source); if !warnings.is_null() { *warnings = Box::into_raw(Box::new(w.into())); } + FfiResult::ok(null()) } /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetResourceAddSourceWithHooks"] pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( - this: &mut StyleSheetResourcePtr, + this: StyleSheetResourcePtr, hooks: parser::hooks::CParserHooks, path: *const c_char, source: *const c_char, warnings: *mut *mut Array, -) { - let res = &mut *(this.ptr as *mut StyleSheetResource); +) -> FfiResult { + check_null!((this, path, source), null()); + let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let source = CStr::from_ptr(source).to_string_lossy(); let w = res.add_source_with_hooks(&path, &source, Some(Box::new(hooks))); if !warnings.is_null() { *warnings = Box::into_raw(Box::new(w.into())); } + FfiResult::ok(null()) } + /// # Safety /// #[cfg(feature = "deserialize")] -#[no_mangle] +#[export_name = "FPStyleSheetResourceAddBincode"] pub unsafe extern "C" fn style_sheet_resource_add_bincode( - this: &mut StyleSheetResourcePtr, + this: StyleSheetResourcePtr, path: *const c_char, - buffer_ptr: *mut u8, + buffer_ptr: BufferPtr, buffer_len: usize, - drop_fn: Option, - drop_args: *mut (), + drop_fn: Option, + drop_args: RawMutPtr, warnings: *mut *mut Array, -) { - let res = &mut *(this.ptr as *mut StyleSheetResource); +) -> FfiResult { + check_null!((this, path, buffer_ptr), null()); + let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let bincode: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); let path = CStr::from_ptr(path).to_string_lossy(); let w = res.add_bincode_zero_copy(&path, bincode, move || { @@ -155,119 +211,146 @@ pub unsafe extern "C" fn style_sheet_resource_add_bincode( if !warnings.is_null() { *warnings = Box::into_raw(Box::new(w.into())); } + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetResourceDirectDependencies"] pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( - this: &mut StyleSheetResourcePtr, + this: StyleSheetResourcePtr, path: *const c_char, -) -> *mut Array { - let res = &mut *(this.ptr as *mut StyleSheetResource); +) -> FfiResult<*mut Array> { + check_null!((this, path), core::ptr::null_mut()); + let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let deps = res.direct_dependencies(&path); let deps: Vec<_> = deps.into_iter().map(StrRef::from).collect(); - Box::into_raw(Box::new(deps.into())) + FfiResult::ok(Box::into_raw(Box::new(deps.into()))) } + /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetResourceGenerateImportIndex"] pub unsafe extern "C" fn style_sheet_resource_generate_import_index( - this: &mut StyleSheetResourcePtr, -) -> StyleSheetImportIndexPtr { - let res = &mut *(this.ptr as *mut StyleSheetResource); - let ii = Box::into_raw(Box::new(res.generate_import_indexes())); - let style_sheet_map: Box = Box::default(); - StyleSheetImportIndexPtr { - ptr: ii as *mut (), - map: Box::into_raw(style_sheet_map) as *mut _, - } + this: StyleSheetResourcePtr, +) -> FfiResult { + check_null!((this), core::ptr::null_mut()); + let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); + FfiResult::ok( + StyleSheetImportIndex { + inner: res.generate_import_indexes(), + map: StyleSheetMap::default(), + } + .to_ptr(), + ) } type StyleSheetMap = HashMap; -#[repr(C)] -pub struct StyleSheetImportIndexPtr { - ptr: *mut (), - map: *mut (), +pub type StyleSheetImportIndexPtr = RawMutPtr; + +struct StyleSheetImportIndex { + inner: group::StyleSheetImportIndex, + map: StyleSheetMap, } + +impl StyleSheetImportIndex { + fn to_ptr(self) -> StyleSheetImportIndexPtr { + Box::into_raw(Box::new(self)) as StyleSheetImportIndexPtr + } +} + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn style_sheet_import_index_new() -> StyleSheetImportIndexPtr { - let ii = Box::into_raw(Box::new(StyleSheetImportIndex::new())); - let style_sheet_map: Box = Box::default(); - StyleSheetImportIndexPtr { - ptr: ii as *mut (), - map: Box::into_raw(style_sheet_map) as *mut _, - } +#[export_name = "FPStyleSheetImportIndexNew"] +pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult { + FfiResult::ok( + StyleSheetImportIndex { + inner: group::StyleSheetImportIndex::new(), + map: StyleSheetMap::default(), + } + .to_ptr(), + ) } + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn style_sheet_import_index_free(this: &mut StyleSheetImportIndexPtr) { - drop(Box::from_raw(this.ptr as *mut StyleSheetImportIndex)); - this.ptr = core::ptr::null_mut(); - drop(Box::from_raw(this.map as *mut StyleSheetMap)); - this.map = core::ptr::null_mut(); +#[export_name = "FPStyleSheetImportIndexFree"] +pub unsafe extern "C" fn style_sheet_import_index_free( + this: StyleSheetImportIndexPtr, +) -> FfiResult { + check_null!((this), null()); + drop(Box::from_raw(this as *mut StyleSheetImportIndex)); + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexQueryAndMarkDependencies"] pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( - this: &mut StyleSheetImportIndexPtr, + this: StyleSheetImportIndexPtr, path: *const c_char, -) -> *mut Array { - let ii = &mut *(this.ptr as *mut StyleSheetImportIndex); +) -> FfiResult<*mut Array> { + check_null!((this, path), core::ptr::null_mut()); + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); - let deps = ii.query_and_mark_dependencies(&path); + let deps = style_sheet_import_index + .inner + .query_and_mark_dependencies(&path); let deps: Vec<_> = deps.into_iter().map(StrRef::from).collect(); - Box::into_raw(Box::new(deps.into())) + FfiResult::ok(Box::into_raw(Box::new(deps.into()))) } + /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexListDependencies"] pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( - this: &mut StyleSheetImportIndexPtr, + this: StyleSheetImportIndexPtr, path: *const c_char, -) -> *mut Array { - let ii = &mut *(this.ptr as *mut StyleSheetImportIndex); +) -> FfiResult<*mut Array> { + check_null!((this, path), core::ptr::null_mut()); + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); - let deps = ii.list_dependencies(&path, true); + let deps = style_sheet_import_index + .inner + .list_dependencies(&path, true); let deps: Vec<_> = deps.into_iter().map(StrRef::from).collect(); - Box::into_raw(Box::new(deps.into())) + FfiResult::ok(Box::into_raw(Box::new(deps.into()))) } + /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexListDependency"] pub unsafe extern "C" fn style_sheet_import_index_list_dependency( - this: &mut StyleSheetImportIndexPtr, + this: StyleSheetImportIndexPtr, path: *const c_char, -) -> *mut Array { - if path.is_null() { - panic!("style_sheet_import_index_list_dependency: path is null!") - } - let ii = &mut *(this.ptr as *mut StyleSheetImportIndex); +) -> FfiResult<*mut Array> { + check_null!((this, path), core::ptr::null_mut()); + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); - let deps = ii.list_dependencies(&path, false); + let deps = style_sheet_import_index + .inner + .list_dependencies(&path, false); let deps: Vec<_> = deps.into_iter().map(StrRef::from).collect(); - Box::into_raw(Box::new(deps.into())) + FfiResult::ok(Box::into_raw(Box::new(deps.into()))) } /// # Safety /// #[cfg(feature = "deserialize")] -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexAddBincode"] pub unsafe extern "C" fn style_sheet_import_index_add_bincode( - this: &mut StyleSheetImportIndexPtr, + this: StyleSheetImportIndexPtr, path: *const c_char, - buffer_ptr: *mut u8, + buffer_ptr: BufferPtr, buffer_len: usize, drop_fn: Option, drop_args: *mut (), warnings: *mut *mut Array, -) { +) -> FfiResult { use float_pigment_consistent_bincode::Options; use parser::WarningKind; + check_null!((this, path, buffer_ptr), null()); let path = CStr::from_ptr(path).to_string_lossy(); let path: &str = &path; let sheet = de_static_ref_zero_copy_env( @@ -305,148 +388,181 @@ pub unsafe extern "C" fn style_sheet_import_index_add_bincode( }, ); let path = drop_css_extension(path).into(); - let map = &mut *(this.map as *mut StyleSheetMap); - map.insert(path, sheet); + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); + style_sheet_import_index.map.insert(path, sheet); + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexRemoveBincode"] pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( - this: &mut StyleSheetImportIndexPtr, + this: StyleSheetImportIndexPtr, path: *const c_char, -) { +) -> FfiResult { + check_null!((this, path), null()); let path = CStr::from_ptr(path).to_string_lossy(); let path: &str = &path; let path = drop_css_extension(path); - let map = &mut *(this.map as *mut StyleSheetMap); - map.remove(path); + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); + style_sheet_import_index.map.remove(path); + FfiResult::ok(null()) } /// # Safety /// -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexGetStyleSheet"] pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( - this: &mut StyleSheetImportIndexPtr, + this: StyleSheetImportIndexPtr, path: *const StrRef, -) -> *mut StyleSheet { +) -> FfiResult<*mut StyleSheet> { + check_null!((this, path), core::ptr::null_mut()); let path = (*path).as_str(); let path = drop_css_extension(path); - let map = &mut *(this.map as *mut StyleSheetMap); - match map.get_mut(path) { - None => core::ptr::null_mut(), - Some(x) => x as *mut _, + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); + match style_sheet_import_index.map.get_mut(path) { + None => FfiResult::error(FfiErrorCode::InvalidPath, core::ptr::null_mut()), + Some(x) => FfiResult::ok(x as *mut StyleSheet), } } /// # Safety /// #[cfg(all(feature = "serialize", feature = "serialize_json"))] -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexSerializeJson"] pub unsafe extern "C" fn style_sheet_import_index_serialize_json( - this: &mut StyleSheetImportIndexPtr, + this: StyleSheetImportIndexPtr, ret_buffer_len: &mut usize, -) -> *mut u8 { - let ii = &mut *(this.ptr as *mut StyleSheetImportIndex); - let serial = ii.serialize_json(); +) -> FfiResult { + check_null!((this), core::ptr::null_mut()); + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); + let serial = style_sheet_import_index.inner.serialize_json(); *ret_buffer_len = serial.len(); let ret = Box::into_raw(serial.into_boxed_str()); - ret as *mut u8 + FfiResult::ok(ret as BufferPtr) } /// # Safety /// #[cfg(feature = "serialize")] -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexSerializeBincode"] pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( - this: &mut StyleSheetImportIndexPtr, + this: StyleSheetImportIndexPtr, ret_buffer_len: &mut usize, -) -> *mut u8 { - let ii = &mut *(this.ptr as *mut StyleSheetImportIndex); - let serial = ii.serialize_bincode(); +) -> FfiResult { + check_null!((this), core::ptr::null_mut()); + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); + let serial = style_sheet_import_index.inner.serialize_bincode(); *ret_buffer_len = serial.len(); let ret = Box::into_raw(serial.into_boxed_slice()); - ret as *mut u8 + FfiResult::ok(ret as BufferPtr) } /// # Safety /// #[cfg(all(feature = "deserialize", feature = "deserialize_json"))] -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexDeserializeJson"] pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( json: *const c_char, -) -> StyleSheetImportIndexPtr { +) -> FfiResult { + check_null!((json), core::ptr::null_mut()); let json = CStr::from_ptr(json).to_string_lossy(); - let ii = StyleSheetImportIndex::deserialize_json(&json); - let ii = Box::into_raw(Box::new(ii)); - StyleSheetImportIndexPtr { - ptr: ii as *mut (), - map: Box::into_raw(Box::new(StyleSheetMap::default())) as *mut _, - } + FfiResult::ok( + StyleSheetImportIndex { + inner: group::StyleSheetImportIndex::deserialize_json(&json), + map: StyleSheetMap::default(), + } + .to_ptr(), + ) } /// # Safety /// #[cfg(feature = "deserialize")] -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexDeserializeBincode"] pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( - buffer_ptr: *mut u8, + buffer_ptr: BufferPtr, buffer_len: usize, - drop_fn: Option, - drop_args: *mut (), -) -> StyleSheetImportIndexPtr { + drop_fn: Option, + drop_args: RawMutPtr, +) -> FfiResult { + check_null!((buffer_ptr), core::ptr::null_mut()); let bincode: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); - let ii = StyleSheetImportIndex::deserialize_bincode_zero_copy(bincode, move || { - if let Some(drop_fn) = drop_fn { - drop_fn(drop_args); + FfiResult::ok( + StyleSheetImportIndex { + inner: group::StyleSheetImportIndex::deserialize_bincode_zero_copy( + bincode, + move || { + if let Some(drop_fn) = drop_fn { + drop_fn(drop_args); + } + }, + ), + map: StyleSheetMap::default(), } - }); - let ii = Box::into_raw(Box::new(ii)); - let style_sheet_map: Box = Box::default(); - StyleSheetImportIndexPtr { - ptr: ii as *mut (), - map: Box::into_raw(style_sheet_map) as *mut _, - } + .to_ptr(), + ) } /// # Safety /// #[cfg(feature = "deserialize")] -#[no_mangle] +#[export_name = "FPStyleSheetImportIndexMergeBincode"] pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( - this: &mut StyleSheetImportIndexPtr, - buffer_ptr: *mut u8, + this: StyleSheetImportIndexPtr, + buffer_ptr: BufferPtr, buffer_len: usize, drop_fn: Option, drop_args: *mut (), -) { - let ii = &mut *(this.ptr as *mut StyleSheetImportIndex); +) -> FfiResult { + check_null!((this, buffer_ptr), null()); + let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let bincode: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); - ii.merge_bincode_zero_copy(bincode, move || { - if let Some(drop_fn) = drop_fn { - drop_fn(drop_args); - } - }); + style_sheet_import_index + .inner + .merge_bincode_zero_copy(bincode, move || { + if let Some(drop_fn) = drop_fn { + drop_fn(drop_args); + } + }); + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) { +#[export_name = "FPBufferFree"] +pub unsafe extern "C" fn buffer_free( + buffer_ptr: BufferPtr, + buffer_len: usize, +) -> FfiResult { + check_null!((buffer_ptr), null()); let x: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); drop(Box::from_raw(x)); + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) { +#[export_name = "FPArrayStrRefFree"] +pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) -> FfiResult { + check_null!((x), null()); drop(Box::from_raw(x)); + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn array_warning_free(warnings: *mut Array) { +#[export_name = "FPArrayWarningFree"] +pub unsafe extern "C" fn array_warning_free( + warnings: *mut Array, +) -> FfiResult { + check_null!((warnings), null()); drop(Box::from_raw(warnings)); + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] +#[export_name = "FPParseInlineStyle"] pub unsafe extern "C" fn parse_inline_style( inline_style_text_ptr: *const c_char, warnings: *mut *mut Array, -) -> *mut InlineRule { +) -> FfiResult<*mut InlineRule> { + check_null!((inline_style_text_ptr), core::ptr::null_mut()); let inline_style_text = CStr::from_ptr(inline_style_text_ptr).to_string_lossy(); let (prop, w) = parser::parse_inline_style(&inline_style_text, parser::StyleParsingDebugMode::None); @@ -474,56 +590,67 @@ pub unsafe extern "C" fn parse_inline_style( ImportantBitSet::Array(important.into_bit_vec().to_bytes().into()) }; let inline_rule = InlineRule::new(properties, important); - Box::into_raw(Box::new(inline_rule)) + FfiResult::ok(Box::into_raw(Box::new(inline_rule))) } /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) { +#[export_name = "FPInlineStyleFree"] +pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiResult { + check_null!((inline_rule), null()); drop(Box::from_raw(inline_rule)); + FfiResult::ok(null()) } /// # Safety /// -#[no_mangle] +#[export_name = "FPParseStyleSheetFromString"] pub unsafe extern "C" fn parse_style_sheet_from_string( style_text_ptr: *const c_char, -) -> *mut StyleSheet { +) -> FfiResult<*mut StyleSheet> { + check_null!((style_text_ptr), core::ptr::null_mut()); let style_text = CStr::from_ptr(style_text_ptr).to_string_lossy(); let (compiled_style_sheet, _) = parser::parse_style_sheet("string", &style_text); let style_sheet = StyleSheet::from_sheet(&compiled_style_sheet); - Box::into_raw(Box::new(style_sheet)) + FfiResult::ok(Box::into_raw(Box::new(style_sheet))) } /// # Safety /// -#[no_mangle] +#[export_name = "FPParseSelectorFromString"] pub unsafe extern "C" fn parse_selector_from_string( selector_text_ptr: *const c_char, -) -> *mut Selector { +) -> FfiResult<*mut Selector> { + check_null!((selector_text_ptr), core::ptr::null_mut()); let selector_text = CStr::from_ptr(selector_text_ptr).to_string_lossy(); let selector = Selector::from_string(&selector_text); - Box::into_raw(Box::new(selector)) + FfiResult::ok(Box::into_raw(Box::new(selector))) } /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn selector_free(selector: *mut Selector) { +#[export_name = "FPSelectorFree"] +pub unsafe extern "C" fn selector_free(selector: *mut Selector) -> FfiResult { + check_null!((selector), null()); drop(Box::from_raw(selector)); + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn style_sheet_free(style_sheet: *mut StyleSheet) { +#[export_name = "FPStyleSheetFree"] +pub unsafe extern "C" fn style_sheet_free(style_sheet: *mut StyleSheet) -> FfiResult { + check_null!((style_sheet), null()); drop(Box::from_raw(style_sheet)); + FfiResult::ok(null()) } + /// # Safety /// #[cfg(feature = "deserialize")] -#[no_mangle] +#[export_name = "FPStyleSheetBincodeVersion"] pub unsafe extern "C" fn style_sheet_bincode_version( - buffer_ptr: *mut u8, + buffer_ptr: BufferPtr, buffer_len: usize, -) -> *mut StrRef { +) -> FfiResult<*mut StrRef> { use float_pigment_consistent_bincode::Options; + check_null!((buffer_ptr), core::ptr::null_mut()); let sheet = de_static_ref_zero_copy_env( core::slice::from_raw_parts_mut(buffer_ptr, buffer_len), |s| { @@ -553,58 +680,66 @@ pub unsafe extern "C" fn style_sheet_bincode_version( StyleSheet::V1(v1) => v1.version, _ => Box::new("unknown version".into()), }; - Box::into_raw(version) + FfiResult::ok(Box::into_raw(version)) } + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn css_parser_version() -> *mut StrRef { +#[export_name = "FPCssParserVersion"] +pub unsafe extern "C" fn css_parser_version() -> FfiResult<*mut StrRef> { let version = env!("CARGO_PKG_VERSION").to_string().into(); - Box::into_raw(Box::new(version)) + FfiResult::ok(Box::into_raw(Box::new(version))) } #[repr(C)] -#[derive(Debug)] +#[derive(Debug, Default)] pub struct ColorValue { red: u8, green: u8, blue: u8, alpha: u8, } + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> ColorValue { +#[export_name = "FPParseColorFromString"] +pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiResult { + check_null!((source), ColorValue::default()); let source = CStr::from_ptr(source).to_string_lossy(); let ret = parse_color_to_rgba(&source); - ColorValue { + FfiResult::ok(ColorValue { red: ret.0, green: ret.1, blue: ret.2, alpha: ret.3, - } + }) } /// # Safety /// -#[no_mangle] +#[export_name = "FPSubstituteVariable"] pub unsafe extern "C" fn substitute_variable( expr_ptr: *const c_char, map: *mut (), getter: CustomPropertyGetter, setter: CustomPropertySetter, -) -> *const c_char { +) -> FfiResult<*const c_char> { + check_null!((expr_ptr, map), null()); let expr = CStr::from_ptr(expr_ptr).to_string_lossy(); let context = CustomPropertyContext::create(map, getter, setter); if let Some(ret) = parser::property_value::var::substitute_variable(&expr, &context) { - CString::new(ret).expect("CString new error").into_raw() - } else { - null() + if let Ok(r) = CString::new(ret) { + return FfiResult::ok(r.into_raw()); + } } + FfiResult::ok(null()) } + /// # Safety /// -#[no_mangle] -pub unsafe extern "C" fn str_free(ptr: *const c_char) { +#[export_name = "FPStrFree"] +pub unsafe extern "C" fn str_free(ptr: *const c_char) -> FfiResult { + check_null!((ptr), null()); drop(CString::from_raw(ptr as *mut _)); + FfiResult::ok(null()) } diff --git a/float-pigment-forest/src/ffi.rs b/float-pigment-forest/src/ffi.rs index ebac911..b5c357a 100644 --- a/float-pigment-forest/src/ffi.rs +++ b/float-pigment-forest/src/ffi.rs @@ -432,9 +432,9 @@ pub unsafe extern "C" fn NodeClearMeasureFunc(node: NodePtr) { /// # Safety /// #[no_mangle] -pub unsafe extern "C" fn NodeHasMeasureFunc(node: NodePtr) { +pub unsafe extern "C" fn NodeHasMeasureFunc(node: NodePtr) -> bool { let node = &*(node.ptr as *mut Node); - node.has_measure_func(); + node.has_measure_func() } /// # Safety From 174258cbf1688633a7baa88d07ff3d1d26d090b9 Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 13:50:26 +0800 Subject: [PATCH 02/12] feat: better ffi error impl --- float-pigment-css/float_pigment_css.h | 204 ++++++++++++++------------ float-pigment-css/src/ffi.rs | 77 +++++----- float-pigment-css/src/parser/hooks.rs | 15 +- 3 files changed, 167 insertions(+), 129 deletions(-) diff --git a/float-pigment-css/float_pigment_css.h b/float-pigment-css/float_pigment_css.h index 26eb317..0b984c1 100644 --- a/float-pigment-css/float_pigment_css.h +++ b/float-pigment-css/float_pigment_css.h @@ -89,6 +89,13 @@ enum class ContainKeyword { Paint, }; +enum class FfiErrorCode { + None, + NullPointer, + InvalidPath, + Unknown, +}; + enum class FontDisplay { Auto, Block, @@ -265,6 +272,14 @@ enum class WarningKind : uint32_t { InvalidEnvDefaultValue, }; +using NullPtr = const void*; + +template +struct FfiResult { + T value; + FfiErrorCode err; +}; + struct StrRef { size_t offset; size_t len; @@ -286,9 +301,7 @@ struct Warning { uint32_t end_col; }; -struct CParserHooksContext { - void *inner; -}; +using BufferPtr = uint8_t*; template struct Box { @@ -8728,6 +8741,8 @@ struct ColorValue { uint8_t alpha; }; +using CCharPtr = const char*; + struct SelectorRelationType { enum class Tag { None, @@ -9007,143 +9022,150 @@ struct StyleSheet { }; }; -struct StyleSheetImportIndexPtr { - void *ptr; - void *map; -}; +using RawMutPtr = void*; -struct StyleSheetResourcePtr { - void *ptr; +using StyleSheetImportIndexPtr = RawMutPtr; + +using StyleSheetResourcePtr = RawMutPtr; + +struct CParserHooksContext { + void *inner; }; struct CParserHooks { void (*parsed_property)(CParserHooksContext, Property*); }; +using CustomPropertyGetter = const char*(*)(void *map, const char *name); + +using CustomPropertySetter = void(*)(void *map, const char *name, const char *value); + extern "C" { -void array_str_ref_free(Array *x); +FfiResult FPArrayStrRefFree(Array *x); -void array_warning_free(Array *warnings); +FfiResult FPArrayWarningFree(Array *warnings); -void buffer_free(uint8_t *buffer_ptr, size_t buffer_len); +FfiResult FPBufferFree(BufferPtr buffer_ptr, size_t buffer_len); -StrRef *css_parser_version(); +FfiResult FPCssParserVersion(); -void generate_warning(CParserHooksContext *self, const char *message); +FfiResult FPInlineStyleFree(InlineRule *inline_rule); -void inline_style_free(InlineRule *inline_rule); +FfiResult FPParseColorFromString(CCharPtr source); -ColorValue parse_color_from_string(const char *source); +FfiResult FPParseInlineStyle(CCharPtr inline_style_text_ptr, + Array **warnings); -InlineRule *parse_inline_style(const char *inline_style_text_ptr, Array **warnings); +FfiResult FPParseSelectorFromString(CCharPtr selector_text_ptr); -Selector *parse_selector_from_string(const char *selector_text_ptr); +FfiResult FPParseStyleSheetFromString(CCharPtr style_text_ptr); -StyleSheet *parse_style_sheet_from_string(const char *style_text_ptr); +FfiResult FPSelectorFree(Selector *selector); -void selector_free(Selector *selector); +FfiResult FPStrFree(CCharPtr ptr); -void str_free(const char *ptr); +FfiResult FPStyleSheetBincodeVersion(BufferPtr buffer_ptr, size_t buffer_len); -size_t str_len(const StrRef *self); +FfiResult FPStyleSheetFree(StyleSheet *style_sheet); -const uint8_t *str_ptr(const StrRef *self); +FfiResult FPStyleSheetImportIndexAddBincode(StyleSheetImportIndexPtr this_, + CCharPtr path, + BufferPtr buffer_ptr, + size_t buffer_len, + void (*drop_fn)(RawMutPtr), + RawMutPtr drop_args, + Array **warnings); -StrRef *style_sheet_bincode_version(uint8_t *buffer_ptr, size_t buffer_len); +FfiResult FPStyleSheetImportIndexDeserializeBincode(BufferPtr buffer_ptr, + size_t buffer_len, + void (*drop_fn)(RawMutPtr), + RawMutPtr drop_args); -void style_sheet_free(StyleSheet *style_sheet); +FfiResult FPStyleSheetImportIndexDeserializeJson(CCharPtr json); -void style_sheet_import_index_add_bincode(StyleSheetImportIndexPtr *this_, - const char *path, - uint8_t *buffer_ptr, - size_t buffer_len, - void (*drop_fn)(void*), - void *drop_args, - Array **warnings); +FfiResult FPStyleSheetImportIndexFree(StyleSheetImportIndexPtr this_); -StyleSheetImportIndexPtr style_sheet_import_index_deserialize_bincode(uint8_t *buffer_ptr, - size_t buffer_len, - void (*drop_fn)(void*), - void *drop_args); +FfiResult FPStyleSheetImportIndexGetStyleSheet(StyleSheetImportIndexPtr this_, + CCharPtr path); -StyleSheetImportIndexPtr style_sheet_import_index_deserialize_json(const char *json); +FfiResult*> FPStyleSheetImportIndexListDependencies(StyleSheetImportIndexPtr this_, + CCharPtr path); -void style_sheet_import_index_free(StyleSheetImportIndexPtr *this_); +FfiResult*> FPStyleSheetImportIndexListDependency(StyleSheetImportIndexPtr this_, + CCharPtr path); -StyleSheet *style_sheet_import_index_get_style_sheet(StyleSheetImportIndexPtr *this_, - const StrRef *path); +FfiResult FPStyleSheetImportIndexMergeBincode(StyleSheetImportIndexPtr this_, + BufferPtr buffer_ptr, + size_t buffer_len, + void (*drop_fn)(void*), + void *drop_args); -Array *style_sheet_import_index_list_dependencies(StyleSheetImportIndexPtr *this_, - const char *path); +FfiResult FPStyleSheetImportIndexNew(); -Array *style_sheet_import_index_list_dependency(StyleSheetImportIndexPtr *this_, - const char *path); +FfiResult*> FPStyleSheetImportIndexQueryAndMarkDependencies(StyleSheetImportIndexPtr this_, + CCharPtr path); -void style_sheet_import_index_merge_bincode(StyleSheetImportIndexPtr *this_, - uint8_t *buffer_ptr, - size_t buffer_len, - void (*drop_fn)(void*), - void *drop_args); +FfiResult FPStyleSheetImportIndexRemoveBincode(StyleSheetImportIndexPtr this_, + CCharPtr path); -StyleSheetImportIndexPtr style_sheet_import_index_new(); +FfiResult FPStyleSheetImportIndexSerializeBincode(StyleSheetImportIndexPtr this_, + size_t *ret_buffer_len); -Array *style_sheet_import_index_query_and_mark_dependencies(StyleSheetImportIndexPtr *this_, - const char *path); +FfiResult FPStyleSheetImportIndexSerializeJson(StyleSheetImportIndexPtr this_, + size_t *ret_buffer_len); -void style_sheet_import_index_remove_bincode(StyleSheetImportIndexPtr *this_, const char *path); +FfiResult FPStyleSheetResourceAddBincode(StyleSheetResourcePtr this_, + CCharPtr path, + BufferPtr buffer_ptr, + size_t buffer_len, + void (*drop_fn)(RawMutPtr), + RawMutPtr drop_args, + Array **warnings); -uint8_t *style_sheet_import_index_serialize_bincode(StyleSheetImportIndexPtr *this_, - size_t *ret_buffer_len); +FfiResult FPStyleSheetResourceAddSource(StyleSheetResourcePtr this_, + CCharPtr path, + CCharPtr source, + Array **warnings); -uint8_t *style_sheet_import_index_serialize_json(StyleSheetImportIndexPtr *this_, - size_t *ret_buffer_len); +FfiResult FPStyleSheetResourceAddSourceWithHooks(StyleSheetResourcePtr this_, + CParserHooks hooks, + CCharPtr path, + CCharPtr source, + Array **warnings); -void style_sheet_resource_add_bincode(StyleSheetResourcePtr *this_, - const char *path, - uint8_t *buffer_ptr, - size_t buffer_len, - void (*drop_fn)(void*), - void *drop_args, - Array **warnings); +FfiResult FPStyleSheetResourceAddTagNamePrefix(StyleSheetResourcePtr this_, + CCharPtr path, + CCharPtr prefix); -void style_sheet_resource_add_source(StyleSheetResourcePtr *this_, - const char *path, - const char *source, - Array **warnings); +FfiResult*> FPStyleSheetResourceDirectDependencies(StyleSheetResourcePtr this_, + CCharPtr path); -void style_sheet_resource_add_source_with_hooks(StyleSheetResourcePtr *this_, - CParserHooks hooks, - const char *path, - const char *source, - Array **warnings); +FfiResult FPStyleSheetResourceFree(StyleSheetResourcePtr this_); -void style_sheet_resource_add_tag_name_prefix(StyleSheetResourcePtr *this_, - const char *path, - const char *prefix); +FfiResult FPStyleSheetResourceGenerateImportIndex(StyleSheetResourcePtr this_); -Array *style_sheet_resource_direct_dependencies(StyleSheetResourcePtr *this_, - const char *path); +FfiResult FPStyleSheetResourceNew(); -void style_sheet_resource_free(StyleSheetResourcePtr *this_); +FfiResult FPStyleSheetResourceSerializeBincode(StyleSheetResourcePtr this_, + CCharPtr path, + size_t *ret_buffer_len); -StyleSheetImportIndexPtr style_sheet_resource_generate_import_index(StyleSheetResourcePtr *this_); +FfiResult FPStyleSheetResourceSerializeJson(StyleSheetResourcePtr this_, + CCharPtr path, + size_t *ret_buffer_len); -StyleSheetResourcePtr style_sheet_resource_new(); +FfiResult FPSubstituteVariable(CCharPtr expr_ptr, + RawMutPtr map, + CustomPropertyGetter getter, + CustomPropertySetter setter); -uint8_t *style_sheet_resource_serialize_bincode(StyleSheetResourcePtr *this_, - const char *path, - size_t *ret_buffer_len); +FfiResult generate_warning(CParserHooksContext *self, const char *message); -uint8_t *style_sheet_resource_serialize_json(StyleSheetResourcePtr *this_, - const char *path, - size_t *ret_buffer_len); +size_t str_len(const StrRef *self); -const char *substitute_variable(const char *expr_ptr, - void *map, - CustomPropertyGetter getter, - CustomPropertySetter setter); +const uint8_t *str_ptr(const StrRef *self); } // extern "C" diff --git a/float-pigment-css/src/ffi.rs b/float-pigment-css/src/ffi.rs index 8bf2c2a..953d915 100644 --- a/float-pigment-css/src/ffi.rs +++ b/float-pigment-css/src/ffi.rs @@ -31,6 +31,7 @@ use sheet::str_store::StrRef; #[cfg(feature = "deserialize")] use sheet::borrow::de_static_ref_zero_copy_env; +#[macro_export] macro_rules! check_null { (($($arg:expr),+ $(,)?), $default: expr) => { if $( $arg.is_null() )||+ { @@ -39,6 +40,7 @@ macro_rules! check_null { }; } +#[macro_export] macro_rules! raw_ptr_as_mut_ref { ($from:expr, $type:ty) => { unsafe { &mut *($from as *mut $type) } @@ -52,6 +54,9 @@ pub type NullPtr = *const (); pub type StyleSheetResourcePtr = RawMutPtr; pub type BufferPtr = *mut u8; + +pub type CCharPtr = *const c_char; + #[repr(C)] pub enum FfiErrorCode { None, @@ -62,18 +67,18 @@ pub enum FfiErrorCode { #[repr(C)] pub struct FfiResult { - value: T, - err: FfiErrorCode, + pub value: T, + pub err: FfiErrorCode, } impl FfiResult { - fn ok(value: T) -> Self { + pub fn ok(value: T) -> Self { Self { err: FfiErrorCode::None, value, } } - fn error(err: FfiErrorCode, default: T) -> Self { + pub fn error(err: FfiErrorCode, default: T) -> Self { Self { err, value: default, @@ -102,8 +107,8 @@ pub unsafe extern "C" fn style_sheet_resource_free( #[export_name = "FPStyleSheetResourceAddTagNamePrefix"] pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( this: StyleSheetResourcePtr, - path: *const c_char, - prefix: *const c_char, + path: CCharPtr, + prefix: CCharPtr, ) -> FfiResult { check_null!((this, path, prefix), null()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); @@ -118,7 +123,7 @@ pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( #[export_name = "FPStyleSheetResourceSerializeJson"] pub unsafe extern "C" fn style_sheet_resource_serialize_json( this: StyleSheetResourcePtr, - path: *const c_char, + path: CCharPtr, ret_buffer_len: &mut usize, ) -> FfiResult { check_null!((this, path), core::ptr::null_mut()); @@ -135,7 +140,7 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_json( #[export_name = "FPStyleSheetResourceSerializeBincode"] pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( this: StyleSheetResourcePtr, - path: *const c_char, + path: CCharPtr, ret_buffer_len: &mut usize, ) -> FfiResult { check_null!((this, path), core::ptr::null_mut()); @@ -151,8 +156,8 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( #[export_name = "FPStyleSheetResourceAddSource"] pub unsafe extern "C" fn style_sheet_resource_add_source( this: StyleSheetResourcePtr, - path: *const c_char, - source: *const c_char, + path: CCharPtr, + source: CCharPtr, warnings: *mut *mut Array, ) -> FfiResult { check_null!((this, path, source), null()); @@ -171,8 +176,8 @@ pub unsafe extern "C" fn style_sheet_resource_add_source( pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( this: StyleSheetResourcePtr, hooks: parser::hooks::CParserHooks, - path: *const c_char, - source: *const c_char, + path: CCharPtr, + source: CCharPtr, warnings: *mut *mut Array, ) -> FfiResult { check_null!((this, path, source), null()); @@ -192,7 +197,7 @@ pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( #[export_name = "FPStyleSheetResourceAddBincode"] pub unsafe extern "C" fn style_sheet_resource_add_bincode( this: StyleSheetResourcePtr, - path: *const c_char, + path: CCharPtr, buffer_ptr: BufferPtr, buffer_len: usize, drop_fn: Option, @@ -219,7 +224,7 @@ pub unsafe extern "C" fn style_sheet_resource_add_bincode( #[export_name = "FPStyleSheetResourceDirectDependencies"] pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( this: StyleSheetResourcePtr, - path: *const c_char, + path: CCharPtr, ) -> FfiResult<*mut Array> { check_null!((this, path), core::ptr::null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); @@ -290,7 +295,7 @@ pub unsafe extern "C" fn style_sheet_import_index_free( #[export_name = "FPStyleSheetImportIndexQueryAndMarkDependencies"] pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( this: StyleSheetImportIndexPtr, - path: *const c_char, + path: CCharPtr, ) -> FfiResult<*mut Array> { check_null!((this, path), core::ptr::null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); @@ -307,7 +312,7 @@ pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( #[export_name = "FPStyleSheetImportIndexListDependencies"] pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( this: StyleSheetImportIndexPtr, - path: *const c_char, + path: CCharPtr, ) -> FfiResult<*mut Array> { check_null!((this, path), core::ptr::null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); @@ -324,7 +329,7 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( #[export_name = "FPStyleSheetImportIndexListDependency"] pub unsafe extern "C" fn style_sheet_import_index_list_dependency( this: StyleSheetImportIndexPtr, - path: *const c_char, + path: CCharPtr, ) -> FfiResult<*mut Array> { check_null!((this, path), core::ptr::null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); @@ -341,18 +346,17 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependency( #[export_name = "FPStyleSheetImportIndexAddBincode"] pub unsafe extern "C" fn style_sheet_import_index_add_bincode( this: StyleSheetImportIndexPtr, - path: *const c_char, + path: CCharPtr, buffer_ptr: BufferPtr, buffer_len: usize, - drop_fn: Option, - drop_args: *mut (), + drop_fn: Option, + drop_args: RawMutPtr, warnings: *mut *mut Array, ) -> FfiResult { use float_pigment_consistent_bincode::Options; use parser::WarningKind; check_null!((this, path, buffer_ptr), null()); let path = CStr::from_ptr(path).to_string_lossy(); - let path: &str = &path; let sheet = de_static_ref_zero_copy_env( core::slice::from_raw_parts_mut(buffer_ptr, buffer_len), |s| { @@ -387,7 +391,7 @@ pub unsafe extern "C" fn style_sheet_import_index_add_bincode( } }, ); - let path = drop_css_extension(path).into(); + let path = drop_css_extension(&path).into(); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); style_sheet_import_index.map.insert(path, sheet); FfiResult::ok(null()) @@ -398,12 +402,11 @@ pub unsafe extern "C" fn style_sheet_import_index_add_bincode( #[export_name = "FPStyleSheetImportIndexRemoveBincode"] pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( this: StyleSheetImportIndexPtr, - path: *const c_char, + path: CCharPtr, ) -> FfiResult { check_null!((this, path), null()); let path = CStr::from_ptr(path).to_string_lossy(); - let path: &str = &path; - let path = drop_css_extension(path); + let path = drop_css_extension(&path); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); style_sheet_import_index.map.remove(path); FfiResult::ok(null()) @@ -413,11 +416,11 @@ pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( #[export_name = "FPStyleSheetImportIndexGetStyleSheet"] pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( this: StyleSheetImportIndexPtr, - path: *const StrRef, + path: CCharPtr, ) -> FfiResult<*mut StyleSheet> { check_null!((this, path), core::ptr::null_mut()); - let path = (*path).as_str(); - let path = drop_css_extension(path); + let path = CStr::from_ptr(path).to_string_lossy(); + let path = drop_css_extension(&path); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); match style_sheet_import_index.map.get_mut(path) { None => FfiResult::error(FfiErrorCode::InvalidPath, core::ptr::null_mut()), @@ -459,7 +462,7 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( #[cfg(all(feature = "deserialize", feature = "deserialize_json"))] #[export_name = "FPStyleSheetImportIndexDeserializeJson"] pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( - json: *const c_char, + json: CCharPtr, ) -> FfiResult { check_null!((json), core::ptr::null_mut()); let json = CStr::from_ptr(json).to_string_lossy(); @@ -559,7 +562,7 @@ pub unsafe extern "C" fn array_warning_free( /// #[export_name = "FPParseInlineStyle"] pub unsafe extern "C" fn parse_inline_style( - inline_style_text_ptr: *const c_char, + inline_style_text_ptr: CCharPtr, warnings: *mut *mut Array, ) -> FfiResult<*mut InlineRule> { check_null!((inline_style_text_ptr), core::ptr::null_mut()); @@ -604,7 +607,7 @@ pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiR /// #[export_name = "FPParseStyleSheetFromString"] pub unsafe extern "C" fn parse_style_sheet_from_string( - style_text_ptr: *const c_char, + style_text_ptr: CCharPtr, ) -> FfiResult<*mut StyleSheet> { check_null!((style_text_ptr), core::ptr::null_mut()); let style_text = CStr::from_ptr(style_text_ptr).to_string_lossy(); @@ -616,7 +619,7 @@ pub unsafe extern "C" fn parse_style_sheet_from_string( /// #[export_name = "FPParseSelectorFromString"] pub unsafe extern "C" fn parse_selector_from_string( - selector_text_ptr: *const c_char, + selector_text_ptr: CCharPtr, ) -> FfiResult<*mut Selector> { check_null!((selector_text_ptr), core::ptr::null_mut()); let selector_text = CStr::from_ptr(selector_text_ptr).to_string_lossy(); @@ -703,7 +706,7 @@ pub struct ColorValue { /// # Safety /// #[export_name = "FPParseColorFromString"] -pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiResult { +pub unsafe extern "C" fn parse_color_from_string(source: CCharPtr) -> FfiResult { check_null!((source), ColorValue::default()); let source = CStr::from_ptr(source).to_string_lossy(); let ret = parse_color_to_rgba(&source); @@ -719,11 +722,11 @@ pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiRe /// #[export_name = "FPSubstituteVariable"] pub unsafe extern "C" fn substitute_variable( - expr_ptr: *const c_char, - map: *mut (), + expr_ptr: CCharPtr, + map: RawMutPtr, getter: CustomPropertyGetter, setter: CustomPropertySetter, -) -> FfiResult<*const c_char> { +) -> FfiResult { check_null!((expr_ptr, map), null()); let expr = CStr::from_ptr(expr_ptr).to_string_lossy(); let context = CustomPropertyContext::create(map, getter, setter); @@ -738,7 +741,7 @@ pub unsafe extern "C" fn substitute_variable( /// # Safety /// #[export_name = "FPStrFree"] -pub unsafe extern "C" fn str_free(ptr: *const c_char) -> FfiResult { +pub unsafe extern "C" fn str_free(ptr: CCharPtr) -> FfiResult { check_null!((ptr), null()); drop(CString::from_raw(ptr as *mut _)); FfiResult::ok(null()) diff --git a/float-pigment-css/src/parser/hooks.rs b/float-pigment-css/src/parser/hooks.rs index 26e33d8..64a9ed1 100644 --- a/float-pigment-css/src/parser/hooks.rs +++ b/float-pigment-css/src/parser/hooks.rs @@ -1,12 +1,17 @@ //! Parser hooks can be used to attach some compilation information. use alloc::vec::Vec; + #[cfg(feature = "ffi")] use core::ffi::{c_char, CStr}; use cssparser::SourceLocation; use super::{Warning, WarningKind}; + +#[cfg(feature = "ffi")] +use crate::ffi::{FfiResult, NullPtr}; + use crate::property::Property; /// A `context` for current sompilation step. @@ -53,10 +58,18 @@ impl CParserHooksContext { /// /// The message should be a valid C string. #[no_mangle] - pub unsafe extern "C" fn generate_warning(&mut self, message: *const c_char) { + pub unsafe extern "C" fn generate_warning( + &mut self, + message: *const c_char, + ) -> FfiResult { + use crate::check_null; + use crate::ffi::FfiErrorCode; + use core::ptr::null; + check_null!((message), null()); let message = CStr::from_ptr(message).to_string_lossy(); let ctx = &mut *(self.inner as *mut ParserHooksContext); ctx.generate_warning(&message); + FfiResult::ok(null()) } } From 0f3138ee953c9249fea210a908bd10dc34e6505d Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 15:02:02 +0800 Subject: [PATCH 03/12] feat: better ffi error impl --- float-pigment-css/src/ffi.rs | 193 ++++++++++++++++------------------- 1 file changed, 89 insertions(+), 104 deletions(-) diff --git a/float-pigment-css/src/ffi.rs b/float-pigment-css/src/ffi.rs index 953d915..6c5a935 100644 --- a/float-pigment-css/src/ffi.rs +++ b/float-pigment-css/src/ffi.rs @@ -9,7 +9,7 @@ use alloc::{ }; use bit_set::BitSet; use core::ffi::{c_char, CStr}; -use core::ptr::null; +use core::ptr::{null, null_mut}; use hashbrown::HashMap; use crate::parser::parse_color_to_rgba; @@ -43,20 +43,14 @@ macro_rules! check_null { #[macro_export] macro_rules! raw_ptr_as_mut_ref { ($from:expr, $type:ty) => { - unsafe { &mut *($from as *mut $type) } + &mut *($from as *mut $type) }; } -type RawMutPtr = *mut (); +pub type RawMutPtr = *mut (); pub type NullPtr = *const (); -pub type StyleSheetResourcePtr = RawMutPtr; - -pub type BufferPtr = *mut u8; - -pub type CCharPtr = *const c_char; - #[repr(C)] pub enum FfiErrorCode { None, @@ -89,15 +83,13 @@ impl FfiResult { /// # Safety /// #[export_name = "FPStyleSheetResourceNew"] -pub unsafe extern "C" fn style_sheet_resource_new() -> FfiResult { - FfiResult::ok(Box::into_raw(Box::new(group::StyleSheetResource::new())) as StyleSheetResourcePtr) +pub unsafe extern "C" fn style_sheet_resource_new() -> FfiResult { + FfiResult::ok(Box::into_raw(Box::new(group::StyleSheetResource::new())) as RawMutPtr) } /// # Safety /// #[export_name = "FPStyleSheetResourceFree"] -pub unsafe extern "C" fn style_sheet_resource_free( - this: StyleSheetResourcePtr, -) -> FfiResult { +pub unsafe extern "C" fn style_sheet_resource_free(this: RawMutPtr) -> FfiResult { check_null!((this), null()); drop(Box::from_raw(this as *mut group::StyleSheetResource)); FfiResult::ok(null()) @@ -106,9 +98,9 @@ pub unsafe extern "C" fn style_sheet_resource_free( /// #[export_name = "FPStyleSheetResourceAddTagNamePrefix"] pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( - this: StyleSheetResourcePtr, - path: CCharPtr, - prefix: CCharPtr, + this: RawMutPtr, + path: *const c_char, + prefix: *const c_char, ) -> FfiResult { check_null!((this, path, prefix), null()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); @@ -122,42 +114,42 @@ pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( #[cfg(all(feature = "serialize", feature = "serialize_json"))] #[export_name = "FPStyleSheetResourceSerializeJson"] pub unsafe extern "C" fn style_sheet_resource_serialize_json( - this: StyleSheetResourcePtr, - path: CCharPtr, + this: RawMutPtr, + path: *const c_char, ret_buffer_len: &mut usize, -) -> FfiResult { - check_null!((this, path), core::ptr::null_mut()); +) -> FfiResult<*mut u8> { + check_null!((this, path), null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let serial = res.serialize_json(&path).unwrap_or_default(); *ret_buffer_len = serial.len(); let ret = Box::into_raw(serial.into_boxed_str()); - FfiResult::ok(ret as BufferPtr) + FfiResult::ok(ret as *mut u8) } /// # Safety /// #[cfg(feature = "serialize")] #[export_name = "FPStyleSheetResourceSerializeBincode"] pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( - this: StyleSheetResourcePtr, - path: CCharPtr, + this: RawMutPtr, + path: *const c_char, ret_buffer_len: &mut usize, -) -> FfiResult { - check_null!((this, path), core::ptr::null_mut()); +) -> FfiResult<*mut u8> { + check_null!((this, path), null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let serial = res.serialize_bincode(&path).unwrap_or_default(); *ret_buffer_len = serial.len(); let ret = Box::into_raw(serial.into_boxed_slice()); - FfiResult::ok(ret as BufferPtr) + FfiResult::ok(ret as *mut u8) } /// # Safety /// #[export_name = "FPStyleSheetResourceAddSource"] pub unsafe extern "C" fn style_sheet_resource_add_source( - this: StyleSheetResourcePtr, - path: CCharPtr, - source: CCharPtr, + this: RawMutPtr, + path: *const c_char, + source: *const c_char, warnings: *mut *mut Array, ) -> FfiResult { check_null!((this, path, source), null()); @@ -174,10 +166,10 @@ pub unsafe extern "C" fn style_sheet_resource_add_source( /// #[export_name = "FPStyleSheetResourceAddSourceWithHooks"] pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( - this: StyleSheetResourcePtr, + this: RawMutPtr, hooks: parser::hooks::CParserHooks, - path: CCharPtr, - source: CCharPtr, + path: *const c_char, + source: *const c_char, warnings: *mut *mut Array, ) -> FfiResult { check_null!((this, path, source), null()); @@ -196,9 +188,9 @@ pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetResourceAddBincode"] pub unsafe extern "C" fn style_sheet_resource_add_bincode( - this: StyleSheetResourcePtr, - path: CCharPtr, - buffer_ptr: BufferPtr, + this: RawMutPtr, + path: *const c_char, + buffer_ptr: *mut u8, buffer_len: usize, drop_fn: Option, drop_args: RawMutPtr, @@ -223,10 +215,10 @@ pub unsafe extern "C" fn style_sheet_resource_add_bincode( /// #[export_name = "FPStyleSheetResourceDirectDependencies"] pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( - this: StyleSheetResourcePtr, - path: CCharPtr, + this: RawMutPtr, + path: *const c_char, ) -> FfiResult<*mut Array> { - check_null!((this, path), core::ptr::null_mut()); + check_null!((this, path), null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let deps = res.direct_dependencies(&path); @@ -238,53 +230,49 @@ pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( /// #[export_name = "FPStyleSheetResourceGenerateImportIndex"] pub unsafe extern "C" fn style_sheet_resource_generate_import_index( - this: StyleSheetResourcePtr, -) -> FfiResult { - check_null!((this), core::ptr::null_mut()); + this: RawMutPtr, +) -> FfiResult { + check_null!((this), null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); FfiResult::ok( StyleSheetImportIndex { inner: res.generate_import_indexes(), map: StyleSheetMap::default(), } - .to_ptr(), + .into_raw(), ) } type StyleSheetMap = HashMap; -pub type StyleSheetImportIndexPtr = RawMutPtr; - struct StyleSheetImportIndex { inner: group::StyleSheetImportIndex, map: StyleSheetMap, } impl StyleSheetImportIndex { - fn to_ptr(self) -> StyleSheetImportIndexPtr { - Box::into_raw(Box::new(self)) as StyleSheetImportIndexPtr + fn into_raw(self) -> RawMutPtr { + Box::into_raw(Box::new(self)) as RawMutPtr } } /// # Safety /// #[export_name = "FPStyleSheetImportIndexNew"] -pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult { +pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult { FfiResult::ok( StyleSheetImportIndex { inner: group::StyleSheetImportIndex::new(), map: StyleSheetMap::default(), } - .to_ptr(), + .into_raw(), ) } /// # Safety /// #[export_name = "FPStyleSheetImportIndexFree"] -pub unsafe extern "C" fn style_sheet_import_index_free( - this: StyleSheetImportIndexPtr, -) -> FfiResult { +pub unsafe extern "C" fn style_sheet_import_index_free(this: RawMutPtr) -> FfiResult { check_null!((this), null()); drop(Box::from_raw(this as *mut StyleSheetImportIndex)); FfiResult::ok(null()) @@ -294,10 +282,10 @@ pub unsafe extern "C" fn style_sheet_import_index_free( /// #[export_name = "FPStyleSheetImportIndexQueryAndMarkDependencies"] pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( - this: StyleSheetImportIndexPtr, - path: CCharPtr, + this: RawMutPtr, + path: *const c_char, ) -> FfiResult<*mut Array> { - check_null!((this, path), core::ptr::null_mut()); + check_null!((this, path), null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); let deps = style_sheet_import_index @@ -311,10 +299,10 @@ pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( /// #[export_name = "FPStyleSheetImportIndexListDependencies"] pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( - this: StyleSheetImportIndexPtr, - path: CCharPtr, + this: RawMutPtr, + path: *const c_char, ) -> FfiResult<*mut Array> { - check_null!((this, path), core::ptr::null_mut()); + check_null!((this, path), null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); let deps = style_sheet_import_index @@ -328,10 +316,10 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( /// #[export_name = "FPStyleSheetImportIndexListDependency"] pub unsafe extern "C" fn style_sheet_import_index_list_dependency( - this: StyleSheetImportIndexPtr, - path: CCharPtr, + this: RawMutPtr, + path: *const c_char, ) -> FfiResult<*mut Array> { - check_null!((this, path), core::ptr::null_mut()); + check_null!((this, path), null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); let deps = style_sheet_import_index @@ -345,9 +333,9 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependency( #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetImportIndexAddBincode"] pub unsafe extern "C" fn style_sheet_import_index_add_bincode( - this: StyleSheetImportIndexPtr, - path: CCharPtr, - buffer_ptr: BufferPtr, + this: RawMutPtr, + path: *const c_char, + buffer_ptr: *mut u8, buffer_len: usize, drop_fn: Option, drop_args: RawMutPtr, @@ -401,8 +389,8 @@ pub unsafe extern "C" fn style_sheet_import_index_add_bincode( /// #[export_name = "FPStyleSheetImportIndexRemoveBincode"] pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( - this: StyleSheetImportIndexPtr, - path: CCharPtr, + this: RawMutPtr, + path: *const c_char, ) -> FfiResult { check_null!((this, path), null()); let path = CStr::from_ptr(path).to_string_lossy(); @@ -415,15 +403,15 @@ pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( /// #[export_name = "FPStyleSheetImportIndexGetStyleSheet"] pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( - this: StyleSheetImportIndexPtr, - path: CCharPtr, + this: RawMutPtr, + path: *const c_char, ) -> FfiResult<*mut StyleSheet> { - check_null!((this, path), core::ptr::null_mut()); + check_null!((this, path), null_mut()); let path = CStr::from_ptr(path).to_string_lossy(); let path = drop_css_extension(&path); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); match style_sheet_import_index.map.get_mut(path) { - None => FfiResult::error(FfiErrorCode::InvalidPath, core::ptr::null_mut()), + None => FfiResult::error(FfiErrorCode::InvalidPath, null_mut()), Some(x) => FfiResult::ok(x as *mut StyleSheet), } } @@ -432,46 +420,46 @@ pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( #[cfg(all(feature = "serialize", feature = "serialize_json"))] #[export_name = "FPStyleSheetImportIndexSerializeJson"] pub unsafe extern "C" fn style_sheet_import_index_serialize_json( - this: StyleSheetImportIndexPtr, + this: RawMutPtr, ret_buffer_len: &mut usize, -) -> FfiResult { - check_null!((this), core::ptr::null_mut()); +) -> FfiResult<*mut u8> { + check_null!((this), null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let serial = style_sheet_import_index.inner.serialize_json(); *ret_buffer_len = serial.len(); let ret = Box::into_raw(serial.into_boxed_str()); - FfiResult::ok(ret as BufferPtr) + FfiResult::ok(ret as *mut u8) } /// # Safety /// #[cfg(feature = "serialize")] #[export_name = "FPStyleSheetImportIndexSerializeBincode"] pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( - this: StyleSheetImportIndexPtr, + this: RawMutPtr, ret_buffer_len: &mut usize, -) -> FfiResult { - check_null!((this), core::ptr::null_mut()); +) -> FfiResult<*mut u8> { + check_null!((this), null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let serial = style_sheet_import_index.inner.serialize_bincode(); *ret_buffer_len = serial.len(); let ret = Box::into_raw(serial.into_boxed_slice()); - FfiResult::ok(ret as BufferPtr) + FfiResult::ok(ret as *mut u8) } /// # Safety /// #[cfg(all(feature = "deserialize", feature = "deserialize_json"))] #[export_name = "FPStyleSheetImportIndexDeserializeJson"] pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( - json: CCharPtr, -) -> FfiResult { - check_null!((json), core::ptr::null_mut()); + json: *const c_char, +) -> FfiResult { + check_null!((json), null_mut()); let json = CStr::from_ptr(json).to_string_lossy(); FfiResult::ok( StyleSheetImportIndex { inner: group::StyleSheetImportIndex::deserialize_json(&json), map: StyleSheetMap::default(), } - .to_ptr(), + .into_raw(), ) } /// # Safety @@ -479,12 +467,12 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetImportIndexDeserializeBincode"] pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( - buffer_ptr: BufferPtr, + buffer_ptr: *mut u8, buffer_len: usize, drop_fn: Option, drop_args: RawMutPtr, -) -> FfiResult { - check_null!((buffer_ptr), core::ptr::null_mut()); +) -> FfiResult { + check_null!((buffer_ptr), null_mut()); let bincode: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); FfiResult::ok( StyleSheetImportIndex { @@ -498,7 +486,7 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( ), map: StyleSheetMap::default(), } - .to_ptr(), + .into_raw(), ) } /// # Safety @@ -506,8 +494,8 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetImportIndexMergeBincode"] pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( - this: StyleSheetImportIndexPtr, - buffer_ptr: BufferPtr, + this: RawMutPtr, + buffer_ptr: *mut u8, buffer_len: usize, drop_fn: Option, drop_args: *mut (), @@ -528,10 +516,7 @@ pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( /// # Safety /// #[export_name = "FPBufferFree"] -pub unsafe extern "C" fn buffer_free( - buffer_ptr: BufferPtr, - buffer_len: usize, -) -> FfiResult { +pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) -> FfiResult { check_null!((buffer_ptr), null()); let x: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); drop(Box::from_raw(x)); @@ -562,10 +547,10 @@ pub unsafe extern "C" fn array_warning_free( /// #[export_name = "FPParseInlineStyle"] pub unsafe extern "C" fn parse_inline_style( - inline_style_text_ptr: CCharPtr, + inline_style_text_ptr: *const c_char, warnings: *mut *mut Array, ) -> FfiResult<*mut InlineRule> { - check_null!((inline_style_text_ptr), core::ptr::null_mut()); + check_null!((inline_style_text_ptr), null_mut()); let inline_style_text = CStr::from_ptr(inline_style_text_ptr).to_string_lossy(); let (prop, w) = parser::parse_inline_style(&inline_style_text, parser::StyleParsingDebugMode::None); @@ -607,9 +592,9 @@ pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiR /// #[export_name = "FPParseStyleSheetFromString"] pub unsafe extern "C" fn parse_style_sheet_from_string( - style_text_ptr: CCharPtr, + style_text_ptr: *const c_char, ) -> FfiResult<*mut StyleSheet> { - check_null!((style_text_ptr), core::ptr::null_mut()); + check_null!((style_text_ptr), null_mut()); let style_text = CStr::from_ptr(style_text_ptr).to_string_lossy(); let (compiled_style_sheet, _) = parser::parse_style_sheet("string", &style_text); let style_sheet = StyleSheet::from_sheet(&compiled_style_sheet); @@ -619,9 +604,9 @@ pub unsafe extern "C" fn parse_style_sheet_from_string( /// #[export_name = "FPParseSelectorFromString"] pub unsafe extern "C" fn parse_selector_from_string( - selector_text_ptr: CCharPtr, + selector_text_ptr: *const c_char, ) -> FfiResult<*mut Selector> { - check_null!((selector_text_ptr), core::ptr::null_mut()); + check_null!((selector_text_ptr), null_mut()); let selector_text = CStr::from_ptr(selector_text_ptr).to_string_lossy(); let selector = Selector::from_string(&selector_text); FfiResult::ok(Box::into_raw(Box::new(selector))) @@ -649,11 +634,11 @@ pub unsafe extern "C" fn style_sheet_free(style_sheet: *mut StyleSheet) -> FfiRe #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetBincodeVersion"] pub unsafe extern "C" fn style_sheet_bincode_version( - buffer_ptr: BufferPtr, + buffer_ptr: *mut u8, buffer_len: usize, ) -> FfiResult<*mut StrRef> { use float_pigment_consistent_bincode::Options; - check_null!((buffer_ptr), core::ptr::null_mut()); + check_null!((buffer_ptr), null_mut()); let sheet = de_static_ref_zero_copy_env( core::slice::from_raw_parts_mut(buffer_ptr, buffer_len), |s| { @@ -706,7 +691,7 @@ pub struct ColorValue { /// # Safety /// #[export_name = "FPParseColorFromString"] -pub unsafe extern "C" fn parse_color_from_string(source: CCharPtr) -> FfiResult { +pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiResult { check_null!((source), ColorValue::default()); let source = CStr::from_ptr(source).to_string_lossy(); let ret = parse_color_to_rgba(&source); @@ -722,11 +707,11 @@ pub unsafe extern "C" fn parse_color_from_string(source: CCharPtr) -> FfiResult< /// #[export_name = "FPSubstituteVariable"] pub unsafe extern "C" fn substitute_variable( - expr_ptr: CCharPtr, + expr_ptr: *const c_char, map: RawMutPtr, getter: CustomPropertyGetter, setter: CustomPropertySetter, -) -> FfiResult { +) -> FfiResult<*const c_char> { check_null!((expr_ptr, map), null()); let expr = CStr::from_ptr(expr_ptr).to_string_lossy(); let context = CustomPropertyContext::create(map, getter, setter); @@ -741,7 +726,7 @@ pub unsafe extern "C" fn substitute_variable( /// # Safety /// #[export_name = "FPStrFree"] -pub unsafe extern "C" fn str_free(ptr: CCharPtr) -> FfiResult { +pub unsafe extern "C" fn str_free(ptr: *const c_char) -> FfiResult { check_null!((ptr), null()); drop(CString::from_raw(ptr as *mut _)); FfiResult::ok(null()) From c8ec92841ec5c4ae0171b297fa663043b6391d76 Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 15:06:29 +0800 Subject: [PATCH 04/12] lint: fix clippy --- float-pigment-css-macro/src/style_syntax.rs | 6 +++--- float-pigment-css/src/path.rs | 2 +- float-pigment-css/src/sheet/mod.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/float-pigment-css-macro/src/style_syntax.rs b/float-pigment-css-macro/src/style_syntax.rs index 103f2ba..4403943 100644 --- a/float-pigment-css-macro/src/style_syntax.rs +++ b/float-pigment-css-macro/src/style_syntax.rs @@ -894,13 +894,13 @@ impl ToTokens for StyleSyntaxDefinition { writeln!(&mut style_doc, "| ---- | ---- | ---- |").unwrap(); let table_list_a = supported_properties .iter() - .filter(|x| !x.name.as_ref().unwrap().starts_with("-")); + .filter(|x| !x.name.as_ref().unwrap().starts_with('-')); let table_list_b = supported_properties .iter() - .filter(|x| x.name.as_ref().unwrap().starts_with("-")); + .filter(|x| x.name.as_ref().unwrap().starts_with('-')); for x in table_list_a.chain(table_list_b) { let name = x.name.as_ref().unwrap(); - let non_standard = name.starts_with("-"); + let non_standard = name.starts_with('-'); let name_col = if non_standard { format!("*`{}`*", name) } else { diff --git a/float-pigment-css/src/path.rs b/float-pigment-css/src/path.rs index 8c035b1..d538dab 100644 --- a/float-pigment-css/src/path.rs +++ b/float-pigment-css/src/path.rs @@ -3,7 +3,7 @@ use alloc::string::String; pub(crate) fn resolve(base: &str, rel: &str) -> String { let mut slices = vec![]; let mut extra_parent_count = 0; - let from_root = base.starts_with("/") || rel.starts_with("/"); + let from_root = base.starts_with('/') || rel.starts_with('/'); let main = if let Some(rel) = rel.strip_prefix('/') { rel } else { diff --git a/float-pigment-css/src/sheet/mod.rs b/float-pigment-css/src/sheet/mod.rs index c354b50..5aceb71 100644 --- a/float-pigment-css/src/sheet/mod.rs +++ b/float-pigment-css/src/sheet/mod.rs @@ -130,7 +130,7 @@ impl CompiledStyleSheet { let m = match media.clone() { None => parent_media.clone(), Some(mut m) => { - Rc::make_mut(&mut m).parent = parent_media.clone(); + Rc::make_mut(&mut m).parent.clone_from(&parent_media); Some(m) } }; From c3fd5415981a937d3f71f7663c0635b429f4f889 Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 15:09:51 +0800 Subject: [PATCH 05/12] feat: better ffi error impl --- float-pigment-css/float_pigment_css.h | 123 ++++++++++++-------------- 1 file changed, 55 insertions(+), 68 deletions(-) diff --git a/float-pigment-css/float_pigment_css.h b/float-pigment-css/float_pigment_css.h index 0b984c1..0dc24e6 100644 --- a/float-pigment-css/float_pigment_css.h +++ b/float-pigment-css/float_pigment_css.h @@ -301,8 +301,6 @@ struct Warning { uint32_t end_col; }; -using BufferPtr = uint8_t*; - template struct Box { T *ptr; @@ -8741,8 +8739,6 @@ struct ColorValue { uint8_t alpha; }; -using CCharPtr = const char*; - struct SelectorRelationType { enum class Tag { None, @@ -9024,10 +9020,6 @@ struct StyleSheet { using RawMutPtr = void*; -using StyleSheetImportIndexPtr = RawMutPtr; - -using StyleSheetResourcePtr = RawMutPtr; - struct CParserHooksContext { void *inner; }; @@ -9047,119 +9039,114 @@ FfiResult FPArrayStrRefFree(Array *x); FfiResult FPArrayWarningFree(Array *warnings); -FfiResult FPBufferFree(BufferPtr buffer_ptr, size_t buffer_len); +FfiResult FPBufferFree(uint8_t *buffer_ptr, size_t buffer_len); FfiResult FPCssParserVersion(); FfiResult FPInlineStyleFree(InlineRule *inline_rule); -FfiResult FPParseColorFromString(CCharPtr source); +FfiResult FPParseColorFromString(const char *source); -FfiResult FPParseInlineStyle(CCharPtr inline_style_text_ptr, +FfiResult FPParseInlineStyle(const char *inline_style_text_ptr, Array **warnings); -FfiResult FPParseSelectorFromString(CCharPtr selector_text_ptr); +FfiResult FPParseSelectorFromString(const char *selector_text_ptr); -FfiResult FPParseStyleSheetFromString(CCharPtr style_text_ptr); +FfiResult FPParseStyleSheetFromString(const char *style_text_ptr); FfiResult FPSelectorFree(Selector *selector); -FfiResult FPStrFree(CCharPtr ptr); +FfiResult FPStrFree(const char *ptr); -FfiResult FPStyleSheetBincodeVersion(BufferPtr buffer_ptr, size_t buffer_len); +FfiResult FPStyleSheetBincodeVersion(uint8_t *buffer_ptr, size_t buffer_len); FfiResult FPStyleSheetFree(StyleSheet *style_sheet); -FfiResult FPStyleSheetImportIndexAddBincode(StyleSheetImportIndexPtr this_, - CCharPtr path, - BufferPtr buffer_ptr, +FfiResult FPStyleSheetImportIndexAddBincode(RawMutPtr this_, + const char *path, + uint8_t *buffer_ptr, size_t buffer_len, void (*drop_fn)(RawMutPtr), RawMutPtr drop_args, Array **warnings); -FfiResult FPStyleSheetImportIndexDeserializeBincode(BufferPtr buffer_ptr, - size_t buffer_len, - void (*drop_fn)(RawMutPtr), - RawMutPtr drop_args); +FfiResult FPStyleSheetImportIndexDeserializeBincode(uint8_t *buffer_ptr, + size_t buffer_len, + void (*drop_fn)(RawMutPtr), + RawMutPtr drop_args); -FfiResult FPStyleSheetImportIndexDeserializeJson(CCharPtr json); +FfiResult FPStyleSheetImportIndexDeserializeJson(const char *json); -FfiResult FPStyleSheetImportIndexFree(StyleSheetImportIndexPtr this_); +FfiResult FPStyleSheetImportIndexFree(RawMutPtr this_); -FfiResult FPStyleSheetImportIndexGetStyleSheet(StyleSheetImportIndexPtr this_, - CCharPtr path); +FfiResult FPStyleSheetImportIndexGetStyleSheet(RawMutPtr this_, const char *path); -FfiResult*> FPStyleSheetImportIndexListDependencies(StyleSheetImportIndexPtr this_, - CCharPtr path); +FfiResult*> FPStyleSheetImportIndexListDependencies(RawMutPtr this_, + const char *path); -FfiResult*> FPStyleSheetImportIndexListDependency(StyleSheetImportIndexPtr this_, - CCharPtr path); +FfiResult*> FPStyleSheetImportIndexListDependency(RawMutPtr this_, const char *path); -FfiResult FPStyleSheetImportIndexMergeBincode(StyleSheetImportIndexPtr this_, - BufferPtr buffer_ptr, +FfiResult FPStyleSheetImportIndexMergeBincode(RawMutPtr this_, + uint8_t *buffer_ptr, size_t buffer_len, void (*drop_fn)(void*), void *drop_args); -FfiResult FPStyleSheetImportIndexNew(); +FfiResult FPStyleSheetImportIndexNew(); -FfiResult*> FPStyleSheetImportIndexQueryAndMarkDependencies(StyleSheetImportIndexPtr this_, - CCharPtr path); +FfiResult*> FPStyleSheetImportIndexQueryAndMarkDependencies(RawMutPtr this_, + const char *path); -FfiResult FPStyleSheetImportIndexRemoveBincode(StyleSheetImportIndexPtr this_, - CCharPtr path); +FfiResult FPStyleSheetImportIndexRemoveBincode(RawMutPtr this_, const char *path); -FfiResult FPStyleSheetImportIndexSerializeBincode(StyleSheetImportIndexPtr this_, - size_t *ret_buffer_len); +FfiResult FPStyleSheetImportIndexSerializeBincode(RawMutPtr this_, + size_t *ret_buffer_len); -FfiResult FPStyleSheetImportIndexSerializeJson(StyleSheetImportIndexPtr this_, - size_t *ret_buffer_len); +FfiResult FPStyleSheetImportIndexSerializeJson(RawMutPtr this_, size_t *ret_buffer_len); -FfiResult FPStyleSheetResourceAddBincode(StyleSheetResourcePtr this_, - CCharPtr path, - BufferPtr buffer_ptr, +FfiResult FPStyleSheetResourceAddBincode(RawMutPtr this_, + const char *path, + uint8_t *buffer_ptr, size_t buffer_len, void (*drop_fn)(RawMutPtr), RawMutPtr drop_args, Array **warnings); -FfiResult FPStyleSheetResourceAddSource(StyleSheetResourcePtr this_, - CCharPtr path, - CCharPtr source, +FfiResult FPStyleSheetResourceAddSource(RawMutPtr this_, + const char *path, + const char *source, Array **warnings); -FfiResult FPStyleSheetResourceAddSourceWithHooks(StyleSheetResourcePtr this_, +FfiResult FPStyleSheetResourceAddSourceWithHooks(RawMutPtr this_, CParserHooks hooks, - CCharPtr path, - CCharPtr source, + const char *path, + const char *source, Array **warnings); -FfiResult FPStyleSheetResourceAddTagNamePrefix(StyleSheetResourcePtr this_, - CCharPtr path, - CCharPtr prefix); +FfiResult FPStyleSheetResourceAddTagNamePrefix(RawMutPtr this_, + const char *path, + const char *prefix); -FfiResult*> FPStyleSheetResourceDirectDependencies(StyleSheetResourcePtr this_, - CCharPtr path); +FfiResult*> FPStyleSheetResourceDirectDependencies(RawMutPtr this_, const char *path); -FfiResult FPStyleSheetResourceFree(StyleSheetResourcePtr this_); +FfiResult FPStyleSheetResourceFree(RawMutPtr this_); -FfiResult FPStyleSheetResourceGenerateImportIndex(StyleSheetResourcePtr this_); +FfiResult FPStyleSheetResourceGenerateImportIndex(RawMutPtr this_); -FfiResult FPStyleSheetResourceNew(); +FfiResult FPStyleSheetResourceNew(); -FfiResult FPStyleSheetResourceSerializeBincode(StyleSheetResourcePtr this_, - CCharPtr path, - size_t *ret_buffer_len); +FfiResult FPStyleSheetResourceSerializeBincode(RawMutPtr this_, + const char *path, + size_t *ret_buffer_len); -FfiResult FPStyleSheetResourceSerializeJson(StyleSheetResourcePtr this_, - CCharPtr path, - size_t *ret_buffer_len); +FfiResult FPStyleSheetResourceSerializeJson(RawMutPtr this_, + const char *path, + size_t *ret_buffer_len); -FfiResult FPSubstituteVariable(CCharPtr expr_ptr, - RawMutPtr map, - CustomPropertyGetter getter, - CustomPropertySetter setter); +FfiResult FPSubstituteVariable(const char *expr_ptr, + RawMutPtr map, + CustomPropertyGetter getter, + CustomPropertySetter setter); FfiResult generate_warning(CParserHooksContext *self, const char *message); From 412134bcbc71de23da58daabf73566f57eed716b Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 15:23:15 +0800 Subject: [PATCH 06/12] fix: serialize_json type bug --- float-pigment-css/tests/serde.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/float-pigment-css/tests/serde.rs b/float-pigment-css/tests/serde.rs index 402aef2..0871ec6 100644 --- a/float-pigment-css/tests/serde.rs +++ b/float-pigment-css/tests/serde.rs @@ -22,7 +22,7 @@ fn for_each_serialize_format(s: &str, mut f: impl FnMut(StyleSheetGroup)) { let mut ssg = StyleSheetGroup::new(); let buf = compile_style_sheet_to_json("", s); let mut resource = StyleSheetResource::new(); - resource.add_json("", buf); + resource.add_json("", &buf); ssg.append_from_resource(&resource, "", None); f(ssg); } From 97139c32750b5577c7576e6ce41bf72403d92ddb Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 16:22:24 +0800 Subject: [PATCH 07/12] docs: add ffi docs --- float-pigment-css/src/ffi.rs | 81 ++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/float-pigment-css/src/ffi.rs b/float-pigment-css/src/ffi.rs index 6c5a935..b883598 100644 --- a/float-pigment-css/src/ffi.rs +++ b/float-pigment-css/src/ffi.rs @@ -81,21 +81,23 @@ impl FfiResult { } /// # Safety -/// +/// Create a new resource manager. #[export_name = "FPStyleSheetResourceNew"] pub unsafe extern "C" fn style_sheet_resource_new() -> FfiResult { FfiResult::ok(Box::into_raw(Box::new(group::StyleSheetResource::new())) as RawMutPtr) } + /// # Safety -/// +/// Free the resource manager. #[export_name = "FPStyleSheetResourceFree"] pub unsafe extern "C" fn style_sheet_resource_free(this: RawMutPtr) -> FfiResult { check_null!((this), null()); drop(Box::from_raw(this as *mut group::StyleSheetResource)); FfiResult::ok(null()) } + /// # Safety -/// +/// Add a tag name prefix to the resource manager. #[export_name = "FPStyleSheetResourceAddTagNamePrefix"] pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( this: RawMutPtr, @@ -109,8 +111,9 @@ pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( res.add_tag_name_prefix(&path, &prefix); FfiResult::ok(null()) } + /// # Safety -/// +/// Serialize the specified style sheet to the JSON format. #[cfg(all(feature = "serialize", feature = "serialize_json"))] #[export_name = "FPStyleSheetResourceSerializeJson"] pub unsafe extern "C" fn style_sheet_resource_serialize_json( @@ -126,8 +129,9 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_json( let ret = Box::into_raw(serial.into_boxed_str()); FfiResult::ok(ret as *mut u8) } + /// # Safety -/// +/// Serialize the specified style sheet to the binary format. #[cfg(feature = "serialize")] #[export_name = "FPStyleSheetResourceSerializeBincode"] pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( @@ -144,7 +148,7 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( FfiResult::ok(ret as *mut u8) } /// # Safety -/// +/// Add a style sheet to the resource manager. #[export_name = "FPStyleSheetResourceAddSource"] pub unsafe extern "C" fn style_sheet_resource_add_source( this: RawMutPtr, @@ -162,8 +166,9 @@ pub unsafe extern "C" fn style_sheet_resource_add_source( } FfiResult::ok(null()) } + /// # Safety -/// +/// Add a style sheet to the resource manager with hooks. #[export_name = "FPStyleSheetResourceAddSourceWithHooks"] pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( this: RawMutPtr, @@ -184,7 +189,7 @@ pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( } /// # Safety -/// +/// Add a style sheet to the resource manager from binary format. #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetResourceAddBincode"] pub unsafe extern "C" fn style_sheet_resource_add_bincode( @@ -212,7 +217,7 @@ pub unsafe extern "C" fn style_sheet_resource_add_bincode( } /// # Safety -/// +/// Get the direct dependencies of the specified style sheet. #[export_name = "FPStyleSheetResourceDirectDependencies"] pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( this: RawMutPtr, @@ -227,7 +232,7 @@ pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( } /// # Safety -/// +/// Generate the import index of the resource manager. #[export_name = "FPStyleSheetResourceGenerateImportIndex"] pub unsafe extern "C" fn style_sheet_resource_generate_import_index( this: RawMutPtr, @@ -257,7 +262,7 @@ impl StyleSheetImportIndex { } /// # Safety -/// +/// Create a new style sheet import index. #[export_name = "FPStyleSheetImportIndexNew"] pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult { FfiResult::ok( @@ -270,7 +275,7 @@ pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult } /// # Safety -/// +/// Free the style sheet import index. #[export_name = "FPStyleSheetImportIndexFree"] pub unsafe extern "C" fn style_sheet_import_index_free(this: RawMutPtr) -> FfiResult { check_null!((this), null()); @@ -279,7 +284,7 @@ pub unsafe extern "C" fn style_sheet_import_index_free(this: RawMutPtr) -> FfiRe } /// # Safety -/// +/// Query and mark the dependencies of the specified style sheet. #[export_name = "FPStyleSheetImportIndexQueryAndMarkDependencies"] pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( this: RawMutPtr, @@ -296,7 +301,7 @@ pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( } /// # Safety -/// +/// List the dependencies of the specified style sheet. #[export_name = "FPStyleSheetImportIndexListDependencies"] pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( this: RawMutPtr, @@ -313,7 +318,7 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( } /// # Safety -/// +/// List the dependency of the specified style sheet. #[export_name = "FPStyleSheetImportIndexListDependency"] pub unsafe extern "C" fn style_sheet_import_index_list_dependency( this: RawMutPtr, @@ -329,7 +334,7 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependency( FfiResult::ok(Box::into_raw(Box::new(deps.into()))) } /// # Safety -/// +/// Add a style sheet to the import index from binary format. #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetImportIndexAddBincode"] pub unsafe extern "C" fn style_sheet_import_index_add_bincode( @@ -386,7 +391,7 @@ pub unsafe extern "C" fn style_sheet_import_index_add_bincode( } /// # Safety -/// +/// Remove a style sheet from the style sheet import index. #[export_name = "FPStyleSheetImportIndexRemoveBincode"] pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( this: RawMutPtr, @@ -400,7 +405,7 @@ pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( FfiResult::ok(null()) } /// # Safety -/// +/// Get the style sheet from the style sheet import index. #[export_name = "FPStyleSheetImportIndexGetStyleSheet"] pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( this: RawMutPtr, @@ -416,7 +421,7 @@ pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( } } /// # Safety -/// +/// Serialize the style sheet import index to the JSON format. #[cfg(all(feature = "serialize", feature = "serialize_json"))] #[export_name = "FPStyleSheetImportIndexSerializeJson"] pub unsafe extern "C" fn style_sheet_import_index_serialize_json( @@ -431,7 +436,7 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_json( FfiResult::ok(ret as *mut u8) } /// # Safety -/// +/// Serialize the style sheet import index to the binary format. #[cfg(feature = "serialize")] #[export_name = "FPStyleSheetImportIndexSerializeBincode"] pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( @@ -446,7 +451,7 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( FfiResult::ok(ret as *mut u8) } /// # Safety -/// +/// Deserialize the style sheet import index from the JSON format. #[cfg(all(feature = "deserialize", feature = "deserialize_json"))] #[export_name = "FPStyleSheetImportIndexDeserializeJson"] pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( @@ -490,7 +495,7 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( ) } /// # Safety -/// +/// Merge the style sheet import index from binary format. #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetImportIndexMergeBincode"] pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( @@ -514,7 +519,7 @@ pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( } /// # Safety -/// +/// Free the buffer. #[export_name = "FPBufferFree"] pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) -> FfiResult { check_null!((buffer_ptr), null()); @@ -524,7 +529,7 @@ pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) -> } /// # Safety -/// +/// Free the array of string references. #[export_name = "FPArrayStrRefFree"] pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) -> FfiResult { check_null!((x), null()); @@ -533,7 +538,7 @@ pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) -> FfiResult< } /// # Safety -/// +/// Free the array of warnings. #[export_name = "FPArrayWarningFree"] pub unsafe extern "C" fn array_warning_free( warnings: *mut Array, @@ -544,7 +549,7 @@ pub unsafe extern "C" fn array_warning_free( } /// # Safety -/// +/// Parse the inline style from the string. #[export_name = "FPParseInlineStyle"] pub unsafe extern "C" fn parse_inline_style( inline_style_text_ptr: *const c_char, @@ -580,16 +585,18 @@ pub unsafe extern "C" fn parse_inline_style( let inline_rule = InlineRule::new(properties, important); FfiResult::ok(Box::into_raw(Box::new(inline_rule))) } + /// # Safety -/// +/// Free the inline style. #[export_name = "FPInlineStyleFree"] pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiResult { check_null!((inline_rule), null()); drop(Box::from_raw(inline_rule)); FfiResult::ok(null()) } + /// # Safety -/// +/// Parse the style sheet from the string. #[export_name = "FPParseStyleSheetFromString"] pub unsafe extern "C" fn parse_style_sheet_from_string( style_text_ptr: *const c_char, @@ -600,8 +607,9 @@ pub unsafe extern "C" fn parse_style_sheet_from_string( let style_sheet = StyleSheet::from_sheet(&compiled_style_sheet); FfiResult::ok(Box::into_raw(Box::new(style_sheet))) } + /// # Safety -/// +/// Parse the selector from the string. #[export_name = "FPParseSelectorFromString"] pub unsafe extern "C" fn parse_selector_from_string( selector_text_ptr: *const c_char, @@ -611,8 +619,9 @@ pub unsafe extern "C" fn parse_selector_from_string( let selector = Selector::from_string(&selector_text); FfiResult::ok(Box::into_raw(Box::new(selector))) } + /// # Safety -/// +/// Free the selector. #[export_name = "FPSelectorFree"] pub unsafe extern "C" fn selector_free(selector: *mut Selector) -> FfiResult { check_null!((selector), null()); @@ -621,7 +630,7 @@ pub unsafe extern "C" fn selector_free(selector: *mut Selector) -> FfiResult FfiResult { check_null!((style_sheet), null()); @@ -630,7 +639,7 @@ pub unsafe extern "C" fn style_sheet_free(style_sheet: *mut StyleSheet) -> FfiRe } /// # Safety -/// +/// Get the version of the style sheet in the binary format. #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetBincodeVersion"] pub unsafe extern "C" fn style_sheet_bincode_version( @@ -672,7 +681,7 @@ pub unsafe extern "C" fn style_sheet_bincode_version( } /// # Safety -/// +/// Get the version of the CSS parser. #[export_name = "FPCssParserVersion"] pub unsafe extern "C" fn css_parser_version() -> FfiResult<*mut StrRef> { let version = env!("CARGO_PKG_VERSION").to_string().into(); @@ -689,7 +698,7 @@ pub struct ColorValue { } /// # Safety -/// +/// Parse the color from the string. #[export_name = "FPParseColorFromString"] pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiResult { check_null!((source), ColorValue::default()); @@ -704,7 +713,7 @@ pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiRe } /// # Safety -/// +/// Substitute the variable in the expression. #[export_name = "FPSubstituteVariable"] pub unsafe extern "C" fn substitute_variable( expr_ptr: *const c_char, @@ -724,7 +733,7 @@ pub unsafe extern "C" fn substitute_variable( } /// # Safety -/// +/// Free the string. #[export_name = "FPStrFree"] pub unsafe extern "C" fn str_free(ptr: *const c_char) -> FfiResult { check_null!((ptr), null()); From 907346faa26bc8566d943d5a0f67801adc20ad08 Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 16:41:03 +0800 Subject: [PATCH 08/12] feat: better ffi error impl --- float-pigment-css/src/ffi.rs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/float-pigment-css/src/ffi.rs b/float-pigment-css/src/ffi.rs index b883598..d7abea8 100644 --- a/float-pigment-css/src/ffi.rs +++ b/float-pigment-css/src/ffi.rs @@ -24,6 +24,7 @@ use crate::parser::property_value::var::{ }; use crate::sheet; use group::drop_css_extension; +use group::StyleSheetImportIndex as StyleSheetImportIndexImpl; use parser::Warning; use sheet::borrow::{Array, StyleSheet}; use sheet::str_store::StrRef; @@ -68,14 +69,14 @@ pub struct FfiResult { impl FfiResult { pub fn ok(value: T) -> Self { Self { - err: FfiErrorCode::None, value, + err: FfiErrorCode::None, } } pub fn error(err: FfiErrorCode, default: T) -> Self { Self { - err, value: default, + err, } } } @@ -251,7 +252,7 @@ pub unsafe extern "C" fn style_sheet_resource_generate_import_index( type StyleSheetMap = HashMap; struct StyleSheetImportIndex { - inner: group::StyleSheetImportIndex, + inner: StyleSheetImportIndexImpl, map: StyleSheetMap, } @@ -267,7 +268,7 @@ impl StyleSheetImportIndex { pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult { FfiResult::ok( StyleSheetImportIndex { - inner: group::StyleSheetImportIndex::new(), + inner: StyleSheetImportIndexImpl::new(), map: StyleSheetMap::default(), } .into_raw(), @@ -461,7 +462,7 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( let json = CStr::from_ptr(json).to_string_lossy(); FfiResult::ok( StyleSheetImportIndex { - inner: group::StyleSheetImportIndex::deserialize_json(&json), + inner: StyleSheetImportIndexImpl::deserialize_json(&json), map: StyleSheetMap::default(), } .into_raw(), @@ -481,14 +482,11 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( let bincode: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); FfiResult::ok( StyleSheetImportIndex { - inner: group::StyleSheetImportIndex::deserialize_bincode_zero_copy( - bincode, - move || { - if let Some(drop_fn) = drop_fn { - drop_fn(drop_args); - } - }, - ), + inner: StyleSheetImportIndexImpl::deserialize_bincode_zero_copy(bincode, move || { + if let Some(drop_fn) = drop_fn { + drop_fn(drop_args); + } + }), map: StyleSheetMap::default(), } .into_raw(), From 3153ac165c71c0f1a41fa18b7c32bc203711f8c6 Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 17:15:08 +0800 Subject: [PATCH 09/12] feat: better ffi error impl --- float-pigment-css/src/ffi.rs | 129 ++++++++++++++++++-------- float-pigment-css/src/parser/hooks.rs | 2 +- 2 files changed, 91 insertions(+), 40 deletions(-) diff --git a/float-pigment-css/src/ffi.rs b/float-pigment-css/src/ffi.rs index d7abea8..0b0da45 100644 --- a/float-pigment-css/src/ffi.rs +++ b/float-pigment-css/src/ffi.rs @@ -34,9 +34,9 @@ use sheet::borrow::de_static_ref_zero_copy_env; #[macro_export] macro_rules! check_null { - (($($arg:expr),+ $(,)?), $default: expr) => { - if $( $arg.is_null() )||+ { - return FfiResult::error(FfiErrorCode::NullPointer, $default); + ($arg:expr, $error:expr, $default:expr) => { + if $arg.is_null() { + return FfiResult::error($error, $default); } }; } @@ -55,8 +55,23 @@ pub type NullPtr = *const (); #[repr(C)] pub enum FfiErrorCode { None, - NullPointer, + ThisNullPointer, + PathNullPointer, + PrefixNullPointer, + SourceNullPointer, + BufferNullPointer, + ExprPtrNullPointer, + StrNullPointer, + InlineStyleTextNullPointer, + InlineRuleNullPointer, + StyleTextNullPointer, + SelectorTextNullPointer, InvalidPath, + JsonNullPointer, + ArrayNullPointer, + SelectorNullPointer, + StyleSheetNullPointer, + MapNullPointer, Unknown, } @@ -92,7 +107,7 @@ pub unsafe extern "C" fn style_sheet_resource_new() -> FfiResult { /// Free the resource manager. #[export_name = "FPStyleSheetResourceFree"] pub unsafe extern "C" fn style_sheet_resource_free(this: RawMutPtr) -> FfiResult { - check_null!((this), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null()); drop(Box::from_raw(this as *mut group::StyleSheetResource)); FfiResult::ok(null()) } @@ -105,7 +120,9 @@ pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( path: *const c_char, prefix: *const c_char, ) -> FfiResult { - check_null!((this, path, prefix), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null()); + check_null!(path, FfiErrorCode::PathNullPointer, null()); + check_null!(prefix, FfiErrorCode::PrefixNullPointer, null()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let prefix = CStr::from_ptr(prefix).to_string_lossy(); @@ -122,7 +139,8 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_json( path: *const c_char, ret_buffer_len: &mut usize, ) -> FfiResult<*mut u8> { - check_null!((this, path), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); + check_null!(path, FfiErrorCode::PathNullPointer, null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let serial = res.serialize_json(&path).unwrap_or_default(); @@ -140,7 +158,8 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( path: *const c_char, ret_buffer_len: &mut usize, ) -> FfiResult<*mut u8> { - check_null!((this, path), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); + check_null!(path, FfiErrorCode::PathNullPointer, null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let serial = res.serialize_bincode(&path).unwrap_or_default(); @@ -157,7 +176,9 @@ pub unsafe extern "C" fn style_sheet_resource_add_source( source: *const c_char, warnings: *mut *mut Array, ) -> FfiResult { - check_null!((this, path, source), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null()); + check_null!(path, FfiErrorCode::PathNullPointer, null()); + check_null!(source, FfiErrorCode::SourceNullPointer, null()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let source = CStr::from_ptr(source).to_string_lossy(); @@ -178,7 +199,9 @@ pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( source: *const c_char, warnings: *mut *mut Array, ) -> FfiResult { - check_null!((this, path, source), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null()); + check_null!(path, FfiErrorCode::PathNullPointer, null()); + check_null!(source, FfiErrorCode::SourceNullPointer, null()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let source = CStr::from_ptr(source).to_string_lossy(); @@ -202,7 +225,9 @@ pub unsafe extern "C" fn style_sheet_resource_add_bincode( drop_args: RawMutPtr, warnings: *mut *mut Array, ) -> FfiResult { - check_null!((this, path, buffer_ptr), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null()); + check_null!(path, FfiErrorCode::PathNullPointer, null()); + check_null!(buffer_ptr, FfiErrorCode::BufferNullPointer, null()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let bincode: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); let path = CStr::from_ptr(path).to_string_lossy(); @@ -224,7 +249,8 @@ pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( this: RawMutPtr, path: *const c_char, ) -> FfiResult<*mut Array> { - check_null!((this, path), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); + check_null!(path, FfiErrorCode::PathNullPointer, null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); let path = CStr::from_ptr(path).to_string_lossy(); let deps = res.direct_dependencies(&path); @@ -238,7 +264,7 @@ pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( pub unsafe extern "C" fn style_sheet_resource_generate_import_index( this: RawMutPtr, ) -> FfiResult { - check_null!((this), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); let res = raw_ptr_as_mut_ref!(this, group::StyleSheetResource); FfiResult::ok( StyleSheetImportIndex { @@ -279,7 +305,7 @@ pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult /// Free the style sheet import index. #[export_name = "FPStyleSheetImportIndexFree"] pub unsafe extern "C" fn style_sheet_import_index_free(this: RawMutPtr) -> FfiResult { - check_null!((this), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null()); drop(Box::from_raw(this as *mut StyleSheetImportIndex)); FfiResult::ok(null()) } @@ -291,7 +317,8 @@ pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( this: RawMutPtr, path: *const c_char, ) -> FfiResult<*mut Array> { - check_null!((this, path), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); + check_null!(path, FfiErrorCode::PathNullPointer, null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); let deps = style_sheet_import_index @@ -308,7 +335,8 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( this: RawMutPtr, path: *const c_char, ) -> FfiResult<*mut Array> { - check_null!((this, path), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); + check_null!(path, FfiErrorCode::PathNullPointer, null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); let deps = style_sheet_import_index @@ -325,7 +353,8 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependency( this: RawMutPtr, path: *const c_char, ) -> FfiResult<*mut Array> { - check_null!((this, path), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); + check_null!(path, FfiErrorCode::PathNullPointer, null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let path = CStr::from_ptr(path).to_string_lossy(); let deps = style_sheet_import_index @@ -349,7 +378,9 @@ pub unsafe extern "C" fn style_sheet_import_index_add_bincode( ) -> FfiResult { use float_pigment_consistent_bincode::Options; use parser::WarningKind; - check_null!((this, path, buffer_ptr), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); + check_null!(path, FfiErrorCode::PathNullPointer, null_mut()); + check_null!(buffer_ptr, FfiErrorCode::BufferNullPointer, null_mut()); let path = CStr::from_ptr(path).to_string_lossy(); let sheet = de_static_ref_zero_copy_env( core::slice::from_raw_parts_mut(buffer_ptr, buffer_len), @@ -398,7 +429,8 @@ pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( this: RawMutPtr, path: *const c_char, ) -> FfiResult { - check_null!((this, path), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null()); + check_null!(path, FfiErrorCode::PathNullPointer, null()); let path = CStr::from_ptr(path).to_string_lossy(); let path = drop_css_extension(&path); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); @@ -412,7 +444,8 @@ pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( this: RawMutPtr, path: *const c_char, ) -> FfiResult<*mut StyleSheet> { - check_null!((this, path), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); + check_null!(path, FfiErrorCode::PathNullPointer, null_mut()); let path = CStr::from_ptr(path).to_string_lossy(); let path = drop_css_extension(&path); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); @@ -429,7 +462,7 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_json( this: RawMutPtr, ret_buffer_len: &mut usize, ) -> FfiResult<*mut u8> { - check_null!((this), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let serial = style_sheet_import_index.inner.serialize_json(); *ret_buffer_len = serial.len(); @@ -444,7 +477,7 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( this: RawMutPtr, ret_buffer_len: &mut usize, ) -> FfiResult<*mut u8> { - check_null!((this), null_mut()); + check_null!(this, FfiErrorCode::ThisNullPointer, null_mut()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let serial = style_sheet_import_index.inner.serialize_bincode(); *ret_buffer_len = serial.len(); @@ -458,7 +491,7 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( json: *const c_char, ) -> FfiResult { - check_null!((json), null_mut()); + check_null!(json, FfiErrorCode::JsonNullPointer, null_mut()); let json = CStr::from_ptr(json).to_string_lossy(); FfiResult::ok( StyleSheetImportIndex { @@ -478,7 +511,7 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( drop_fn: Option, drop_args: RawMutPtr, ) -> FfiResult { - check_null!((buffer_ptr), null_mut()); + check_null!(buffer_ptr, FfiErrorCode::BufferNullPointer, null_mut()); let bincode: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); FfiResult::ok( StyleSheetImportIndex { @@ -503,7 +536,8 @@ pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( drop_fn: Option, drop_args: *mut (), ) -> FfiResult { - check_null!((this, buffer_ptr), null()); + check_null!(this, FfiErrorCode::ThisNullPointer, null()); + check_null!(buffer_ptr, FfiErrorCode::BufferNullPointer, null()); let style_sheet_import_index = raw_ptr_as_mut_ref!(this, StyleSheetImportIndex); let bincode: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); style_sheet_import_index @@ -520,7 +554,7 @@ pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( /// Free the buffer. #[export_name = "FPBufferFree"] pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) -> FfiResult { - check_null!((buffer_ptr), null()); + check_null!(buffer_ptr, FfiErrorCode::BufferNullPointer, null()); let x: *mut [u8] = core::slice::from_raw_parts_mut(buffer_ptr, buffer_len); drop(Box::from_raw(x)); FfiResult::ok(null()) @@ -530,7 +564,7 @@ pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) -> /// Free the array of string references. #[export_name = "FPArrayStrRefFree"] pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) -> FfiResult { - check_null!((x), null()); + check_null!(x, FfiErrorCode::ArrayNullPointer, null()); drop(Box::from_raw(x)); FfiResult::ok(null()) } @@ -541,7 +575,7 @@ pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) -> FfiResult< pub unsafe extern "C" fn array_warning_free( warnings: *mut Array, ) -> FfiResult { - check_null!((warnings), null()); + check_null!(warnings, FfiErrorCode::ArrayNullPointer, null()); drop(Box::from_raw(warnings)); FfiResult::ok(null()) } @@ -553,7 +587,11 @@ pub unsafe extern "C" fn parse_inline_style( inline_style_text_ptr: *const c_char, warnings: *mut *mut Array, ) -> FfiResult<*mut InlineRule> { - check_null!((inline_style_text_ptr), null_mut()); + check_null!( + inline_style_text_ptr, + FfiErrorCode::InlineStyleTextNullPointer, + null_mut() + ); let inline_style_text = CStr::from_ptr(inline_style_text_ptr).to_string_lossy(); let (prop, w) = parser::parse_inline_style(&inline_style_text, parser::StyleParsingDebugMode::None); @@ -588,7 +626,7 @@ pub unsafe extern "C" fn parse_inline_style( /// Free the inline style. #[export_name = "FPInlineStyleFree"] pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiResult { - check_null!((inline_rule), null()); + check_null!(inline_rule, FfiErrorCode::InlineRuleNullPointer, null()); drop(Box::from_raw(inline_rule)); FfiResult::ok(null()) } @@ -599,7 +637,11 @@ pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiR pub unsafe extern "C" fn parse_style_sheet_from_string( style_text_ptr: *const c_char, ) -> FfiResult<*mut StyleSheet> { - check_null!((style_text_ptr), null_mut()); + check_null!( + style_text_ptr, + FfiErrorCode::StyleTextNullPointer, + null_mut() + ); let style_text = CStr::from_ptr(style_text_ptr).to_string_lossy(); let (compiled_style_sheet, _) = parser::parse_style_sheet("string", &style_text); let style_sheet = StyleSheet::from_sheet(&compiled_style_sheet); @@ -612,7 +654,11 @@ pub unsafe extern "C" fn parse_style_sheet_from_string( pub unsafe extern "C" fn parse_selector_from_string( selector_text_ptr: *const c_char, ) -> FfiResult<*mut Selector> { - check_null!((selector_text_ptr), null_mut()); + check_null!( + selector_text_ptr, + FfiErrorCode::SelectorTextNullPointer, + null_mut() + ); let selector_text = CStr::from_ptr(selector_text_ptr).to_string_lossy(); let selector = Selector::from_string(&selector_text); FfiResult::ok(Box::into_raw(Box::new(selector))) @@ -622,7 +668,7 @@ pub unsafe extern "C" fn parse_selector_from_string( /// Free the selector. #[export_name = "FPSelectorFree"] pub unsafe extern "C" fn selector_free(selector: *mut Selector) -> FfiResult { - check_null!((selector), null()); + check_null!(selector, FfiErrorCode::SelectorNullPointer, null()); drop(Box::from_raw(selector)); FfiResult::ok(null()) } @@ -631,7 +677,7 @@ pub unsafe extern "C" fn selector_free(selector: *mut Selector) -> FfiResult FfiResult { - check_null!((style_sheet), null()); + check_null!(style_sheet, FfiErrorCode::StyleSheetNullPointer, null()); drop(Box::from_raw(style_sheet)); FfiResult::ok(null()) } @@ -645,7 +691,7 @@ pub unsafe extern "C" fn style_sheet_bincode_version( buffer_len: usize, ) -> FfiResult<*mut StrRef> { use float_pigment_consistent_bincode::Options; - check_null!((buffer_ptr), null_mut()); + check_null!(buffer_ptr, FfiErrorCode::BufferNullPointer, null_mut()); let sheet = de_static_ref_zero_copy_env( core::slice::from_raw_parts_mut(buffer_ptr, buffer_len), |s| { @@ -699,7 +745,11 @@ pub struct ColorValue { /// Parse the color from the string. #[export_name = "FPParseColorFromString"] pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiResult { - check_null!((source), ColorValue::default()); + check_null!( + source, + FfiErrorCode::SourceNullPointer, + ColorValue::default() + ); let source = CStr::from_ptr(source).to_string_lossy(); let ret = parse_color_to_rgba(&source); FfiResult::ok(ColorValue { @@ -719,7 +769,8 @@ pub unsafe extern "C" fn substitute_variable( getter: CustomPropertyGetter, setter: CustomPropertySetter, ) -> FfiResult<*const c_char> { - check_null!((expr_ptr, map), null()); + check_null!(expr_ptr, FfiErrorCode::ExprPtrNullPointer, null()); + check_null!(map, FfiErrorCode::MapNullPointer, null()); let expr = CStr::from_ptr(expr_ptr).to_string_lossy(); let context = CustomPropertyContext::create(map, getter, setter); if let Some(ret) = parser::property_value::var::substitute_variable(&expr, &context) { @@ -734,7 +785,7 @@ pub unsafe extern "C" fn substitute_variable( /// Free the string. #[export_name = "FPStrFree"] pub unsafe extern "C" fn str_free(ptr: *const c_char) -> FfiResult { - check_null!((ptr), null()); - drop(CString::from_raw(ptr as *mut _)); + check_null!(ptr, FfiErrorCode::StrNullPointer, null()); + drop(CString::from_raw(ptr as *mut c_char)); FfiResult::ok(null()) } diff --git a/float-pigment-css/src/parser/hooks.rs b/float-pigment-css/src/parser/hooks.rs index 64a9ed1..1bca936 100644 --- a/float-pigment-css/src/parser/hooks.rs +++ b/float-pigment-css/src/parser/hooks.rs @@ -65,7 +65,7 @@ impl CParserHooksContext { use crate::check_null; use crate::ffi::FfiErrorCode; use core::ptr::null; - check_null!((message), null()); + check_null!(message, FfiErrorCode::StrNullPointer, null()); let message = CStr::from_ptr(message).to_string_lossy(); let ctx = &mut *(self.inner as *mut ParserHooksContext); ctx.generate_warning(&message); From 887323fe5d572412118c14c0bdf3071fc31daa4a Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 18:25:30 +0800 Subject: [PATCH 10/12] feat: better ffi error impl --- float-pigment-css/float_pigment_css.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/float-pigment-css/float_pigment_css.h b/float-pigment-css/float_pigment_css.h index 0dc24e6..8f525c9 100644 --- a/float-pigment-css/float_pigment_css.h +++ b/float-pigment-css/float_pigment_css.h @@ -91,8 +91,23 @@ enum class ContainKeyword { enum class FfiErrorCode { None, - NullPointer, + ThisNullPointer, + PathNullPointer, + PrefixNullPointer, + SourceNullPointer, + BufferNullPointer, + ExprPtrNullPointer, + StrNullPointer, + InlineStyleTextNullPointer, + InlineRuleNullPointer, + StyleTextNullPointer, + SelectorTextNullPointer, InvalidPath, + JsonNullPointer, + ArrayNullPointer, + SelectorNullPointer, + StyleSheetNullPointer, + MapNullPointer, Unknown, }; From 599419d20861d849292f673f50cc1eb312f301e1 Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 20:04:16 +0800 Subject: [PATCH 11/12] docs: add ffi docs --- float-pigment-css/src/ffi.rs | 391 ++++++++++++++++++++++++++++++++++- 1 file changed, 387 insertions(+), 4 deletions(-) diff --git a/float-pigment-css/src/ffi.rs b/float-pigment-css/src/ffi.rs index 0b0da45..08847c0 100644 --- a/float-pigment-css/src/ffi.rs +++ b/float-pigment-css/src/ffi.rs @@ -97,14 +97,43 @@ impl FfiResult { } /// # Safety -/// Create a new resource manager. +/// +/// Create a new style sheet resource. +/// +/// This function returns a raw pointer to a heap-allocated style sheet resource. +/// The caller is responsible for eventually freeing this memory using [FPStyleSheetResourceFree]. +/// +/// # Examples +/// +/// ```c +/// FfiResult result = FPStyleSheetResourceNew(); +/// if (result.err != FfiErrorCode::None) { +/// // handle error +/// } +/// RawMutPtr resource = result.value; +/// ``` +/// #[export_name = "FPStyleSheetResourceNew"] pub unsafe extern "C" fn style_sheet_resource_new() -> FfiResult { FfiResult::ok(Box::into_raw(Box::new(group::StyleSheetResource::new())) as RawMutPtr) } /// # Safety -/// Free the resource manager. +/// +/// Free the style sheet resource. +/// +/// This function takes a raw pointer to a style sheet resource +/// and frees the memory allocated for it. +/// +/// # Examples +/// +/// ```c +/// FfiResult result = FPStyleSheetResourceFree(resource); +/// if (result.err != FfiErrorCode::None) { +/// // handle error +/// } +/// ``` +/// #[export_name = "FPStyleSheetResourceFree"] pub unsafe extern "C" fn style_sheet_resource_free(this: RawMutPtr) -> FfiResult { check_null!(this, FfiErrorCode::ThisNullPointer, null()); @@ -113,7 +142,20 @@ pub unsafe extern "C" fn style_sheet_resource_free(this: RawMutPtr) -> FfiResult } /// # Safety -/// Add a tag name prefix to the resource manager. +/// Add a tag name prefix to the resource. +/// +/// This function takes a raw pointer to a style sheet resource, +/// a path to the style sheet, and a prefix to add to the tag name. +/// +/// # Examples +/// +/// ```c +/// FfiResult result = FPStyleSheetResourceAddTagNamePrefix(resource, path, prefix); +/// if (result.err != FfiErrorCode::None) { +/// // handle error +/// } +/// ``` +/// #[export_name = "FPStyleSheetResourceAddTagNamePrefix"] pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( this: RawMutPtr, @@ -132,6 +174,19 @@ pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( /// # Safety /// Serialize the specified style sheet to the JSON format. +/// +/// This function takes a raw pointer to a style sheet resource, +/// a path to the style sheet, and a pointer to a buffer to store the serialized data. +/// +/// # Examples +/// +/// ```c +/// FfiResult result = FPStyleSheetResourceSerializeJson(resource, path, &mut buffer_len); +/// if (result.err != FfiErrorCode::None) { +/// // handle error +/// } +/// ``` +/// #[cfg(all(feature = "serialize", feature = "serialize_json"))] #[export_name = "FPStyleSheetResourceSerializeJson"] pub unsafe extern "C" fn style_sheet_resource_serialize_json( @@ -150,7 +205,18 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_json( } /// # Safety +/// /// Serialize the specified style sheet to the binary format. +/// +/// This function takes a raw pointer to a style sheet resource, +/// a path to the style sheet, and a pointer to a buffer to store the serialized data. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetResourceSerializeBincode(resource, path, &mut buffer_len); +/// ``` +/// #[cfg(feature = "serialize")] #[export_name = "FPStyleSheetResourceSerializeBincode"] pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( @@ -168,7 +234,18 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( FfiResult::ok(ret as *mut u8) } /// # Safety +/// /// Add a style sheet to the resource manager. +/// +/// This function takes a raw pointer to a style sheet resource, +/// a path to the style sheet, and a pointer to a buffer to store the serialized data. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetResourceAddSource(resource, path, source, &mut warnings); +/// ``` +/// #[export_name = "FPStyleSheetResourceAddSource"] pub unsafe extern "C" fn style_sheet_resource_add_source( this: RawMutPtr, @@ -190,7 +267,18 @@ pub unsafe extern "C" fn style_sheet_resource_add_source( } /// # Safety +/// /// Add a style sheet to the resource manager with hooks. +/// +/// This function takes a raw pointer to a style sheet resource, +/// a parser hooks, a path to the style sheet, and a pointer to a buffer to store the warnings. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetResourceAddSourceWithHooks(resource, hooks, path, source, &mut warnings); +/// ``` +/// #[export_name = "FPStyleSheetResourceAddSourceWithHooks"] pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( this: RawMutPtr, @@ -214,6 +302,17 @@ pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( /// # Safety /// Add a style sheet to the resource manager from binary format. +/// +/// This function takes a raw pointer to a style sheet resource, +/// a path to the style sheet, a pointer to a buffer to store the serialized data, +/// a drop function, a drop argument, and a pointer to a buffer to store the warnings. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetResourceAddBincode(resource, path, buffer_ptr, buffer_len, drop_fn, drop_args, &mut warnings); +/// ``` +/// #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetResourceAddBincode"] pub unsafe extern "C" fn style_sheet_resource_add_bincode( @@ -244,6 +343,16 @@ pub unsafe extern "C" fn style_sheet_resource_add_bincode( /// # Safety /// Get the direct dependencies of the specified style sheet. +/// +/// This function takes a raw pointer to a style sheet resource, +/// a path to the style sheet, and returns a pointer to an array of string references. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetResourceDirectDependencies(resource, path); +/// ``` +/// #[export_name = "FPStyleSheetResourceDirectDependencies"] pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( this: RawMutPtr, @@ -259,7 +368,18 @@ pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( } /// # Safety -/// Generate the import index of the resource manager. +/// +/// Generate the import index of the resource. +/// +/// This function takes a raw pointer to a style sheet resource, +/// and returns a pointer to a raw pointer to the import index. +/// +/// # Examples +/// +/// ```c +/// RawMutPtr import_index = FPStyleSheetResourceGenerateImportIndex(resource); +/// ``` +/// #[export_name = "FPStyleSheetResourceGenerateImportIndex"] pub unsafe extern "C" fn style_sheet_resource_generate_import_index( this: RawMutPtr, @@ -290,6 +410,16 @@ impl StyleSheetImportIndex { /// # Safety /// Create a new style sheet import index. +/// +/// This function returns a raw pointer to a heap-allocated style sheet import index. +/// The caller is responsible for eventually freeing this memory using [FPStyleSheetImportIndexFree]. +/// +/// # Examples +/// +/// ```c +/// RawMutPtr import_index = FPStyleSheetImportIndexNew(); +/// ``` +/// #[export_name = "FPStyleSheetImportIndexNew"] pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult { FfiResult::ok( @@ -303,6 +433,16 @@ pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult /// # Safety /// Free the style sheet import index. +/// +/// This function takes a raw pointer to a style sheet import index +/// and frees the memory allocated for it. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexFree(import_index); +/// ``` +/// #[export_name = "FPStyleSheetImportIndexFree"] pub unsafe extern "C" fn style_sheet_import_index_free(this: RawMutPtr) -> FfiResult { check_null!(this, FfiErrorCode::ThisNullPointer, null()); @@ -312,6 +452,16 @@ pub unsafe extern "C" fn style_sheet_import_index_free(this: RawMutPtr) -> FfiRe /// # Safety /// Query and mark the dependencies of the specified style sheet. +/// +/// This function takes a raw pointer to a style sheet import index, +/// a path to the style sheet, and returns a pointer to an array of string references. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexQueryAndMarkDependencies(import_index, path); +/// ``` +/// #[export_name = "FPStyleSheetImportIndexQueryAndMarkDependencies"] pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( this: RawMutPtr, @@ -330,6 +480,16 @@ pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( /// # Safety /// List the dependencies of the specified style sheet. +/// +/// This function takes a raw pointer to a style sheet import index, +/// a path to the style sheet, and returns a pointer to an array of string references. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexListDependencies(import_index, path); +/// ``` +/// #[export_name = "FPStyleSheetImportIndexListDependencies"] pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( this: RawMutPtr, @@ -348,6 +508,16 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( /// # Safety /// List the dependency of the specified style sheet. +/// +/// This function takes a raw pointer to a style sheet import index, +/// a path to the style sheet, and returns a pointer to an array of string references. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexListDependency(import_index, path); +/// ``` +/// #[export_name = "FPStyleSheetImportIndexListDependency"] pub unsafe extern "C" fn style_sheet_import_index_list_dependency( this: RawMutPtr, @@ -363,8 +533,20 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependency( let deps: Vec<_> = deps.into_iter().map(StrRef::from).collect(); FfiResult::ok(Box::into_raw(Box::new(deps.into()))) } + /// # Safety /// Add a style sheet to the import index from binary format. +/// +/// This function takes a raw pointer to a style sheet import index, +/// a path to the style sheet, a pointer to a buffer to store the serialized data, +/// a drop function, a drop argument, and a pointer to a buffer to store the warnings. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexAddBincode(import_index, path, buffer_ptr, buffer_len, drop_fn, drop_args, &mut warnings); +/// ``` +/// #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetImportIndexAddBincode"] pub unsafe extern "C" fn style_sheet_import_index_add_bincode( @@ -424,6 +606,16 @@ pub unsafe extern "C" fn style_sheet_import_index_add_bincode( /// # Safety /// Remove a style sheet from the style sheet import index. +/// +/// This function takes a raw pointer to a style sheet import index, +/// a path to the style sheet, and removes the style sheet from the import index. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexRemoveBincode(import_index, path); +/// ``` +/// #[export_name = "FPStyleSheetImportIndexRemoveBincode"] pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( this: RawMutPtr, @@ -439,6 +631,16 @@ pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( } /// # Safety /// Get the style sheet from the style sheet import index. +/// +/// This function takes a raw pointer to a style sheet import index, +/// a path to the style sheet, and returns a pointer to the style sheet. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexGetStyleSheet(import_index, path); +/// ``` +/// #[export_name = "FPStyleSheetImportIndexGetStyleSheet"] pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( this: RawMutPtr, @@ -456,6 +658,16 @@ pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( } /// # Safety /// Serialize the style sheet import index to the JSON format. +/// +/// This function takes a raw pointer to a style sheet import index, +/// and returns a pointer to the serialized data. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexSerializeJson(import_index, &buffer_len); +/// ``` +/// #[cfg(all(feature = "serialize", feature = "serialize_json"))] #[export_name = "FPStyleSheetImportIndexSerializeJson"] pub unsafe extern "C" fn style_sheet_import_index_serialize_json( @@ -471,6 +683,16 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_json( } /// # Safety /// Serialize the style sheet import index to the binary format. +/// +/// This function takes a raw pointer to a style sheet import index, +/// and returns a pointer to the serialized data. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexSerializeBincode(import_index, &buffer_len); +/// ``` +/// #[cfg(feature = "serialize")] #[export_name = "FPStyleSheetImportIndexSerializeBincode"] pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( @@ -486,6 +708,16 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( } /// # Safety /// Deserialize the style sheet import index from the JSON format. +/// +/// This function takes a raw pointer to the JSON data, +/// and returns a pointer to the deserialized style sheet import index. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexDeserializeJson(json, &import_index); +/// ``` +/// #[cfg(all(feature = "deserialize", feature = "deserialize_json"))] #[export_name = "FPStyleSheetImportIndexDeserializeJson"] pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( @@ -502,6 +734,16 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( ) } /// # Safety +/// Deserialize the style sheet import index from the binary format. +/// +/// This function takes a raw pointer to the binary data, +/// and returns a pointer to the deserialized style sheet import index. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexDeserializeBincode(buffer_ptr, buffer_len, drop_fn, drop_args); +/// ``` /// #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetImportIndexDeserializeBincode"] @@ -527,6 +769,16 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( } /// # Safety /// Merge the style sheet import index from binary format. +/// +/// This function takes a raw pointer to a style sheet import index, +/// a pointer to the binary data, a drop function, and a drop argument. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetImportIndexMergeBincode(import_index, buffer_ptr, buffer_len, drop_fn, drop_args); +/// ``` +/// #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetImportIndexMergeBincode"] pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( @@ -552,6 +804,15 @@ pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( /// # Safety /// Free the buffer. +/// +/// This function takes a pointer to the buffer and the length of the buffer. +/// +/// # Examples +/// +/// ```c +/// FPBufferFree(buffer_ptr, buffer_len); +/// ``` +/// #[export_name = "FPBufferFree"] pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) -> FfiResult { check_null!(buffer_ptr, FfiErrorCode::BufferNullPointer, null()); @@ -562,6 +823,15 @@ pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) -> /// # Safety /// Free the array of string references. +/// +/// This function takes a pointer to the array of string references. +/// +/// # Examples +/// +/// ```c +/// FPArrayStrRefFree(x); +/// ``` +/// #[export_name = "FPArrayStrRefFree"] pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) -> FfiResult { check_null!(x, FfiErrorCode::ArrayNullPointer, null()); @@ -571,6 +841,15 @@ pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) -> FfiResult< /// # Safety /// Free the array of warnings. +/// +/// This function takes a pointer to the array of warnings. +/// +/// # Examples +/// +/// ```c +/// FPArrayWarningFree(warnings); +/// ``` +/// #[export_name = "FPArrayWarningFree"] pub unsafe extern "C" fn array_warning_free( warnings: *mut Array, @@ -582,6 +861,16 @@ pub unsafe extern "C" fn array_warning_free( /// # Safety /// Parse the inline style from the string. +/// +/// This function takes a pointer to the inline style text, +/// a pointer to the array of warnings, and returns a pointer to the inline rule. +/// +/// # Examples +/// +/// ```c +/// FPParseInlineStyle(inline_style_text_ptr, warnings); +/// ``` +/// #[export_name = "FPParseInlineStyle"] pub unsafe extern "C" fn parse_inline_style( inline_style_text_ptr: *const c_char, @@ -624,6 +913,15 @@ pub unsafe extern "C" fn parse_inline_style( /// # Safety /// Free the inline style. +/// +/// This function takes a pointer to the inline style. +/// +/// # Examples +/// +/// ```c +/// FPInlineStyleFree(inline_rule); +/// ``` +/// #[export_name = "FPInlineStyleFree"] pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiResult { check_null!(inline_rule, FfiErrorCode::InlineRuleNullPointer, null()); @@ -633,6 +931,16 @@ pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiR /// # Safety /// Parse the style sheet from the string. +/// +/// This function takes a pointer to the style sheet text, +/// and returns a pointer to the style sheet. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetFromString(style_text_ptr); +/// ``` +/// #[export_name = "FPParseStyleSheetFromString"] pub unsafe extern "C" fn parse_style_sheet_from_string( style_text_ptr: *const c_char, @@ -650,6 +958,16 @@ pub unsafe extern "C" fn parse_style_sheet_from_string( /// # Safety /// Parse the selector from the string. +/// +/// This function takes a pointer to the selector text, +/// and returns a pointer to the selector. +/// +/// # Examples +/// +/// ```c +/// FPParseSelectorFromString(selector_text_ptr); +/// ``` +/// #[export_name = "FPParseSelectorFromString"] pub unsafe extern "C" fn parse_selector_from_string( selector_text_ptr: *const c_char, @@ -666,6 +984,15 @@ pub unsafe extern "C" fn parse_selector_from_string( /// # Safety /// Free the selector. +/// +/// This function takes a pointer to the selector. +/// +/// # Examples +/// +/// ```c +/// FPSelectorFree(selector); +/// ``` +/// #[export_name = "FPSelectorFree"] pub unsafe extern "C" fn selector_free(selector: *mut Selector) -> FfiResult { check_null!(selector, FfiErrorCode::SelectorNullPointer, null()); @@ -675,6 +1002,15 @@ pub unsafe extern "C" fn selector_free(selector: *mut Selector) -> FfiResult FfiResult { check_null!(style_sheet, FfiErrorCode::StyleSheetNullPointer, null()); @@ -684,6 +1020,16 @@ pub unsafe extern "C" fn style_sheet_free(style_sheet: *mut StyleSheet) -> FfiRe /// # Safety /// Get the version of the style sheet in the binary format. +/// +/// This function takes a pointer to the buffer and the length of the buffer, +/// and returns a pointer to the version of the style sheet. +/// +/// # Examples +/// +/// ```c +/// FPStyleSheetBincodeVersion(buffer_ptr, buffer_len); +/// ``` +/// #[cfg(feature = "deserialize")] #[export_name = "FPStyleSheetBincodeVersion"] pub unsafe extern "C" fn style_sheet_bincode_version( @@ -726,6 +1072,14 @@ pub unsafe extern "C" fn style_sheet_bincode_version( /// # Safety /// Get the version of the CSS parser. +/// +/// This function returns a pointer to the version of the CSS parser. +/// +/// # Examples +/// +/// ```c +/// FPCssParserVersion(); +/// ``` #[export_name = "FPCssParserVersion"] pub unsafe extern "C" fn css_parser_version() -> FfiResult<*mut StrRef> { let version = env!("CARGO_PKG_VERSION").to_string().into(); @@ -743,6 +1097,16 @@ pub struct ColorValue { /// # Safety /// Parse the color from the string. +/// +/// This function takes a pointer to the source string, +/// and returns a pointer to the color value. +/// +/// # Examples +/// +/// ```c +/// FPParseColorFromString(source); +/// ``` +/// #[export_name = "FPParseColorFromString"] pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiResult { check_null!( @@ -762,6 +1126,16 @@ pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiRe /// # Safety /// Substitute the variable in the expression. +/// +/// This function takes a pointer to the expression, +/// a pointer to the map, a getter, and a setter. +/// +/// # Examples +/// +/// ```c +/// FPSubstituteVariable(expr_ptr, map, getter, setter); +/// ``` +/// #[export_name = "FPSubstituteVariable"] pub unsafe extern "C" fn substitute_variable( expr_ptr: *const c_char, @@ -783,6 +1157,15 @@ pub unsafe extern "C" fn substitute_variable( /// # Safety /// Free the string. +/// +/// This function takes a pointer to the string. +/// +/// # Examples +/// +/// ```c +/// FPStrFree(ptr); +/// ``` +/// #[export_name = "FPStrFree"] pub unsafe extern "C" fn str_free(ptr: *const c_char) -> FfiResult { check_null!(ptr, FfiErrorCode::StrNullPointer, null()); From a4793ec56a25dea4e4e9aba1b70f2092759a25a1 Mon Sep 17 00:00:00 2001 From: RomChung Date: Thu, 13 Feb 2025 20:14:51 +0800 Subject: [PATCH 12/12] docs: add ffi docs --- float-pigment-css/src/ffi.rs | 196 ++++++++++++++++++++++------------- 1 file changed, 124 insertions(+), 72 deletions(-) diff --git a/float-pigment-css/src/ffi.rs b/float-pigment-css/src/ffi.rs index 08847c0..2f8c40a 100644 --- a/float-pigment-css/src/ffi.rs +++ b/float-pigment-css/src/ffi.rs @@ -100,8 +100,11 @@ impl FfiResult { /// /// Create a new style sheet resource. /// -/// This function returns a raw pointer to a heap-allocated style sheet resource. -/// The caller is responsible for eventually freeing this memory using [FPStyleSheetResourceFree]. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) +/// * `source` - C string pointer to the CSS source content (UTF-8 encoded) +/// * `warnings` - Optional output parameter to receive warnings array pointer /// /// # Examples /// @@ -122,8 +125,8 @@ pub unsafe extern "C" fn style_sheet_resource_new() -> FfiResult { /// /// Free the style sheet resource. /// -/// This function takes a raw pointer to a style sheet resource -/// and frees the memory allocated for it. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance /// /// # Examples /// @@ -144,8 +147,10 @@ pub unsafe extern "C" fn style_sheet_resource_free(this: RawMutPtr) -> FfiResult /// # Safety /// Add a tag name prefix to the resource. /// -/// This function takes a raw pointer to a style sheet resource, -/// a path to the style sheet, and a prefix to add to the tag name. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance +/// * `path` - C string pointer to the stylesheet path (UTF-8 encoded) +/// * `prefix` - C string pointer to the prefix to add to the tag name (UTF-8 encoded) /// /// # Examples /// @@ -175,8 +180,10 @@ pub unsafe extern "C" fn style_sheet_resource_add_tag_name_prefix( /// # Safety /// Serialize the specified style sheet to the JSON format. /// -/// This function takes a raw pointer to a style sheet resource, -/// a path to the style sheet, and a pointer to a buffer to store the serialized data. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance +/// * `path` - C string pointer to the stylesheet path (UTF-8 encoded) +/// * `ret_buffer_len` - Pointer to a variable to store the length of the serialized data /// /// # Examples /// @@ -208,13 +215,18 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_json( /// /// Serialize the specified style sheet to the binary format. /// -/// This function takes a raw pointer to a style sheet resource, -/// a path to the style sheet, and a pointer to a buffer to store the serialized data. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance +/// * `path` - C string pointer to the stylesheet path (UTF-8 encoded) +/// * `ret_buffer_len` - Pointer to a variable to store the length of the serialized data /// /// # Examples /// /// ```c -/// FPStyleSheetResourceSerializeBincode(resource, path, &mut buffer_len); +/// FfiResult result = FPStyleSheetResourceSerializeBincode(resource, path, &mut buffer_len); +/// if (result.err != FfiErrorCode::None) { +/// // handle error +/// } /// ``` /// #[cfg(feature = "serialize")] @@ -237,8 +249,11 @@ pub unsafe extern "C" fn style_sheet_resource_serialize_bincode( /// /// Add a style sheet to the resource manager. /// -/// This function takes a raw pointer to a style sheet resource, -/// a path to the style sheet, and a pointer to a buffer to store the serialized data. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) +/// * `source` - C string pointer to the CSS source content (UTF-8 encoded) +/// * `warnings` - Optional output parameter to receive warnings array pointer /// /// # Examples /// @@ -270,8 +285,12 @@ pub unsafe extern "C" fn style_sheet_resource_add_source( /// /// Add a style sheet to the resource manager with hooks. /// -/// This function takes a raw pointer to a style sheet resource, -/// a parser hooks, a path to the style sheet, and a pointer to a buffer to store the warnings. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance +/// * `hooks` - A parser hooks +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) +/// * `source` - C string pointer to the CSS source content (UTF-8 encoded) +/// * `warnings` - Optional output parameter to receive warnings array pointer /// /// # Examples /// @@ -303,9 +322,14 @@ pub unsafe extern "C" fn style_sheet_resource_add_source_with_hooks( /// # Safety /// Add a style sheet to the resource manager from binary format. /// -/// This function takes a raw pointer to a style sheet resource, -/// a path to the style sheet, a pointer to a buffer to store the serialized data, -/// a drop function, a drop argument, and a pointer to a buffer to store the warnings. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance +/// * `path` - C string pointer to the stylesheet path (UTF-8 encoded) +/// * `buffer_ptr` - Pointer to the buffer to store the serialized data +/// * `buffer_len` - Length of the buffer +/// * `drop_fn` - Optional drop function +/// * `drop_args` - Pointer to the drop argument +/// * `warnings` - Optional output parameter to receive warnings array pointer /// /// # Examples /// @@ -344,8 +368,9 @@ pub unsafe extern "C" fn style_sheet_resource_add_bincode( /// # Safety /// Get the direct dependencies of the specified style sheet. /// -/// This function takes a raw pointer to a style sheet resource, -/// a path to the style sheet, and returns a pointer to an array of string references. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance +/// * `path` - C string pointer to the stylesheet path (UTF-8 encoded) /// /// # Examples /// @@ -371,13 +396,13 @@ pub unsafe extern "C" fn style_sheet_resource_direct_dependencies( /// /// Generate the import index of the resource. /// -/// This function takes a raw pointer to a style sheet resource, -/// and returns a pointer to a raw pointer to the import index. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetResource`] instance /// /// # Examples /// /// ```c -/// RawMutPtr import_index = FPStyleSheetResourceGenerateImportIndex(resource); +/// FPStyleSheetResourceGenerateImportIndex(resource); /// ``` /// #[export_name = "FPStyleSheetResourceGenerateImportIndex"] @@ -411,9 +436,6 @@ impl StyleSheetImportIndex { /// # Safety /// Create a new style sheet import index. /// -/// This function returns a raw pointer to a heap-allocated style sheet import index. -/// The caller is responsible for eventually freeing this memory using [FPStyleSheetImportIndexFree]. -/// /// # Examples /// /// ```c @@ -434,8 +456,8 @@ pub unsafe extern "C" fn style_sheet_import_index_new() -> FfiResult /// # Safety /// Free the style sheet import index. /// -/// This function takes a raw pointer to a style sheet import index -/// and frees the memory allocated for it. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance /// /// # Examples /// @@ -453,8 +475,9 @@ pub unsafe extern "C" fn style_sheet_import_index_free(this: RawMutPtr) -> FfiRe /// # Safety /// Query and mark the dependencies of the specified style sheet. /// -/// This function takes a raw pointer to a style sheet import index, -/// a path to the style sheet, and returns a pointer to an array of string references. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) /// /// # Examples /// @@ -481,8 +504,9 @@ pub unsafe extern "C" fn style_sheet_import_index_query_and_mark_dependencies( /// # Safety /// List the dependencies of the specified style sheet. /// -/// This function takes a raw pointer to a style sheet import index, -/// a path to the style sheet, and returns a pointer to an array of string references. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) /// /// # Examples /// @@ -509,8 +533,9 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependencies( /// # Safety /// List the dependency of the specified style sheet. /// -/// This function takes a raw pointer to a style sheet import index, -/// a path to the style sheet, and returns a pointer to an array of string references. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) /// /// # Examples /// @@ -537,9 +562,14 @@ pub unsafe extern "C" fn style_sheet_import_index_list_dependency( /// # Safety /// Add a style sheet to the import index from binary format. /// -/// This function takes a raw pointer to a style sheet import index, -/// a path to the style sheet, a pointer to a buffer to store the serialized data, -/// a drop function, a drop argument, and a pointer to a buffer to store the warnings. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) +/// * `buffer_ptr` - Pointer to the buffer to store the serialized data +/// * `buffer_len` - Length of the buffer +/// * `drop_fn` - Optional drop function +/// * `drop_args` - Pointer to the drop argument +/// * `warnings` - Optional output parameter to receive warnings array pointer /// /// # Examples /// @@ -607,8 +637,9 @@ pub unsafe extern "C" fn style_sheet_import_index_add_bincode( /// # Safety /// Remove a style sheet from the style sheet import index. /// -/// This function takes a raw pointer to a style sheet import index, -/// a path to the style sheet, and removes the style sheet from the import index. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) /// /// # Examples /// @@ -632,8 +663,9 @@ pub unsafe extern "C" fn style_sheet_import_index_remove_bincode( /// # Safety /// Get the style sheet from the style sheet import index. /// -/// This function takes a raw pointer to a style sheet import index, -/// a path to the style sheet, and returns a pointer to the style sheet. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `path` - C string pointer to the style sheet path (UTF-8 encoded) /// /// # Examples /// @@ -659,8 +691,9 @@ pub unsafe extern "C" fn style_sheet_import_index_get_style_sheet( /// # Safety /// Serialize the style sheet import index to the JSON format. /// -/// This function takes a raw pointer to a style sheet import index, -/// and returns a pointer to the serialized data. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `ret_buffer_len` - Pointer to a variable to store the length of the serialized data /// /// # Examples /// @@ -684,8 +717,9 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_json( /// # Safety /// Serialize the style sheet import index to the binary format. /// -/// This function takes a raw pointer to a style sheet import index, -/// and returns a pointer to the serialized data. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `ret_buffer_len` - Pointer to a variable to store the length of the serialized data /// /// # Examples /// @@ -709,8 +743,8 @@ pub unsafe extern "C" fn style_sheet_import_index_serialize_bincode( /// # Safety /// Deserialize the style sheet import index from the JSON format. /// -/// This function takes a raw pointer to the JSON data, -/// and returns a pointer to the deserialized style sheet import index. +/// # Arguments +/// * `json` - C string pointer to the JSON data /// /// # Examples /// @@ -736,8 +770,11 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_json( /// # Safety /// Deserialize the style sheet import index from the binary format. /// -/// This function takes a raw pointer to the binary data, -/// and returns a pointer to the deserialized style sheet import index. +/// # Arguments +/// * `buffer_ptr` - Pointer to the binary data +/// * `buffer_len` - Length of the binary data +/// * `drop_fn` - Optional drop function +/// * `drop_args` - Pointer to the drop argument /// /// # Examples /// @@ -770,8 +807,12 @@ pub unsafe extern "C" fn style_sheet_import_index_deserialize_bincode( /// # Safety /// Merge the style sheet import index from binary format. /// -/// This function takes a raw pointer to a style sheet import index, -/// a pointer to the binary data, a drop function, and a drop argument. +/// # Arguments +/// * `this` - A raw pointer to a [`StyleSheetImportIndex`] instance +/// * `buffer_ptr` - Pointer to the binary data +/// * `buffer_len` - Length of the binary data +/// * `drop_fn` - Optional drop function +/// * `drop_args` - Pointer to the drop argument /// /// # Examples /// @@ -805,7 +846,9 @@ pub unsafe extern "C" fn style_sheet_import_index_merge_bincode( /// # Safety /// Free the buffer. /// -/// This function takes a pointer to the buffer and the length of the buffer. +/// # Arguments +/// * `buffer_ptr` - Pointer to the buffer +/// * `buffer_len` - Length of the buffer /// /// # Examples /// @@ -824,7 +867,8 @@ pub unsafe extern "C" fn buffer_free(buffer_ptr: *mut u8, buffer_len: usize) -> /// # Safety /// Free the array of string references. /// -/// This function takes a pointer to the array of string references. +/// # Arguments +/// * `x` - Pointer to the array of string references /// /// # Examples /// @@ -842,7 +886,8 @@ pub unsafe extern "C" fn array_str_ref_free(x: *mut Array) -> FfiResult< /// # Safety /// Free the array of warnings. /// -/// This function takes a pointer to the array of warnings. +/// # Arguments +/// * `warnings` - Pointer to the array of warnings /// /// # Examples /// @@ -862,8 +907,9 @@ pub unsafe extern "C" fn array_warning_free( /// # Safety /// Parse the inline style from the string. /// -/// This function takes a pointer to the inline style text, -/// a pointer to the array of warnings, and returns a pointer to the inline rule. +/// # Arguments +/// * `inline_style_text_ptr` - Pointer to the inline style text +/// * `warnings` - Optional output parameter to receive warnings array pointer /// /// # Examples /// @@ -914,7 +960,8 @@ pub unsafe extern "C" fn parse_inline_style( /// # Safety /// Free the inline style. /// -/// This function takes a pointer to the inline style. +/// # Arguments +/// * `inline_rule` - Pointer to the inline style /// /// # Examples /// @@ -932,8 +979,8 @@ pub unsafe extern "C" fn inline_style_free(inline_rule: *mut InlineRule) -> FfiR /// # Safety /// Parse the style sheet from the string. /// -/// This function takes a pointer to the style sheet text, -/// and returns a pointer to the style sheet. +/// # Arguments +/// * `style_text_ptr` - Pointer to the style sheet text /// /// # Examples /// @@ -959,8 +1006,8 @@ pub unsafe extern "C" fn parse_style_sheet_from_string( /// # Safety /// Parse the selector from the string. /// -/// This function takes a pointer to the selector text, -/// and returns a pointer to the selector. +/// # Arguments +/// * `selector_text_ptr` - Pointer to the selector text /// /// # Examples /// @@ -985,7 +1032,8 @@ pub unsafe extern "C" fn parse_selector_from_string( /// # Safety /// Free the selector. /// -/// This function takes a pointer to the selector. +/// # Arguments +/// * `selector` - Pointer to the selector /// /// # Examples /// @@ -1003,7 +1051,8 @@ pub unsafe extern "C" fn selector_free(selector: *mut Selector) -> FfiResult FfiRe /// # Safety /// Get the version of the style sheet in the binary format. /// -/// This function takes a pointer to the buffer and the length of the buffer, -/// and returns a pointer to the version of the style sheet. +/// # Arguments +/// * `buffer_ptr` - Pointer to the buffer +/// * `buffer_len` - Length of the buffer /// /// # Examples /// @@ -1073,8 +1123,6 @@ pub unsafe extern "C" fn style_sheet_bincode_version( /// # Safety /// Get the version of the CSS parser. /// -/// This function returns a pointer to the version of the CSS parser. -/// /// # Examples /// /// ```c @@ -1098,8 +1146,8 @@ pub struct ColorValue { /// # Safety /// Parse the color from the string. /// -/// This function takes a pointer to the source string, -/// and returns a pointer to the color value. +/// # Arguments +/// * `source` - Pointer to the source string /// /// # Examples /// @@ -1127,8 +1175,11 @@ pub unsafe extern "C" fn parse_color_from_string(source: *const c_char) -> FfiRe /// # Safety /// Substitute the variable in the expression. /// -/// This function takes a pointer to the expression, -/// a pointer to the map, a getter, and a setter. +/// # Arguments +/// * `expr_ptr` - Pointer to the expression +/// * `map` - Pointer to the map +/// * `getter` - Custom property getter +/// * `setter` - Custom property setter /// /// # Examples /// @@ -1158,7 +1209,8 @@ pub unsafe extern "C" fn substitute_variable( /// # Safety /// Free the string. /// -/// This function takes a pointer to the string. +/// # Arguments +/// * `ptr` - Pointer to the string /// /// # Examples ///