float_pigment_css/parser/
hooks.rs1use alloc::vec::Vec;
4
5#[cfg(feature = "ffi")]
6use core::ffi::{c_char, CStr};
7
8use cssparser::SourceLocation;
9
10use super::{Warning, WarningKind};
11
12#[cfg(feature = "ffi")]
13use crate::ffi::{FfiResult, NullPtr};
14
15use crate::property::Property;
16
17pub struct ParserHooksContext<'a> {
19 pub(super) warnings: &'a mut Vec<Warning>,
20 pub(super) start_loc: SourceLocation,
21 pub(super) end_loc: SourceLocation,
22}
23
24impl<'a> ParserHooksContext<'a> {
25 pub fn generate_warning(&mut self, message: &str) {
27 let start = self.start_loc;
28 let end = self.end_loc;
29 self.warnings.push(Warning {
30 kind: WarningKind::HooksGenerated,
31 message: message.into(),
32 start_line: start.line,
33 start_col: start.column,
34 end_line: end.line,
35 end_col: end.column,
36 })
37 }
38}
39
40pub trait Hooks {
42 fn parsed_property(&mut self, _ctx: &mut ParserHooksContext, _p: &mut Property) {}
44}
45
46#[cfg(feature = "ffi")]
48#[repr(C)]
49pub struct CParserHooksContext {
50 inner: *mut (),
51}
52
53#[cfg(feature = "ffi")]
54impl CParserHooksContext {
55 #[no_mangle]
61 pub unsafe extern "C" fn generate_warning(
62 &mut self,
63 message: *const c_char,
64 ) -> FfiResult<NullPtr> {
65 use crate::check_null;
66 use crate::ffi::FfiErrorCode;
67 use core::ptr::null;
68 check_null!(message, FfiErrorCode::StrNullPointer, null());
69 let message = CStr::from_ptr(message).to_string_lossy();
70 let ctx = &mut *(self.inner as *mut ParserHooksContext);
71 ctx.generate_warning(&message);
72 FfiResult::ok(null())
73 }
74}
75
76#[cfg(feature = "ffi")]
78#[repr(C)]
79pub struct CParserHooks {
80 parsed_property: extern "C" fn(CParserHooksContext, *mut Property),
81}
82
83#[cfg(feature = "ffi")]
84impl Hooks for CParserHooks {
85 fn parsed_property(&mut self, ctx: &mut ParserHooksContext, p: &mut Property) {
86 let ctx = CParserHooksContext {
87 inner: ctx as *mut _ as *mut (),
88 };
89 let f = &mut self.parsed_property;
90 f(ctx, p);
91 }
92}