mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-24 16:14:48 +01:00
feat(c): proof of concept of C api
will be long and unpleasant but feasible
This commit is contained in:
parent
0b471b72fa
commit
db0ad947db
6 changed files with 213 additions and 9 deletions
126
Cargo.lock
generated
126
Cargo.lock
generated
|
@ -86,6 +86,17 @@ version = "1.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
|
@ -160,6 +171,12 @@ version = "0.22.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
|
@ -194,6 +211,25 @@ version = "1.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||
|
||||
[[package]]
|
||||
name = "cbindgen"
|
||||
version = "0.24.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"heck 0.4.1",
|
||||
"indexmap 1.9.3",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn 1.0.109",
|
||||
"tempfile",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.20"
|
||||
|
@ -229,11 +265,36 @@ dependencies = [
|
|||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags 1.3.2",
|
||||
"clap_lex",
|
||||
"indexmap 1.9.3",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codemp"
|
||||
version = "0.7.2"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"cbindgen",
|
||||
"codemp-proto",
|
||||
"dashmap",
|
||||
"diamond-types",
|
||||
|
@ -531,12 +592,27 @@ version = "0.14.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
|
@ -893,7 +969,7 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.3.9",
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.52.0",
|
||||
|
@ -950,7 +1026,7 @@ version = "2.16.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04409e8c2d61995696e44d2181b79b68c1dd41f7e24a17cde60bbd9f54ddddef"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.6.0",
|
||||
"chrono",
|
||||
"ctor",
|
||||
"encoding_rs",
|
||||
|
@ -1076,6 +1152,12 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
|
@ -1220,7 +1302,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck",
|
||||
"heck 0.5.0",
|
||||
"itertools",
|
||||
"log",
|
||||
"multimap",
|
||||
|
@ -1312,7 +1394,7 @@ version = "0.22.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1be962f0e06da8f8465729ea2cb71a416d2257dff56cbe40a70d3e62a93ae5d1"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"pyo3-build-config",
|
||||
"quote",
|
||||
|
@ -1364,7 +1446,7 @@ version = "0.5.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1438,7 +1520,7 @@ version = "0.38.37"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
|
@ -1542,7 +1624,7 @@ version = "2.11.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.6.0",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
|
@ -1682,6 +1764,12 @@ version = "0.4.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
|
@ -1741,6 +1829,21 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
|
@ -1833,6 +1936,15 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.8"
|
||||
|
|
|
@ -62,6 +62,8 @@ serde = { version = "1.0", features = ["derive"], optional = true }
|
|||
napi-build = { version = "2.1", optional = true }
|
||||
# glue (python)
|
||||
pyo3-build-config = { version = "0.22", optional = true }
|
||||
# glue (C)
|
||||
cbindgen = { version = "0.24", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
@ -73,6 +75,7 @@ java = ["lazy_static", "jni", "tracing-subscriber", "jni-toolbox"]
|
|||
js = ["napi-build", "tracing-subscriber", "napi", "napi-derive"]
|
||||
py-noabi = ["pyo3", "tracing-subscriber", "pyo3-build-config"]
|
||||
py = ["py-noabi", "pyo3/abi3-py38"]
|
||||
c = ["cbindgen"]
|
||||
lua = ["mlua-codemp-patch", "tracing-subscriber", "lazy_static", "serialize"]
|
||||
lua54 =["lua", "mlua-codemp-patch/lua54"]
|
||||
luajit = ["lua", "mlua-codemp-patch/luajit"]
|
||||
|
|
16
build.rs
16
build.rs
|
@ -4,6 +4,9 @@ extern crate napi_build;
|
|||
#[cfg(any(feature = "py", feature = "py-noabi"))]
|
||||
extern crate pyo3_build_config;
|
||||
|
||||
#[cfg(feature = "c")]
|
||||
extern crate cbindgen;
|
||||
|
||||
/// The main method of the buildscript, required by some glue modules.
|
||||
fn main() {
|
||||
#[cfg(feature = "js")]
|
||||
|
@ -20,7 +23,16 @@ fn main() {
|
|||
{
|
||||
if let Ok("macos") = std::env::var("CARGO_CFG_TARGET_OS").as_deref() {
|
||||
println!("cargo:rustc-cdylib-link-arg=-undefined");
|
||||
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
|
||||
}
|
||||
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "c")]
|
||||
{
|
||||
cbindgen::Builder::new()
|
||||
.with_crate(std::env::var("CARGO_MANIFEST_DIR").unwrap())
|
||||
.generate()
|
||||
.expect("Unable to generate bindings")
|
||||
.write_to_file("dist/c/codemp.h");
|
||||
}
|
||||
}
|
||||
|
|
28
dist/c/codemp.h
vendored
Normal file
28
dist/c/codemp.h
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <new>
|
||||
|
||||
/// A `codemp` client handle.
|
||||
///
|
||||
/// It generates a new UUID and stores user credentials upon connecting.
|
||||
///
|
||||
/// A new [`Client`] can be obtained with [`Client::connect`].
|
||||
struct Client;
|
||||
|
||||
/// A currently active shared development environment
|
||||
///
|
||||
/// Workspaces encapsulate a working environment: cursor positions, filetree, user list
|
||||
/// and more. Each holds a [cursor::Controller] and a map of [buffer::Controller]s.
|
||||
/// Using a workspace handle, it's possible to receive events (user join/leave, filetree updates)
|
||||
/// and create/delete/attach to new buffers.
|
||||
struct Workspace;
|
||||
|
||||
extern "C" {
|
||||
|
||||
Client *Codemp_Client_connect();
|
||||
|
||||
Workspace *Codemp_Client_join_workspace(Client *client, char *workspace);
|
||||
|
||||
} // extern "C"
|
45
src/ffi/c/mod.rs
Normal file
45
src/ffi/c/mod.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
use std::ffi::{c_char, CString};
|
||||
|
||||
use crate::{api::Config, Client, Workspace};
|
||||
|
||||
pub(crate) fn tokio() -> &'static tokio::runtime::Runtime {
|
||||
use std::sync::OnceLock;
|
||||
static RT: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
|
||||
RT.get_or_init(||
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("could not create tokio runtime")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#[no_mangle] // TODO config
|
||||
pub extern "C" fn Codemp_Client_connect() -> *mut Client {
|
||||
match tokio()
|
||||
.block_on(Client::connect(Config::new("", "")))
|
||||
{
|
||||
Ok(c) => Box::into_raw(Box::new(c)),
|
||||
Err(e) => {
|
||||
tracing::error!("failed connecting to remote: {e}");
|
||||
std::ptr::null_mut()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Codemp_Client_join_workspace(client: *mut Client, workspace: *mut c_char) -> *mut Workspace {
|
||||
let client = unsafe { Box::leak(Box::from_raw(client)) };
|
||||
let workspace = unsafe { CString::from_raw(workspace) }.to_string_lossy().to_string();
|
||||
|
||||
match tokio()
|
||||
.block_on(client.join_workspace(workspace))
|
||||
{
|
||||
Ok(ws) => Box::into_raw(Box::new(ws)),
|
||||
Err(e) => {
|
||||
tracing::error!("failed joining workspace: {e}");
|
||||
std::ptr::null_mut()
|
||||
},
|
||||
}
|
||||
|
||||
}
|
|
@ -58,3 +58,7 @@ pub mod js;
|
|||
/// python bindings, built with [pyo3]
|
||||
#[cfg(any(feature = "py", feature = "py-noabi"))]
|
||||
pub mod python;
|
||||
|
||||
/// c bindings, generated with [cbindgen]
|
||||
#[cfg(feature = "c")]
|
||||
pub mod c;
|
||||
|
|
Loading…
Reference in a new issue