api work
This commit is contained in:
parent
2eeb8e52f2
commit
1decd333c8
17
veilid-flutter/rust/Cargo.lock
generated
17
veilid-flutter/rust/Cargo.lock
generated
@ -109,6 +109,9 @@ name = "anyhow"
|
||||
version = "1.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
@ -1357,9 +1360,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.112"
|
||||
version = "0.2.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||
checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
@ -2392,9 +2395,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516"
|
||||
checksum = "0f82496b90c36d70af5fcd482edaa2e0bd16fade569de1330405fecbbdac736b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
@ -2432,9 +2435,9 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.85"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
|
||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -2718,10 +2721,12 @@ dependencies = [
|
||||
name = "veilid-flutter"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-std",
|
||||
"cfg-if 1.0.0",
|
||||
"flutter_rust_bridge",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"veilid-core",
|
||||
]
|
||||
|
||||
|
@ -10,7 +10,9 @@ crate-type = ["cdylib", "staticlib"]
|
||||
async-std = { version = "^1", features = ["unstable"] }
|
||||
veilid-core = { path="../../veilid-core" }
|
||||
flutter_rust_bridge = "^1"
|
||||
parking_lot = "^0"
|
||||
log = "^0"
|
||||
anyhow = { version = "^1", features = ["backtrace"] }
|
||||
|
||||
[build-dependencies]
|
||||
cfg-if = "^1"
|
||||
|
@ -83,5 +83,5 @@ fn main() {
|
||||
.wait()
|
||||
.expect("flutter_rust_bridge_codegen was not running");
|
||||
|
||||
println!("cargo:rerun-if-changed=src/api.c");
|
||||
println!("cargo:rerun-if-changed={}", input_path.to_str().unwrap());
|
||||
}
|
||||
|
@ -2,6 +2,13 @@ use std::sync::Arc;
|
||||
use flutter_rust_bridge::*;
|
||||
use log::*;
|
||||
use std::collections::HashMap;
|
||||
use async_std::sync::Mutex as AsyncMutex;
|
||||
use anyhow::*;
|
||||
use std::fmt;
|
||||
|
||||
// Globals
|
||||
|
||||
static API: AsyncMutex<Option<veilid_core::VeilidAPI>> = AsyncMutex::new(None);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Config Settings
|
||||
@ -100,45 +107,45 @@ pub struct VeilidConfigNetwork {
|
||||
pub leases: VeilidConfigLeases,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct VeilidConfigTableStore {
|
||||
pub directory: String,
|
||||
pub delete: bool,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct VeilidConfigBlockStore {
|
||||
pub directory: String,
|
||||
pub delete: bool,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct VeilidConfigProtectedStore {
|
||||
pub allow_insecure_fallback: bool,
|
||||
pub always_use_insecure_storage: bool,
|
||||
pub insecure_fallback_directory: String,
|
||||
pub delete: bool,
|
||||
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct VeilidConfigCapabilities {
|
||||
pub protocol_udp: bool,
|
||||
pub protocol_connect_tcp: bool,
|
||||
pub protocol_accept_tcp: bool,
|
||||
pub protocol_connect_ws: bool,
|
||||
pub protocol_accept_ws: bool,
|
||||
pub protocol_connect_wss: bool,
|
||||
pub protocol_accept_wss: bool,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct VeilidConfig {
|
||||
pub program_name: String,
|
||||
pub namespace: String,
|
||||
pub capabilities: VeilidConfigCapabilities,
|
||||
pub protected_store: VeilidConfigProtectedStore,
|
||||
// Capabilities
|
||||
pub capabilities__protocol_udp: bool,
|
||||
pub capabilities__protocol_connect_tcp: bool,
|
||||
pub capabilities__protocol_accept_tcp: bool,
|
||||
pub capabilities__protocol_connect_ws: bool,
|
||||
pub capabilities__protocol_accept_ws: bool,
|
||||
pub capabilities__protocol_connect_wss: bool,
|
||||
pub capabilities__protocol_accept_wss: bool,
|
||||
// Protected Store
|
||||
pub protected_store__allow_insecure_fallback: bool,
|
||||
pub protected_store__always_use_insecure_storage: bool,
|
||||
pub protected_store__insecure_fallback_directory: String,
|
||||
pub protected_store__delete: bool,
|
||||
// Table Store
|
||||
pub table_store: VeilidConfigTableStore,
|
||||
// Block Store
|
||||
pub block_store: VeilidConfigBlockStore,
|
||||
// Network
|
||||
pub network: VeilidConfigNetwork,
|
||||
}
|
||||
|
||||
@ -173,6 +180,45 @@ pub enum VeilidAPIError {
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Display for VeilidAPIError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
VeilidAPIError::AlreadyInitialized => write!(f, "VeilidAPIError::AlreadyInitialized"),
|
||||
VeilidAPIError::NotInitialized => write!(f, "VeilidAPIError::NotInitialized"),
|
||||
VeilidAPIError::InvalidConfig(e) => write!(f, "VeilidAPIError::InvalidConfig({})", e),
|
||||
VeilidAPIError::Timeout => write!(f, "VeilidAPIError::Timeout"),
|
||||
VeilidAPIError::Shutdown => write!(f, "VeilidAPIError::Shutdown"),
|
||||
VeilidAPIError::NodeNotFound(ni) => write!(f, "VeilidAPIError::NodeNotFound({})", ni),
|
||||
VeilidAPIError::NoDialInfo(ni) => write!(f, "VeilidAPIError::NoDialInfo({})", ni),
|
||||
VeilidAPIError::Internal(e) => write!(f, "VeilidAPIError::Internal({})", e),
|
||||
VeilidAPIError::Unimplemented(e) => write!(f, "VeilidAPIError::Unimplemented({})", e),
|
||||
VeilidAPIError::ParseError { message, value } => {
|
||||
write!(f, "VeilidAPIError::ParseError({}: {})", message, value)
|
||||
}
|
||||
VeilidAPIError::InvalidArgument {
|
||||
context,
|
||||
argument,
|
||||
value,
|
||||
} => {
|
||||
write!(
|
||||
f,
|
||||
"VeilidAPIError::InvalidArgument({}: {} = {})",
|
||||
context, argument, value
|
||||
)
|
||||
}
|
||||
VeilidAPIError::MissingArgument { context, argument } => {
|
||||
write!(
|
||||
f,
|
||||
"VeilidAPIError::MissingArgument({}: {})",
|
||||
context, argument
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for VeilidAPIError {}
|
||||
|
||||
impl VeilidAPIError {
|
||||
fn from_core(api_error: veilid_core::VeilidAPIError) -> Self {
|
||||
match api_error {
|
||||
@ -233,7 +279,7 @@ impl VeilidUpdate {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VeilidState {
|
||||
attachment: AttachmentState,
|
||||
pub attachment: AttachmentState,
|
||||
}
|
||||
|
||||
impl VeilidState {
|
||||
@ -244,142 +290,156 @@ impl VeilidState {
|
||||
}
|
||||
}
|
||||
|
||||
type Result<T> = std::result::Result<T, VeilidAPIError>;
|
||||
|
||||
/////////////////////////////////////////
|
||||
pub fn startup_veilid_core(sink: StreamSink<VeilidUpdate>, config: VeilidConfig) -> Result<VeilidState> {
|
||||
let core = veilid_core::VeilidCore::new();
|
||||
|
||||
// convert config to hashmap
|
||||
let config_map = HashMap::<String, Box<dyn core::any::Any + 'static>>::new();
|
||||
macro_rules! get_config {
|
||||
($key:expr) => {
|
||||
config_map.insert(stringify!($key)[7..].to_owned(), Box::new($key.clone()));
|
||||
}
|
||||
}
|
||||
macro_rules! default_config {
|
||||
($key:expr, $default_value:expr) => {
|
||||
config_map.insert(stringify!($key)[7..].to_owned(), Box::new($default_value));
|
||||
}
|
||||
}
|
||||
get_config!(config.program_name);
|
||||
get_config!(config.namespace);
|
||||
get_config!(config.capabilities.protocol_udp);
|
||||
get_config!(config.capabilities.protocol_connect_tcp);
|
||||
get_config!(config.capabilities.protocol_accept_tcp);
|
||||
get_config!(config.capabilities.protocol_connect_ws);
|
||||
get_config!(config.capabilities.protocol_accept_ws);
|
||||
get_config!(config.capabilities.protocol_connect_wss);
|
||||
get_config!(config.capabilities.protocol_accept_wss);
|
||||
get_config!(config.table_store.directory);
|
||||
get_config!(config.table_store.delete);
|
||||
get_config!(config.block_store.directory);
|
||||
get_config!(config.block_store.delete);
|
||||
get_config!(config.protected_store.allow_insecure_fallback);
|
||||
get_config!(config.protected_store.always_use_insecure_storage);
|
||||
get_config!(config.protected_store.insecure_fallback_directory);
|
||||
get_config!(config.protected_store.delete);
|
||||
get_config!(config.network.node_id);
|
||||
get_config!(config.network.node_id_secret);
|
||||
get_config!(config.network.max_connections);
|
||||
get_config!(config.network.connection_initial_timeout);
|
||||
get_config!(config.network.bootstrap);
|
||||
get_config!(config.network.dht.resolve_node_timeout);
|
||||
get_config!(config.network.dht.resolve_node_count);
|
||||
get_config!(config.network.dht.resolve_node_fanout);
|
||||
get_config!(config.network.dht.max_find_node_count);
|
||||
get_config!(config.network.dht.get_value_timeout);
|
||||
get_config!(config.network.dht.get_value_count);
|
||||
get_config!(config.network.dht.get_value_fanout);
|
||||
get_config!(config.network.dht.set_value_timeout);
|
||||
get_config!(config.network.dht.set_value_count);
|
||||
get_config!(config.network.dht.set_value_fanout);
|
||||
get_config!(config.network.dht.min_peer_count);
|
||||
get_config!(config.network.dht.min_peer_refresh_time);
|
||||
get_config!(config.network.dht.validate_dial_info_receipt_time);
|
||||
get_config!(config.network.rpc.concurrency);
|
||||
get_config!(config.network.rpc.queue_size);
|
||||
get_config!(config.network.rpc.max_timestamp_behind);
|
||||
get_config!(config.network.rpc.max_timestamp_ahead);
|
||||
get_config!(config.network.rpc.timeout);
|
||||
get_config!(config.network.rpc.max_route_hop_count);
|
||||
get_config!(config.network.upnp);
|
||||
get_config!(config.network.natpmp);
|
||||
get_config!(config.network.enable_local_peer_scope);
|
||||
get_config!(config.network.restricted_nat_retries);
|
||||
default_config!(config.network.tls.certificate_path, "");
|
||||
default_config!(config.network.tls.private_key_path, "");
|
||||
default_config!(config.network.tls.connection_initial_timeout, 0u64);
|
||||
default_config!(config.network.application.https.enabled, false);
|
||||
default_config!(config.network.application.https.listen_address, "");
|
||||
default_config!(config.network.application.https.path, "");
|
||||
default_config!(config.network.application.https.url, Option::<String>::None);
|
||||
default_config!(config.network.application.http.enabled, false);
|
||||
default_config!(config.network.application.http.listen_address, "");
|
||||
default_config!(config.network.application.http.path, "");
|
||||
default_config!(config.network.application.http.url, Option::<String>::None);
|
||||
get_config!(config.network.protocol.udp.enabled);
|
||||
get_config!(config.network.protocol.udp.socket_pool_size);
|
||||
get_config!(config.network.protocol.udp.listen_address);
|
||||
get_config!(config.network.protocol.udp.public_address);
|
||||
get_config!(config.network.protocol.tcp.connect);
|
||||
get_config!(config.network.protocol.tcp.listen);
|
||||
get_config!(config.network.protocol.tcp.max_connections);
|
||||
get_config!(config.network.protocol.tcp.listen_address);
|
||||
get_config!(config.network.protocol.tcp.public_address);
|
||||
get_config!(config.network.protocol.ws.connect);
|
||||
get_config!(config.network.protocol.ws.listen);
|
||||
get_config!(config.network.protocol.ws.max_connections);
|
||||
get_config!(config.network.protocol.ws.listen_address);
|
||||
get_config!(config.network.protocol.ws.path);
|
||||
get_config!(config.network.protocol.ws.url);
|
||||
get_config!(config.network.protocol.wss.connect);
|
||||
default_config!(config.network.protocol.wss.listen, false);
|
||||
get_config!(config.network.protocol.wss.max_connections);
|
||||
default_config!(config.network.protocol.wss.listen_address, "");
|
||||
default_config!(config.network.protocol.wss.path, "");
|
||||
default_config!(config.network.protocol.wss.url, Option::<String>::None);
|
||||
get_config!(config.network.leases.max_server_signal_leases);
|
||||
get_config!(config.network.leases.max_server_relay_leases);
|
||||
get_config!(config.network.leases.max_client_signal_leases);
|
||||
get_config!(config.network.leases.max_client_relay_leases);
|
||||
|
||||
let setup = veilid_core::VeilidCoreSetup {
|
||||
update_callback: Arc::new(
|
||||
move |update: veilid_core::VeilidUpdate| -> veilid_core::SystemPinBoxFuture<()> {
|
||||
Box::pin(async move {
|
||||
if !sink.add(VeilidUpdate::from_core(update)) {
|
||||
error!("error sending veilid update callback");
|
||||
}
|
||||
})
|
||||
},
|
||||
),
|
||||
config_callback: Arc::new(
|
||||
move |key| {
|
||||
config_map.get(&key).ok_or_else(|| {
|
||||
let err = format!("config key '{}' doesn't exist", key);
|
||||
error!("{}",err);
|
||||
err
|
||||
}).map(|v| {
|
||||
*v.clone()
|
||||
})
|
||||
}
|
||||
),
|
||||
};
|
||||
|
||||
async_std::task::block_on( async {
|
||||
let api = core.startup(setup).await.map_err(|e| VeilidAPIError::InvalidConfig(e.clone()))?;
|
||||
let core_state = api.get_state().await.map_err(VeilidAPIError::from_core)?;
|
||||
|
||||
let api = API.lock().await;
|
||||
if api.is_some() {
|
||||
return Err(anyhow!(VeilidAPIError::AlreadyInitialized));
|
||||
}
|
||||
|
||||
let core = veilid_core::VeilidCore::new();
|
||||
|
||||
// convert config to hashmap
|
||||
let config_map = HashMap::<String, Box<dyn core::any::Any + Send + 'static>>::new();
|
||||
macro_rules! get_config {
|
||||
($key:expr) => {
|
||||
config_map.insert(stringify!($key)[7..].to_owned(), Box::new($key.clone()));
|
||||
}
|
||||
}
|
||||
macro_rules! default_config {
|
||||
($key:expr, $default_value:expr) => {
|
||||
config_map.insert(stringify!($key)[7..].to_owned(), Box::new($default_value));
|
||||
}
|
||||
}
|
||||
get_config!(config.program_name);
|
||||
get_config!(config.namespace);
|
||||
get_config!(config.capabilities.protocol_udp);
|
||||
get_config!(config.capabilities.protocol_connect_tcp);
|
||||
get_config!(config.capabilities.protocol_accept_tcp);
|
||||
get_config!(config.capabilities.protocol_connect_ws);
|
||||
get_config!(config.capabilities.protocol_accept_ws);
|
||||
get_config!(config.capabilities.protocol_connect_wss);
|
||||
get_config!(config.capabilities.protocol_accept_wss);
|
||||
get_config!(config.table_store.directory);
|
||||
get_config!(config.table_store.delete);
|
||||
get_config!(config.block_store.directory);
|
||||
get_config!(config.block_store.delete);
|
||||
get_config!(config.protected_store.allow_insecure_fallback);
|
||||
get_config!(config.protected_store.always_use_insecure_storage);
|
||||
get_config!(config.protected_store.insecure_fallback_directory);
|
||||
get_config!(config.protected_store.delete);
|
||||
get_config!(config.network.node_id);
|
||||
get_config!(config.network.node_id_secret);
|
||||
get_config!(config.network.max_connections);
|
||||
get_config!(config.network.connection_initial_timeout);
|
||||
get_config!(config.network.bootstrap);
|
||||
get_config!(config.network.dht.resolve_node_timeout);
|
||||
get_config!(config.network.dht.resolve_node_count);
|
||||
get_config!(config.network.dht.resolve_node_fanout);
|
||||
get_config!(config.network.dht.max_find_node_count);
|
||||
get_config!(config.network.dht.get_value_timeout);
|
||||
get_config!(config.network.dht.get_value_count);
|
||||
get_config!(config.network.dht.get_value_fanout);
|
||||
get_config!(config.network.dht.set_value_timeout);
|
||||
get_config!(config.network.dht.set_value_count);
|
||||
get_config!(config.network.dht.set_value_fanout);
|
||||
get_config!(config.network.dht.min_peer_count);
|
||||
get_config!(config.network.dht.min_peer_refresh_time);
|
||||
get_config!(config.network.dht.validate_dial_info_receipt_time);
|
||||
get_config!(config.network.rpc.concurrency);
|
||||
get_config!(config.network.rpc.queue_size);
|
||||
get_config!(config.network.rpc.max_timestamp_behind);
|
||||
get_config!(config.network.rpc.max_timestamp_ahead);
|
||||
get_config!(config.network.rpc.timeout);
|
||||
get_config!(config.network.rpc.max_route_hop_count);
|
||||
get_config!(config.network.upnp);
|
||||
get_config!(config.network.natpmp);
|
||||
get_config!(config.network.enable_local_peer_scope);
|
||||
get_config!(config.network.restricted_nat_retries);
|
||||
default_config!(config.network.tls.certificate_path, "");
|
||||
default_config!(config.network.tls.private_key_path, "");
|
||||
default_config!(config.network.tls.connection_initial_timeout, 0u64);
|
||||
default_config!(config.network.application.https.enabled, false);
|
||||
default_config!(config.network.application.https.listen_address, "");
|
||||
default_config!(config.network.application.https.path, "");
|
||||
default_config!(config.network.application.https.url, Option::<String>::None);
|
||||
default_config!(config.network.application.http.enabled, false);
|
||||
default_config!(config.network.application.http.listen_address, "");
|
||||
default_config!(config.network.application.http.path, "");
|
||||
default_config!(config.network.application.http.url, Option::<String>::None);
|
||||
get_config!(config.network.protocol.udp.enabled);
|
||||
get_config!(config.network.protocol.udp.socket_pool_size);
|
||||
get_config!(config.network.protocol.udp.listen_address);
|
||||
get_config!(config.network.protocol.udp.public_address);
|
||||
get_config!(config.network.protocol.tcp.connect);
|
||||
get_config!(config.network.protocol.tcp.listen);
|
||||
get_config!(config.network.protocol.tcp.max_connections);
|
||||
get_config!(config.network.protocol.tcp.listen_address);
|
||||
get_config!(config.network.protocol.tcp.public_address);
|
||||
get_config!(config.network.protocol.ws.connect);
|
||||
get_config!(config.network.protocol.ws.listen);
|
||||
get_config!(config.network.protocol.ws.max_connections);
|
||||
get_config!(config.network.protocol.ws.listen_address);
|
||||
get_config!(config.network.protocol.ws.path);
|
||||
get_config!(config.network.protocol.ws.url);
|
||||
get_config!(config.network.protocol.wss.connect);
|
||||
default_config!(config.network.protocol.wss.listen, false);
|
||||
get_config!(config.network.protocol.wss.max_connections);
|
||||
default_config!(config.network.protocol.wss.listen_address, "");
|
||||
default_config!(config.network.protocol.wss.path, "");
|
||||
default_config!(config.network.protocol.wss.url, Option::<String>::None);
|
||||
get_config!(config.network.leases.max_server_signal_leases);
|
||||
get_config!(config.network.leases.max_server_relay_leases);
|
||||
get_config!(config.network.leases.max_client_signal_leases);
|
||||
get_config!(config.network.leases.max_client_relay_leases);
|
||||
|
||||
let setup = veilid_core::VeilidCoreSetup {
|
||||
update_callback: Arc::new(
|
||||
move |update: veilid_core::VeilidUpdate| -> veilid_core::SystemPinBoxFuture<()> {
|
||||
Box::pin(async move {
|
||||
if !sink.add(VeilidUpdate::from_core(update)) {
|
||||
error!("error sending veilid update callback");
|
||||
}
|
||||
})
|
||||
},
|
||||
),
|
||||
config_callback: Arc::new(
|
||||
move |key| {
|
||||
config_map.get(&key).ok_or_else(|| {
|
||||
let err = format!("config key '{}' doesn't exist", key);
|
||||
error!("{}",err);
|
||||
err
|
||||
}).map(|v| {
|
||||
*v.clone()
|
||||
})
|
||||
}
|
||||
),
|
||||
};
|
||||
|
||||
let veilid_api = core.startup(setup).await.map_err(|e| VeilidAPIError::InvalidConfig(e.clone()))?;
|
||||
*api = Some(veilid_api.clone());
|
||||
|
||||
let core_state = veilid_api.get_state().await.map_err(VeilidAPIError::from_core)?;
|
||||
Ok(VeilidState::from_core(core_state))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_veilid_state() -> Result<VeilidState> {
|
||||
|
||||
async_std::task::block_on( async {
|
||||
let veilid_api = API.lock().await.ok_or(anyhow!(VeilidAPIError::NotInitialized))?;
|
||||
let core_state = veilid_api.get_state().await.map_err(VeilidAPIError::from_core)?;
|
||||
Ok(VeilidState::from_core(core_state))
|
||||
})
|
||||
}
|
||||
|
||||
// xxx api functions
|
||||
|
||||
pub fn shutdown_veilid_core() -> Result<()> {
|
||||
|
||||
async_std::task::block_on( async {
|
||||
let veilid_api = API.lock().await.take().ok_or(anyhow!(VeilidAPIError::NotInitialized))?;
|
||||
veilid_api.shutdown().await;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user