fix wasm, flutter work
This commit is contained in:
2
veilid-flutter/rust/.gitignore
vendored
2
veilid-flutter/rust/.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
src/bridge_generated.rs
|
||||
|
||||
##############################################################################
|
||||
### MacOS
|
||||
|
||||
|
3059
veilid-flutter/rust/Cargo.lock
generated
Normal file
3059
veilid-flutter/rust/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,9 +4,13 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
crate-type = ["cdylib", "staticlib"]
|
||||
|
||||
[dependencies]
|
||||
async-std = { version = "^1", features = ["unstable"] }
|
||||
veilid-core = { path="../../veilid-core" }
|
||||
flutter_rust_bridge = "^1"
|
||||
log = "^0"
|
||||
|
||||
[build-dependencies]
|
||||
cfg-if = "^1"
|
||||
|
87
veilid-flutter/rust/build.rs
Normal file
87
veilid-flutter/rust/build.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use cfg_if::*;
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
fn resolve_llvm_path() -> Option<PathBuf> {
|
||||
let paths: Vec<PathBuf> =
|
||||
env::var_os("PATH").map(|paths| env::split_paths(&paths).collect())?;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_os="linux")] {
|
||||
// build host is linux
|
||||
|
||||
// find clang
|
||||
let d = paths.iter().find_map(|p| {
|
||||
if p.join("clang").exists() {
|
||||
if let Ok(real_clang_path) = fs::canonicalize(p.join("clang")) {
|
||||
if let Some(llvmbindir) = real_clang_path.parent() {
|
||||
if let Some(llvmdir) = llvmbindir.parent() {
|
||||
return Some(llvmdir.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
});
|
||||
|
||||
d.or_else(|| {
|
||||
["/usr/lib/llvm-13", "/usr/lib/llvm-12", "/usr/lib/llvm-11", "/usr/lib/llvm-10"].iter().map(Path::new).find_map(|p| if p.exists() { Some(p.to_owned()) } else { None } )
|
||||
})
|
||||
|
||||
} else if #[cfg(target_os="macos")] {
|
||||
// build host is mac
|
||||
["/opt/homebrew/opt/llvm", "/usr/local/homebrew/opt/llvm"].iter().map(Path::new).find_map(|p| if p.exists() { Some(p.to_owned()) } else { None } )
|
||||
} else {
|
||||
// anywhere else, just use the default paths
|
||||
llvm_path = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
//let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
|
||||
|
||||
let input_path = Path::new(&manifest_dir).join("src").join("api.rs");
|
||||
let output_path = Path::new(&manifest_dir)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("lib")
|
||||
.join("bridge_generated.dart");
|
||||
let llvm_path = resolve_llvm_path();
|
||||
|
||||
eprintln!("input_path: {:?}", input_path);
|
||||
eprintln!("output_path: {:?}", output_path);
|
||||
eprintln!("llvm_path: {:?}", llvm_path);
|
||||
|
||||
let mut command = Command::new("flutter_rust_bridge_codegen");
|
||||
if let Some(llvm_path) = llvm_path {
|
||||
command.args([
|
||||
OsStr::new("--rust-input"),
|
||||
input_path.as_os_str(),
|
||||
OsStr::new("--dart-output"),
|
||||
output_path.as_os_str(),
|
||||
OsStr::new("--llvm-path"),
|
||||
llvm_path.as_os_str(),
|
||||
]);
|
||||
} else {
|
||||
command.args([
|
||||
OsStr::new("--rust-input"),
|
||||
input_path.as_os_str(),
|
||||
OsStr::new("--dart-output"),
|
||||
output_path.as_os_str(),
|
||||
]);
|
||||
}
|
||||
|
||||
let mut child = command
|
||||
.spawn()
|
||||
.expect("flutter_rust_bridge_codegen did not execute correctly");
|
||||
child
|
||||
.wait()
|
||||
.expect("flutter_rust_bridge_codegen was not running");
|
||||
|
||||
println!("cargo:rerun-if-changed=src/api.c");
|
||||
}
|
@@ -1,4 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
use flutter_rust_bridge::*;
|
||||
use log::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Config Settings
|
||||
@@ -84,8 +87,8 @@ pub struct VeilidConfigLeases {
|
||||
pub struct VeilidConfigNetwork {
|
||||
pub max_connections: u32,
|
||||
pub connection_initial_timeout: u64,
|
||||
pub node_id: key::DHTKey,
|
||||
pub node_id_secret: key::DHTKeySecret,
|
||||
pub node_id: String,
|
||||
pub node_id_secret: String,
|
||||
pub bootstrap: Vec<String>,
|
||||
pub rpc: VeilidConfigRPC,
|
||||
pub dht: VeilidConfigDHT,
|
||||
@@ -93,7 +96,6 @@ pub struct VeilidConfigNetwork {
|
||||
pub natpmp: bool,
|
||||
pub enable_local_peer_scope: bool,
|
||||
pub restricted_nat_retries: u32,
|
||||
pub tls: VeilidConfigTLS,
|
||||
pub protocol: VeilidConfigProtocol,
|
||||
pub leases: VeilidConfigLeases,
|
||||
}
|
||||
@@ -146,10 +148,10 @@ pub struct VeilidConfig {
|
||||
/////////////////////////////////////////
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum APIErrorKind {
|
||||
pub enum VeilidAPIError {
|
||||
AlreadyInitialized,
|
||||
NotInitialized,
|
||||
InvalidConfig,
|
||||
InvalidConfig(String),
|
||||
Timeout,
|
||||
Shutdown,
|
||||
NodeNotFound(String),
|
||||
@@ -171,10 +173,20 @@ pub enum APIErrorKind {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VeilidAPIError {
|
||||
kind: APIErrorKind,
|
||||
message: String,
|
||||
impl VeilidAPIError {
|
||||
fn from_core(api_error: veilid_core::VeilidAPIError) -> Self {
|
||||
match api_error {
|
||||
veilid_core::VeilidAPIError::Timeout => VeilidAPIError::Timeout,
|
||||
veilid_core::VeilidAPIError::Shutdown => VeilidAPIError::Shutdown,
|
||||
veilid_core::VeilidAPIError::NodeNotFound(node_id) => VeilidAPIError::NodeNotFound(format!("{}",node_id)),
|
||||
veilid_core::VeilidAPIError::NoDialInfo(node_id) => VeilidAPIError::NodeNotFound(format!("{}",node_id)),
|
||||
veilid_core::VeilidAPIError::Internal(msg) => VeilidAPIError::Internal(msg.clone()),
|
||||
veilid_core::VeilidAPIError::Unimplemented(msg)=> VeilidAPIError::Unimplemented(msg.clone()),
|
||||
veilid_core::VeilidAPIError::ParseError{message, value} => VeilidAPIError::ParseError{ message: message.clone(), value: value.clone() },
|
||||
veilid_core::VeilidAPIError::InvalidArgument { context, argument, value } => VeilidAPIError::InvalidArgument{ context: context.clone(), argument: argument.clone(), value: value.clone() },
|
||||
veilid_core::VeilidAPIError::MissingArgument {context, argument } => VeilidAPIError::MissingArgument{ context: context.clone(), argument: argument.clone() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -189,25 +201,185 @@ pub enum AttachmentState {
|
||||
Detaching,
|
||||
}
|
||||
|
||||
impl AttachmentState {
|
||||
fn from_core(attachment_state: veilid_core::AttachmentState) -> Self {
|
||||
match attachment_state {
|
||||
veilid_core::AttachmentState::Detached => AttachmentState::Detached,
|
||||
veilid_core::AttachmentState::Attaching=> AttachmentState::Attaching,
|
||||
veilid_core::AttachmentState::AttachedWeak=> AttachmentState::AttachedWeak,
|
||||
veilid_core::AttachmentState::AttachedGood=> AttachmentState::AttachedGood,
|
||||
veilid_core::AttachmentState::AttachedStrong=> AttachmentState::AttachedStrong,
|
||||
veilid_core::AttachmentState::FullyAttached=> AttachmentState::FullyAttached,
|
||||
veilid_core::AttachmentState::OverAttached=> AttachmentState::OverAttached,
|
||||
veilid_core::AttachmentState::Detaching=> AttachmentState::Detaching,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum VeilidUpdate {
|
||||
Attachment (AttachmentState),
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
///
|
||||
pub fn startup_veilid_core(sink: StreamSink<VeilidUpdate>, config: VeilidConfig) -> Result<(), VeilidAPIError> {
|
||||
let core = veilid_core::VeilidCore::new();
|
||||
|
||||
core.
|
||||
impl VeilidUpdate {
|
||||
fn from_core(veilid_update: veilid_core::VeilidUpdate) -> Self {
|
||||
match veilid_update {
|
||||
veilid_core::VeilidUpdate::Attachment(attachment) => Self::Attachment(AttachmentState::from_core(attachment))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_veilid_state() -> Result<VeilidState, VeilidAPIError> {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VeilidState {
|
||||
attachment: AttachmentState,
|
||||
}
|
||||
|
||||
impl VeilidState {
|
||||
fn from_core(veilid_state: veilid_core::VeilidState) -> Self {
|
||||
Self {
|
||||
attachment: AttachmentState::from_core(veilid_state.attachment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)?;
|
||||
Ok(VeilidState::from_core(core_state))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_veilid_state() -> Result<VeilidState> {
|
||||
|
||||
}
|
||||
|
||||
// xxx api functions
|
||||
|
||||
pub fn shutdown_veilid_core() -> Result<(), VeilidAPIError> {
|
||||
pub fn shutdown_veilid_core() -> Result<()> {
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user