use phlow::{AnySendObject, ObjectRef, PhlowVTable, PhlowView};
use string_box::StringBox;
use value_box::{BorrowedPtr, ErasedBorrowedPtr, OwnedPtr, ReturnBoxerResult};
#[unsafe(no_mangle)]
pub extern "C" fn phlow_vtable_supports_type_name(phlow_vtable: BorrowedPtr<PhlowVTable>) -> bool {
phlow_vtable
.with_ref_ok(|phlow_vtable| phlow_vtable.supports_type_name())
.or_log(false)
}
#[unsafe(no_mangle)]
pub extern "C" fn phlow_vtable_get_type_name(
phlow_vtable: BorrowedPtr<PhlowVTable>,
mut type_name: BorrowedPtr<StringBox>,
) {
phlow_vtable
.with_ref(|phlow_vtable| {
let vtable_type_name = phlow_vtable.type_name().unwrap_or_default();
type_name.with_mut_ok(|type_name| type_name.set_string(vtable_type_name.to_string()))
})
.log();
}
#[unsafe(no_mangle)]
pub extern "C" fn phlow_vtable_supports_to_string(phlow_vtable: BorrowedPtr<PhlowVTable>) -> bool {
phlow_vtable
.with_ref_ok(|phlow_vtable| phlow_vtable.supports_to_string())
.or_log(false)
}
#[unsafe(no_mangle)]
pub extern "C" fn phlow_vtable_to_string_for_typed_object(
phlow_vtable: BorrowedPtr<PhlowVTable>,
object: ErasedBorrowedPtr,
string: BorrowedPtr<StringBox>,
) {
vtable_to_string_for_object(phlow_vtable, string, |phlow_vtable| {
object
.with_ptr_ok(|ptr| unsafe {
ObjectRef::with_erased_ptr(ptr, |object| phlow_vtable.to_string(object))
})
.or_log(None)
.unwrap_or_default()
});
}
#[unsafe(no_mangle)]
pub extern "C" fn phlow_vtable_to_string_for_any_object(
phlow_vtable: BorrowedPtr<PhlowVTable>,
object: BorrowedPtr<AnySendObject>,
string: BorrowedPtr<StringBox>,
) {
vtable_to_string_for_object(phlow_vtable, string, |phlow_vtable| {
object
.with_ref_ok(|object| {
ObjectRef::with_any(object.as_any(), |object| phlow_vtable.to_string(object))
})
.or_log(None)
.unwrap_or_default()
});
}
#[unsafe(no_mangle)]
pub extern "C" fn phlow_vtable_get_views_for_typed_object(
phlow_vtable: BorrowedPtr<PhlowVTable>,
object: ErasedBorrowedPtr,
) -> OwnedPtr<Vec<Box<dyn PhlowView>>> {
vtable_get_views_for_object(phlow_vtable, |phlow_vtable| {
object
.with_ptr_ok(|ptr| unsafe {
ObjectRef::with_erased_ptr(ptr, |object| phlow_vtable.views(object))
})
.or_log(Vec::new())
})
}
#[unsafe(no_mangle)]
pub extern "C" fn phlow_vtable_get_views_for_any_object(
phlow_vtable: BorrowedPtr<PhlowVTable>,
object: BorrowedPtr<AnySendObject>,
) -> OwnedPtr<Vec<Box<dyn PhlowView>>> {
vtable_get_views_for_object(phlow_vtable, |phlow_vtable| {
object
.with_ref_ok(|object| {
ObjectRef::with_any(object.as_any(), |object| phlow_vtable.views(object))
})
.or_log(Vec::new())
})
}
#[unsafe(no_mangle)]
pub extern "C" fn phlow_vtable_drop(phlow_vtable: OwnedPtr<PhlowVTable>) {
drop(phlow_vtable);
}
fn vtable_to_string_for_object(
phlow_vtable: BorrowedPtr<PhlowVTable>,
mut string: BorrowedPtr<StringBox>,
with_object: impl FnOnce(&PhlowVTable) -> String,
) {
phlow_vtable
.with_ref(|phlow_vtable| {
let object_string = with_object(phlow_vtable);
string.with_mut_ok(|string| string.set_string(object_string))
})
.log();
}
fn vtable_get_views_for_object(
phlow_vtable: BorrowedPtr<PhlowVTable>,
with_object: impl FnOnce(&PhlowVTable) -> Vec<Box<dyn PhlowView>>,
) -> OwnedPtr<Vec<Box<dyn PhlowView>>> {
phlow_vtable
.with_ref_ok(|phlow_vtable| OwnedPtr::new(with_object(phlow_vtable)))
.or_log(OwnedPtr::null())
}