use super::*;
#[no_mangle]
pub extern "C" fn dqcs_pdef_new(
typ: dqcs_plugin_type_t,
name: *const c_char,
author: *const c_char,
version: *const c_char,
) -> dqcs_handle_t {
api_return(0, || {
let typ: Result<PluginType> = typ.into();
Ok(insert(PluginDefinition::new(
typ?,
PluginMetadata::new(
receive_optional_str(name)?
.filter(|x| !x.is_empty())
.ok_or_else(oe_inv_arg("plugin name is required"))?,
receive_optional_str(author)?
.filter(|x| !x.is_empty())
.ok_or_else(oe_inv_arg("author name is required"))?,
receive_optional_str(version)?
.filter(|x| !x.is_empty())
.ok_or_else(oe_inv_arg("version string is required"))?,
),
)))
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_type(pdef: dqcs_handle_t) -> dqcs_plugin_type_t {
api_return(dqcs_plugin_type_t::DQCS_PTYPE_INVALID, || {
resolve!(pdef as &PluginDefinition);
Ok(pdef.get_type().into())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_name(pdef: dqcs_handle_t) -> *mut c_char {
api_return_string(|| {
resolve!(pdef as &PluginDefinition);
Ok(pdef.get_metadata().get_name().to_string())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_author(pdef: dqcs_handle_t) -> *mut c_char {
api_return_string(|| {
resolve!(pdef as &PluginDefinition);
Ok(pdef.get_metadata().get_author().to_string())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_version(pdef: dqcs_handle_t) -> *mut c_char {
api_return_string(|| {
resolve!(pdef as &PluginDefinition);
Ok(pdef.get_metadata().get_version().to_string())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_initialize_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
init_cmds: dqcs_handle_t,
) -> dqcs_return_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
pdef.initialize = Box::new(
move |state: &mut PluginState, init_cmds: Vec<ArbCmd>| -> Result<()> {
let init_cmds: ArbCmdQueue = init_cmds.into_iter().collect();
let init_cmds = insert(init_cmds);
let result = cb_return_none(callback(data.data(), state.into(), init_cmds));
delete!(init_cmds);
result
},
);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_drop_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(user_data: *mut c_void, state: dqcs_plugin_state_t) -> dqcs_return_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
pdef.drop = Box::new(move |state: &mut PluginState| -> Result<()> {
cb_return_none(callback(data.data(), state.into()))
});
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_run_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
args: dqcs_handle_t,
) -> dqcs_handle_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
if pdef.get_type() != PluginType::Frontend {
return inv_op("the run() callback is only supported for frontends");
}
pdef.run = Box::new(
move |state: &mut PluginState, args: ArbData| -> Result<ArbData> {
let args = insert(args);
let result =
cb_return(0, callback(data.data(), state.into(), args)).and_then(|arb| {
take!(arb as ArbData);
Ok(arb)
});
delete!(args);
result
},
);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_allocate_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
qubits: dqcs_handle_t,
alloc_cmds: dqcs_handle_t,
) -> dqcs_return_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
if pdef.get_type() == PluginType::Frontend {
return inv_op("the allocate() callback is not supported for frontends");
}
pdef.allocate = Box::new(
move |state: &mut PluginState,
qubits: Vec<QubitRef>,
alloc_cmds: Vec<ArbCmd>|
-> Result<()> {
let qubits: QubitReferenceSet = qubits.into_iter().collect();
let qubits = insert(qubits);
let alloc_cmds: ArbCmdQueue = alloc_cmds.into_iter().collect();
let alloc_cmds = insert(alloc_cmds);
let result =
cb_return_none(callback(data.data(), state.into(), qubits, alloc_cmds));
delete!(qubits);
delete!(alloc_cmds);
result
},
);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_free_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
qubits: dqcs_handle_t,
) -> dqcs_return_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
if pdef.get_type() == PluginType::Frontend {
return inv_op("the free() callback is not supported for frontends");
}
pdef.free = Box::new(
move |state: &mut PluginState, qubits: Vec<QubitRef>| -> Result<()> {
let qubits: QubitReferenceSet = qubits.into_iter().collect();
let qubits = insert(qubits);
let result = cb_return_none(callback(data.data(), state.into(), qubits));
delete!(qubits);
result
},
);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_gate_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
gate: dqcs_handle_t,
) -> dqcs_handle_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
if pdef.get_type() == PluginType::Frontend {
return inv_op("the gate() callback is not supported for frontends");
}
pdef.gate = Box::new(
move |state: &mut PluginState, gate: Gate| -> Result<Vec<QubitMeasurementResult>> {
let gate_handle = insert(gate);
let result = cb_return(0, callback(data.data(), state.into(), gate_handle))
.and_then(|result| {
if result == gate_handle {
Ok(vec![])
} else {
take!(result as QubitMeasurementResultSet);
Ok(result.into_iter().map(|(_, m)| m).collect())
}
});
delete!(gate_handle);
result
},
);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_modify_measurement_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
meas: dqcs_handle_t,
) -> dqcs_handle_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
if pdef.get_type() != PluginType::Operator {
return inv_op("the modify_measurement() callback is only supported for operators");
}
pdef.modify_measurement = Box::new(
move |state: &mut PluginState,
meas: QubitMeasurementResult|
-> Result<Vec<QubitMeasurementResult>> {
let meas_handle = insert(meas);
let result = cb_return(0, callback(data.data(), state.into(), meas_handle))
.and_then(|result| {
take!(result as QubitMeasurementResultSet);
Ok(result.into_iter().map(|(_, m)| m).collect())
});
delete!(meas_handle);
result
},
);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_advance_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
cycles: dqcs_cycle_t,
) -> dqcs_return_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
if pdef.get_type() == PluginType::Frontend {
return inv_op("the advance() callback is not supported for frontends");
}
pdef.advance = Box::new(move |state: &mut PluginState, cycles: u64| -> Result<()> {
cb_return_none(callback(data.data(), state.into(), cycles as dqcs_cycle_t))
});
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_upstream_arb_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
cmd: dqcs_handle_t,
) -> dqcs_handle_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
if pdef.get_type() == PluginType::Frontend {
return inv_op("the upstream_arb() callback is not supported for frontends");
}
pdef.upstream_arb = Box::new(
move |state: &mut PluginState, cmd: ArbCmd| -> Result<ArbData> {
let cmd_handle = insert(cmd);
let result = cb_return(0, callback(data.data(), state.into(), cmd_handle))
.and_then(|result| {
take!(result as ArbData);
Ok(result)
});
delete!(cmd_handle);
result
},
);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_pdef_set_host_arb_cb(
pdef: dqcs_handle_t,
callback: Option<
extern "C" fn(
user_data: *mut c_void,
state: dqcs_plugin_state_t,
cmd: dqcs_handle_t,
) -> dqcs_handle_t,
>,
user_free: Option<extern "C" fn(user_data: *mut c_void)>,
user_data: *mut c_void,
) -> dqcs_return_t {
api_return_none(|| {
let data = CallbackUserData::new(user_free, user_data);
let callback = callback.ok_or_else(oe_inv_arg("callback cannot be null"))?;
resolve!(pdef as &mut PluginDefinition);
pdef.host_arb = Box::new(
move |state: &mut PluginState, cmd: ArbCmd| -> Result<ArbData> {
let cmd_handle = insert(cmd);
let result = cb_return(0, callback(data.data(), state.into(), cmd_handle))
.and_then(|result| {
take!(result as ArbData);
Ok(result)
});
delete!(cmd_handle);
result
},
);
Ok(())
})
}