mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-22 15:24:48 +01:00
feat: added new methods to java, js and py glues
This commit is contained in:
parent
e1da62f0c8
commit
6b7324d37f
5 changed files with 207 additions and 7 deletions
25
dist/java/src/mp/code/Client.java
vendored
25
dist/java/src/mp/code/Client.java
vendored
|
@ -24,6 +24,26 @@ public class Client {
|
||||||
return join_workspace(this.ptr, id);
|
return join_workspace(this.ptr, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static native void create_workspace(long self, String id) throws CodeMPException;
|
||||||
|
public void createWorkspace(String id) throws CodeMPException {
|
||||||
|
return create_workspace(this.ptr, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void delete_workspace(long self, String id) throws CodeMPException;
|
||||||
|
public void deleteWorkspace(String id) throws CodeMPException {
|
||||||
|
return delete_workspace(this.ptr, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void invite_to_workspace(long self, String ws, String usr) throws CodeMPException;
|
||||||
|
public void inviteToWorkspace(String ws, String usr) throws CodeMPException {
|
||||||
|
return invite_to_workspace(this.ptr, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native String[] list_workspaces(long self, boolean owned, boolean invited) throws CodeMPException;
|
||||||
|
public String[] listWorkspaces(boolean owned, boolean invited) throws CodeMPException {
|
||||||
|
return list_workspaces(this.ptr, owned, invited);
|
||||||
|
}
|
||||||
|
|
||||||
private static native boolean leave_workspace(long self, String id);
|
private static native boolean leave_workspace(long self, String id);
|
||||||
public boolean leaveWorkspace(String id) {
|
public boolean leaveWorkspace(String id) {
|
||||||
return leave_workspace(this.ptr, id);
|
return leave_workspace(this.ptr, id);
|
||||||
|
@ -33,6 +53,11 @@ public class Client {
|
||||||
public Optional<Workspace> getWorkspace() {
|
public Optional<Workspace> getWorkspace() {
|
||||||
return Optional.ofNullable(get_workspace(this.ptr));
|
return Optional.ofNullable(get_workspace(this.ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static native void refresh_native(long self);
|
||||||
|
public void refresh() {
|
||||||
|
return refresh_native(this.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
private static native void free(long self);
|
private static native void free(long self);
|
||||||
@Override
|
@Override
|
||||||
|
|
6
dist/py/codemp.pyi
vendored
6
dist/py/codemp.pyi
vendored
|
@ -114,7 +114,13 @@ class Client:
|
||||||
host: str,
|
host: str,
|
||||||
username: str, password: str) -> Client: ...
|
username: str, password: str) -> Client: ...
|
||||||
def join_workspace(self, workspace: str) -> Promise[Workspace]: ...
|
def join_workspace(self, workspace: str) -> Promise[Workspace]: ...
|
||||||
|
def create_workspace(self, workspace: str) -> Promise[None]: ...
|
||||||
|
def delete_workspace(self, workspace: str) -> Promise[None]: ...
|
||||||
|
def invite_to_workspace(self, workspace: str, username: str) -> Promise[None]: ...
|
||||||
|
def list_workspaces(self, owned: bool, invited: bool) -> Promise[list[str]]: ...
|
||||||
def leave_workspace(self, workspace: str) -> bool: ...
|
def leave_workspace(self, workspace: str) -> bool: ...
|
||||||
def get_workspace(self, id: str) -> Workspace: ...
|
def get_workspace(self, id: str) -> Workspace: ...
|
||||||
def active_workspaces(self) -> list[str]: ...
|
def active_workspaces(self) -> list[str]: ...
|
||||||
def user_id(self) -> str: ...
|
def user_id(self) -> str: ...
|
||||||
|
def user_name(self) -> str: ...
|
||||||
|
def refresh(self) -> Promise[None]: ...
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use jni::{objects::{JClass, JString, JValueGen}, sys::{jboolean, jlong, jobject}, JNIEnv};
|
use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jboolean, jlong, jobject, jobjectArray}, JNIEnv};
|
||||||
use crate::{client::Client, Workspace};
|
use crate::{client::Client, Workspace};
|
||||||
|
|
||||||
use super::{JExceptable, RT};
|
use super::{JExceptable, RT};
|
||||||
|
@ -21,7 +21,7 @@ pub extern "system" fn Java_mp_code_Client_connect<'local>(
|
||||||
let pwd: String = env.get_string(&pwd)
|
let pwd: String = env.get_string(&pwd)
|
||||||
.map(|s| s.into())
|
.map(|s| s.into())
|
||||||
.jexcept(&mut env);
|
.jexcept(&mut env);
|
||||||
RT.block_on(crate::Client::new(&url, &user, &pwd))
|
RT.block_on(crate::Client::connect(&url, &user, &pwd))
|
||||||
.map(|client| Box::into_raw(Box::new(client)) as jlong)
|
.map(|client| Box::into_raw(Box::new(client)) as jlong)
|
||||||
.map(|ptr| {
|
.map(|ptr| {
|
||||||
env.find_class("mp/code/Client")
|
env.find_class("mp/code/Client")
|
||||||
|
@ -52,6 +52,87 @@ pub extern "system" fn Java_mp_code_Client_join_1workspace<'local>(
|
||||||
}).jexcept(&mut env).as_raw()
|
}).jexcept(&mut env).as_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a workspace on server, if allowed to
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "system" fn Java_mp_code_Client_create_1workspace<'local>(
|
||||||
|
mut env: JNIEnv<'local>,
|
||||||
|
_class: JClass<'local>,
|
||||||
|
self_ptr: jlong,
|
||||||
|
input: JString<'local>
|
||||||
|
) {
|
||||||
|
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
|
||||||
|
let workspace_id = unsafe { env.get_string_unchecked(&input) }
|
||||||
|
.map(|wid| wid.to_string_lossy().to_string())
|
||||||
|
.jexcept(&mut env);
|
||||||
|
RT
|
||||||
|
.block_on(client.create_workspace(workspace_id))
|
||||||
|
.jexcept(&mut env);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deletes a workspace on server, if allowed to
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "system" fn Java_mp_code_Client_delete_1workspace<'local>(
|
||||||
|
mut env: JNIEnv<'local>,
|
||||||
|
_class: JClass<'local>,
|
||||||
|
self_ptr: jlong,
|
||||||
|
input: JString<'local>
|
||||||
|
) {
|
||||||
|
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
|
||||||
|
let workspace_id = unsafe { env.get_string_unchecked(&input) }
|
||||||
|
.map(|wid| wid.to_string_lossy().to_string())
|
||||||
|
.jexcept(&mut env);
|
||||||
|
RT
|
||||||
|
.block_on(client.delete_workspace(workspace_id))
|
||||||
|
.jexcept(&mut env);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invites another user to an owned workspace
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "system" fn Java_mp_code_Client_invite_1to_1workspace<'local>(
|
||||||
|
mut env: JNIEnv<'local>,
|
||||||
|
_class: JClass<'local>,
|
||||||
|
self_ptr: jlong,
|
||||||
|
ws: JString<'local>,
|
||||||
|
usr: JString<'local>
|
||||||
|
) {
|
||||||
|
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
|
||||||
|
let workspace_id = unsafe { env.get_string_unchecked(&ws) }
|
||||||
|
.map(|wid| wid.to_string_lossy().to_string())
|
||||||
|
.jexcept(&mut env);
|
||||||
|
let user_name = unsafe { env.get_string_unchecked(&usr) }
|
||||||
|
.map(|wid| wid.to_string_lossy().to_string())
|
||||||
|
.jexcept(&mut env);
|
||||||
|
RT
|
||||||
|
.block_on(client.invite_to_workspace(workspace_id, user_name))
|
||||||
|
.jexcept(&mut env);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// List available workspaces
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "system" fn Java_mp_code_Client_list_1workspaces<'local>(
|
||||||
|
mut env: JNIEnv<'local>,
|
||||||
|
_class: JClass<'local>,
|
||||||
|
self_ptr: jlong,
|
||||||
|
owned: jboolean,
|
||||||
|
invited: jboolean
|
||||||
|
) -> jobjectArray {
|
||||||
|
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
|
||||||
|
let list = RT
|
||||||
|
.block_on(client.list_workspaces(owned != 0, invited != 0))
|
||||||
|
.jexcept(&mut env);
|
||||||
|
|
||||||
|
env.find_class("java/lang/String")
|
||||||
|
.and_then(|class| env.new_object_array(list.len() as i32, class, JObject::null()))
|
||||||
|
.map(|arr| {
|
||||||
|
for (idx, path) in list.iter().enumerate() {
|
||||||
|
env.new_string(path)
|
||||||
|
.and_then(|path| env.set_object_array_element(&arr, idx as i32, path))
|
||||||
|
.jexcept(&mut env)
|
||||||
|
}
|
||||||
|
arr
|
||||||
|
}).jexcept(&mut env).as_raw()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: this stays until we get rid of the arc then i'll have to find a better way
|
// TODO: this stays until we get rid of the arc then i'll have to find a better way
|
||||||
fn spawn_updater(workspace: Workspace) -> Workspace {
|
fn spawn_updater(workspace: Workspace) -> Workspace {
|
||||||
let w = workspace.clone();
|
let w = workspace.clone();
|
||||||
|
@ -79,6 +160,7 @@ pub extern "system" fn Java_mp_code_Client_leave_1workspace<'local>(
|
||||||
.map(|wid| client.leave_workspace(&wid) as jboolean)
|
.map(|wid| client.leave_workspace(&wid) as jboolean)
|
||||||
.jexcept(&mut env)
|
.jexcept(&mut env)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a [Workspace] by name and returns a pointer to it.
|
/// Gets a [Workspace] by name and returns a pointer to it.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "system" fn Java_mp_code_Client_get_1workspace<'local>(
|
pub extern "system" fn Java_mp_code_Client_get_1workspace<'local>(
|
||||||
|
@ -100,6 +182,17 @@ pub extern "system" fn Java_mp_code_Client_get_1workspace<'local>(
|
||||||
}).unwrap_or_default().as_raw()
|
}).unwrap_or_default().as_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Refresh client's session token
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "system" fn Java_mp_code_Client_refresh<'local>(
|
||||||
|
mut env: JNIEnv<'local>,
|
||||||
|
_class: JClass<'local>,
|
||||||
|
self_ptr: jlong,
|
||||||
|
) {
|
||||||
|
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
|
||||||
|
RT.block_on(client.refresh()).jexcept(&mut env);
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets up the tracing subscriber.
|
/// Sets up the tracing subscriber.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "system" fn Java_mp_code_Client_setup_1tracing<'local>(
|
pub extern "system" fn Java_mp_code_Client_setup_1tracing<'local>(
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{Client, Workspace};
|
||||||
#[napi]
|
#[napi]
|
||||||
/// connect to codemp servers and return a client session
|
/// connect to codemp servers and return a client session
|
||||||
pub async fn connect(addr: Option<String>, username: String, password: String) -> napi::Result<crate::Client>{
|
pub async fn connect(addr: Option<String>, username: String, password: String) -> napi::Result<crate::Client>{
|
||||||
let client = crate::Client::new(addr.as_deref().unwrap_or("http://codemp.alemi.dev:50053"), username, password)
|
let client = crate::Client::connect(addr.as_deref().unwrap_or("http://codemp.alemi.dev:50053"), username, password)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(client)
|
Ok(client)
|
||||||
|
@ -12,12 +12,42 @@ pub async fn connect(addr: Option<String>, username: String, password: String) -
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
impl Client {
|
impl Client {
|
||||||
|
#[napi(js_name = "create_workspace")]
|
||||||
|
/// create workspace with given id, if able to
|
||||||
|
pub async fn js_create_workspace(&self, workspace: String) -> napi::Result<()> {
|
||||||
|
Ok(self.create_workspace(workspace).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi(js_name = "delete_workspace")]
|
||||||
|
/// delete workspace with given id, if able to
|
||||||
|
pub async fn js_delete_workspace(&self, workspace: String) -> napi::Result<()> {
|
||||||
|
Ok(self.delete_workspace(workspace).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi(js_name = "list_workspaces")]
|
||||||
|
/// list available workspaces
|
||||||
|
pub async fn js_list_workspaces(&self, owned: bool, invited: bool) -> napi::Result<Vec<String>> {
|
||||||
|
Ok(self.list_workspaces(owned, invited).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi(js_name = "invite_to_workspace")]
|
||||||
|
/// invite user to given workspace, if able to
|
||||||
|
pub async fn js_invite_to_workspace(&self, workspace: String, user: String) -> napi::Result<()> {
|
||||||
|
Ok(self.invite_to_workspace(workspace, user).await?)
|
||||||
|
}
|
||||||
|
|
||||||
#[napi(js_name = "join_workspace")]
|
#[napi(js_name = "join_workspace")]
|
||||||
/// join workspace with given id (will start its cursor controller)
|
/// join workspace with given id (will start its cursor controller)
|
||||||
pub async fn js_join_workspace(&self, workspace: String) -> napi::Result<Workspace> {
|
pub async fn js_join_workspace(&self, workspace: String) -> napi::Result<Workspace> {
|
||||||
Ok(self.join_workspace(workspace).await?)
|
Ok(self.join_workspace(workspace).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi(js_name = "leave_workspace")]
|
||||||
|
/// leave workspace and disconnect, returns true if workspace was active
|
||||||
|
pub async fn js_leave_workspace(&self, workspace: String) -> napi::Result<bool> {
|
||||||
|
Ok(self.leave_workspace(&workspace))
|
||||||
|
}
|
||||||
|
|
||||||
#[napi(js_name = "get_workspace")]
|
#[napi(js_name = "get_workspace")]
|
||||||
/// get workspace with given id, if it exists
|
/// get workspace with given id, if it exists
|
||||||
pub fn js_get_workspace(&self, workspace: String) -> Option<Workspace> {
|
pub fn js_get_workspace(&self, workspace: String) -> Option<Workspace> {
|
||||||
|
@ -27,7 +57,7 @@ impl Client {
|
||||||
#[napi(js_name = "user_id")]
|
#[napi(js_name = "user_id")]
|
||||||
/// return current sessions's user id
|
/// return current sessions's user id
|
||||||
pub fn js_user_id(&self) -> String {
|
pub fn js_user_id(&self) -> String {
|
||||||
self.user_id().to_string()
|
self.user().id.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[napi(js_name = "active_workspaces")]
|
#[napi(js_name = "active_workspaces")]
|
||||||
|
@ -35,4 +65,10 @@ impl Client {
|
||||||
pub fn js_active_workspaces(&self) -> Vec<String> {
|
pub fn js_active_workspaces(&self) -> Vec<String> {
|
||||||
self.active_workspaces()
|
self.active_workspaces()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#[napi(js_name = "refresh")]
|
||||||
|
/// refresh client session token
|
||||||
|
pub async fn js_refresh(&self) -> napi::Result<()> {
|
||||||
|
Ok(self.refresh().await?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use super::tokio;
|
||||||
impl Client {
|
impl Client {
|
||||||
#[new]
|
#[new]
|
||||||
fn __new__(host: String, username: String, password: String) -> crate::Result<Self> {
|
fn __new__(host: String, username: String, password: String) -> crate::Result<Self> {
|
||||||
tokio().block_on(Client::new(host, username, password))
|
tokio().block_on(Client::connect(host, username, password))
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[pyo3(name = "join_workspace")]
|
// #[pyo3(name = "join_workspace")]
|
||||||
|
@ -37,6 +37,34 @@ impl Client {
|
||||||
// }))))
|
// }))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "create_workspace")]
|
||||||
|
fn pycreate_workspace(&self, py: Python<'_>, workspace: String) -> PyResult<super::Promise> {
|
||||||
|
tracing::info!("attempting to create workspace {}", workspace);
|
||||||
|
let this = self.clone();
|
||||||
|
crate::a_sync_allow_threads!(py, this.create_workspace(workspace).await)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "delete_workspace")]
|
||||||
|
fn pydelete_workspace(&self, py: Python<'_>, workspace: String) -> PyResult<super::Promise> {
|
||||||
|
tracing::info!("attempting to delete workspace {}", workspace);
|
||||||
|
let this = self.clone();
|
||||||
|
crate::a_sync_allow_threads!(py, this.delete_workspace(workspace).await)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "invite_to_workspace")]
|
||||||
|
fn pyinvite_to_workspace(&self, py: Python<'_>, workspace: String, user: String) -> PyResult<super::Promise> {
|
||||||
|
tracing::info!("attempting to invite {user} to workspace {workspace}");
|
||||||
|
let this = self.clone();
|
||||||
|
crate::a_sync_allow_threads!(py, this.invite_to_workspace(workspace, user).await)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "list_workspaces")]
|
||||||
|
fn pylist_workspaces(&self, py: Python<'_>, owned: bool, invited: bool) -> PyResult<super::Promise> {
|
||||||
|
tracing::info!("attempting to list workspaces");
|
||||||
|
let this = self.clone();
|
||||||
|
crate::a_sync_allow_threads!(py, this.list_workspaces(owned, invited).await)
|
||||||
|
}
|
||||||
|
|
||||||
#[pyo3(name = "leave_workspace")]
|
#[pyo3(name = "leave_workspace")]
|
||||||
fn pyleave_workspace(&self, id: String) -> bool {
|
fn pyleave_workspace(&self, id: String) -> bool {
|
||||||
self.leave_workspace(id.as_str())
|
self.leave_workspace(id.as_str())
|
||||||
|
@ -55,6 +83,18 @@ impl Client {
|
||||||
|
|
||||||
#[pyo3(name = "user_id")]
|
#[pyo3(name = "user_id")]
|
||||||
fn pyuser_id(&self) -> String {
|
fn pyuser_id(&self) -> String {
|
||||||
self.user_id().to_string()
|
self.user().id.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "user_name")]
|
||||||
|
fn pyuser_name(&self) -> String {
|
||||||
|
self.user().name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "refresh")]
|
||||||
|
fn pyrefresh(&self, py: Python<'_>) -> PyResult<super::Promise> {
|
||||||
|
tracing::info!("attempting to refresh token");
|
||||||
|
let this = self.clone();
|
||||||
|
crate::a_sync_allow_threads!(py, this.refresh().await)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue