Macro ergo::make_collection

source ·
macro_rules! make_collection {
    ($collection_type_name:ident, $item_type_name:ident) => { ... };
}
Expand description

ergo-lib uses a number of collection types that are simple wrappers around Vec. We have a generic type for such a collection in ergo-lib-c-core::collections::Collection. A limitation of cbindgen is that it cannot process generic functions. This macro generates a C-compatible interface for such a collection for any desired type T.

As an example the call make_collection(BlockHeaders, BlockHeader); generates:

pub type BlockHeadersPtr = CollectionPtr<BlockHeader>;
pub type ConstBlockHeadersPtr = ConstCollectionPtr<BlockHeader>;

#[no_mangle]
pub unsafe extern "C" fn ergo_lib_block_headers_new(collection_ptr_out: *mut BlockHeadersPtr) {
    #[allow(clippy::unwrap_used)]
    collection_new(collection_ptr_out).unwrap();
}

#[no_mangle]
pub unsafe extern "C" fn ergo_lib_block_headers_delete(collection_ptr_out: BlockHeadersPtr) {
    collection_delete(collection_ptr_out)
}

#[no_mangle]
pub unsafe extern "C" fn ergo_lib_block_headers_len(
    collection_ptr: ConstBlockHeadersPtr,
) -> usize {
    #[allow(clippy::unwrap_used)]
    collection_len(collection_ptr).unwrap()
}

#[no_mangle]
pub unsafe extern "C" fn ergo_lib_block_headers_get(
    collection_ptr: ConstBlockHeadersPtr,
    index: usize,
    element_ptr_out: *mut BlockHeaderPtr,
) -> ReturnOption {
    match collection_get(collection_ptr, index, element_ptr_out) {
       Ok(is_some) => crate::ReturnOption {
           is_some,
           error: std::ptr::null_mut(),
       },
       Err(e) => crate::ReturnOption {
           is_some: false, // Just a dummy value
           error: Error::c_api_from(Err(e)),
       },
    }
}

#[no_mangle]
pub unsafe extern "C" fn ergo_lib_block_headers_add(
    element_ptr: ConstBlockHeaderPtr,
    collection_ptr_out: BlockHeadersPtr,
) {
    #[allow(clippy::unwrap_used)]
    collection_add(collection_ptr_out, element_ptr).unwrap();
}