ergo_lib_c_core/
context_extension.rs

1use crate::constant::{ConstConstantPtr, Constant, ConstantPtr};
2use crate::{
3    util::{const_ptr_as_ref, mut_ptr_as_mut},
4    Error,
5};
6use ergo_lib::ergotree_interpreter::sigma_protocol::prover;
7
8/// User-defined variables to be put into context
9#[derive(PartialEq, Eq, Debug, Clone)]
10pub struct ContextExtension(pub prover::ContextExtension);
11pub type ContextExtensionPtr = *mut ContextExtension;
12pub type ConstContextExtensionPtr = *const ContextExtension;
13
14/// Create new empty ContextExtension instance
15pub unsafe fn context_extension_empty(
16    context_extension_out: *mut ContextExtensionPtr,
17) -> Result<(), Error> {
18    let context_extension_out = mut_ptr_as_mut(context_extension_out, "context_extension_out")?;
19    *context_extension_out = Box::into_raw(Box::new(ContextExtension(
20        prover::ContextExtension::empty(),
21    )));
22    Ok(())
23}
24
25/// Returns the number of elements in the collection
26pub unsafe fn context_extension_len(
27    context_extension_ptr: ConstContextExtensionPtr,
28) -> Result<usize, Error> {
29    let context_extension = const_ptr_as_ref(context_extension_ptr, "context_extension_ptr")?;
30    Ok(context_extension.0.values.len())
31}
32
33/// Returns all keys (represented as u8 values) in the map
34pub unsafe fn context_extension_keys(
35    context_extension_ptr: ConstContextExtensionPtr,
36    output: *mut u8,
37) -> Result<(), Error> {
38    let context_extension = const_ptr_as_ref(context_extension_ptr, "context_extension_ptr")?;
39    let src: Vec<_> = context_extension.0.values.keys().cloned().collect();
40    std::ptr::copy_nonoverlapping(src.as_ptr(), output, src.len());
41    Ok(())
42}
43
44/// Get value for key or fail if key is missing
45pub unsafe fn context_extension_get(
46    context_extension_ptr: ConstContextExtensionPtr,
47    key: u8,
48    constant_out: *mut ConstantPtr,
49) -> Result<bool, Error> {
50    let context_extension = const_ptr_as_ref(context_extension_ptr, "context_extension_ptr")?;
51    let constant_out = mut_ptr_as_mut(constant_out, "constant_out")?;
52    let constant = context_extension
53        .0
54        .values
55        .get(&key)
56        .map(|c| Constant(c.clone()));
57
58    if let Some(constant) = constant {
59        *constant_out = Box::into_raw(Box::new(constant));
60        Ok(true)
61    } else {
62        Ok(false)
63    }
64}
65
66/// Set the supplied pair in the ContextExtension
67pub unsafe fn context_extension_set_pair(
68    constant_ptr: ConstConstantPtr,
69    key: u8,
70    context_extension_ptr: ContextExtensionPtr,
71) -> Result<(), Error> {
72    let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
73    let context_extension = mut_ptr_as_mut(context_extension_ptr, "context_extension_ptr")?;
74    context_extension.0.values.insert(key, constant.0.clone());
75    Ok(())
76}