float_pigment_css/parser/
hooks.rsuse alloc::vec::Vec;
#[cfg(feature = "ffi")]
use core::ffi::{c_char, CStr};
use cssparser::SourceLocation;
use super::{Warning, WarningKind};
use crate::property::Property;
pub struct ParserHooksContext<'a> {
pub(super) warnings: &'a mut Vec<Warning>,
pub(super) start_loc: SourceLocation,
pub(super) end_loc: SourceLocation,
}
impl<'a> ParserHooksContext<'a> {
pub fn generate_warning(&mut self, message: &str) {
let start = self.start_loc;
let end = self.end_loc;
self.warnings.push(Warning {
kind: WarningKind::HooksGenerated,
message: message.into(),
start_line: start.line,
start_col: start.column,
end_line: end.line,
end_col: end.column,
})
}
}
pub trait Hooks {
fn parsed_property(&mut self, _ctx: &mut ParserHooksContext, _p: &mut Property) {}
}
#[cfg(feature = "ffi")]
#[repr(C)]
pub struct CParserHooksContext {
inner: *mut (),
}
#[cfg(feature = "ffi")]
impl CParserHooksContext {
#[no_mangle]
pub unsafe extern "C" fn generate_warning(&mut self, message: *const c_char) {
let message = CStr::from_ptr(message).to_string_lossy();
let ctx = &mut *(self.inner as *mut ParserHooksContext);
ctx.generate_warning(&message);
}
}
#[cfg(feature = "ffi")]
#[repr(C)]
pub struct CParserHooks {
parsed_property: extern "C" fn(CParserHooksContext, *mut Property),
}
#[cfg(feature = "ffi")]
impl Hooks for CParserHooks {
fn parsed_property(&mut self, ctx: &mut ParserHooksContext, p: &mut Property) {
let ctx = CParserHooksContext {
inner: ctx as *mut _ as *mut (),
};
let f = &mut self.parsed_property;
f(ctx, p);
}
}