phlow-ffi 3.0.0

Provides C-like api to the phlow crates
Documentation
use phlow::{AnySendObject, InfoViewInstance, ObjectRef, ViewInstance};
use string_box::StringBox;
use value_box::{BorrowedPtr, BoxerError, ErasedBorrowedPtr, OwnedPtr, ReturnBoxerResult};

use crate::with_view_instance;

#[unsafe(no_mangle)]
pub extern "C" fn phlow_info_view_instance_get_rows_count(
    view_instance: BorrowedPtr<Box<dyn ViewInstance>>,
) -> usize {
    with_view_instance(view_instance, |view_instance: &InfoViewInstance| {
        Ok(view_instance.rows.len())
    })
    .or_log(0)
}

#[unsafe(no_mangle)]
pub extern "C" fn phlow_info_view_instance_get_row_name_at(
    view_instance: BorrowedPtr<Box<dyn ViewInstance>>,
    index: usize,
    mut row_name: BorrowedPtr<StringBox>,
) {
    with_view_instance(view_instance, |view_instance: &InfoViewInstance| {
        view_instance
            .rows
            .get(index)
            .ok_or_else(|| {
                BoxerError::AnyError(format!("Info row at {} does not exist", index).into())
            })
            .and_then(|row| row_name.with_mut_ok(|row_name| row_name.set_string(row.name.clone())))
    })
    .log();
}

#[unsafe(no_mangle)]
pub extern "C" fn phlow_info_view_instance_get_row_text_at(
    view_instance: BorrowedPtr<Box<dyn ViewInstance>>,
    index: usize,
    mut row_text: BorrowedPtr<StringBox>,
) {
    with_view_instance(view_instance, |view_instance: &InfoViewInstance| {
        view_instance
            .rows
            .get(index)
            .ok_or_else(|| {
                BoxerError::AnyError(format!("Info row at {} does not exist", index).into())
            })
            .and_then(|row| row_text.with_mut_ok(|row_text| row_text.set_string(row.text.clone())))
    })
    .log();
}

#[unsafe(no_mangle)]
pub extern "C" fn phlow_info_view_instance_get_row_send_at_for_typed_object(
    view_instance: BorrowedPtr<Box<dyn ViewInstance>>,
    index: usize,
    object: ErasedBorrowedPtr,
) -> OwnedPtr<AnySendObject> {
    with_view_instance(view_instance, |view_instance: &InfoViewInstance| {
        view_instance
            .rows
            .get(index)
            .ok_or_else(|| {
                BoxerError::AnyError(format!("Info row at {} does not exist", index).into())
            })
            .and_then(|row| {
                object.with_ptr_ok(|ptr| unsafe {
                    ObjectRef::with_erased_ptr(ptr, |object| (row.send_computation)(object))
                        .map_or(OwnedPtr::null(), OwnedPtr::new)
                })
            })
    })
    .or_log(OwnedPtr::null())
}

#[unsafe(no_mangle)]
pub extern "C" fn phlow_info_view_instance_get_row_send_at_for_any_object(
    view_instance: BorrowedPtr<Box<dyn ViewInstance>>,
    index: usize,
    object: BorrowedPtr<AnySendObject>,
) -> OwnedPtr<AnySendObject> {
    with_view_instance(view_instance, |view_instance: &InfoViewInstance| {
        view_instance
            .rows
            .get(index)
            .ok_or_else(|| {
                BoxerError::AnyError(format!("Info row at {} does not exist", index).into())
            })
            .and_then(|row| {
                object.with_ref_ok(|ptr| {
                    ObjectRef::with_any(ptr.as_any(), |object| (row.send_computation)(object))
                        .map_or(OwnedPtr::null(), OwnedPtr::new)
                })
            })
    })
    .or_log(OwnedPtr::null())
}