1use crate::{prelude::*, Data};
2use skia_bindings::{self as sb, SkFlattenable};
3use std::ffi::CStr;
4
5// TODO: getFactory()?
6// TODO: NameToFactory()?
7// TODO: FactoryToName()?
8// TODO: Register()?
9// TODO: getFlattenableType()?
10// TODO: serialize() with SkSerialProcs?
11
12require_type_equality!(sb::SkFlattenable_INHERITED, sb::SkRefCnt);
13
14pub trait Flattenable: Sized {
15 fn type_name(&self) -> &CStr;
16 fn serialize(&self) -> Data;
17 fn deserialize(data: &[u8]) -> Option<Self>;
18}
19
20// TODO: find a way to hide these trait's functions from other crates.
21pub trait NativeFlattenable {
22 fn native_flattenable(&self) -> &SkFlattenable;
23 fn native_deserialize(data: &[u8]) -> *mut Self;
24}
25
26impl<N> Flattenable for RCHandle<N>
27where
28 N: NativeFlattenable + NativeRefCountedBase,
29{
30 fn type_name(&self) -> &CStr {
31 unsafe {
32 CStr::from_ptr(sb::C_SkFlattenable_getTypeName(
33 self.native().native_flattenable(),
34 ))
35 }
36 }
37
38 fn serialize(&self) -> Data {
39 DataOption>::from_ptr(unsafe { sb::C_SkFlattenable_serialize(self.native().native_flattenable()) })
40 .unwrap()
41 }
42
43 fn deserialize(data: &[u8]) -> Option<Self> {
44 RCHandle::from_ptr(N::native_deserialize(data))
45 }
46}
47