mirror of
https://github.com/hexedtech/codemp.git
synced 2024-12-22 21:04:53 +01:00
Merge pull request #49 from hexedtech/chore/rename
chore: enforcing API consistency (also across FFI)
This commit is contained in:
commit
d7c9acd928
36 changed files with 906 additions and 766 deletions
334
Cargo.lock
generated
334
Cargo.lock
generated
|
@ -4,9 +4,9 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
@ -49,9 +49,9 @@ checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
|
|||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
|
||||
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
|
||||
dependencies = [
|
||||
"async-stream-impl",
|
||||
"futures-core",
|
||||
|
@ -60,24 +60,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-stream-impl"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
||||
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.82"
|
||||
version = "0.1.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1"
|
||||
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -88,15 +88,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
|||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.7.5"
|
||||
version = "0.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
|
||||
checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
|
@ -114,16 +114,16 @@ dependencies = [
|
|||
"rustversion",
|
||||
"serde",
|
||||
"sync_wrapper 1.0.1",
|
||||
"tower",
|
||||
"tower 0.5.1",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.4.3"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3"
|
||||
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
|
@ -134,7 +134,7 @@ dependencies = [
|
|||
"mime",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"sync_wrapper 0.1.2",
|
||||
"sync_wrapper 1.0.1",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
@ -190,15 +190,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.7.1"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.20"
|
||||
version = "1.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45bcde016d64c21da4be18b655631e5ab6d3107607e71a73a9f53eb48aae23fb"
|
||||
checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
@ -343,7 +343,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -440,36 +440,36 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -490,9 +490,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
|
@ -512,7 +512,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-sink",
|
||||
"http",
|
||||
"indexmap 2.5.0",
|
||||
"indexmap 2.6.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
@ -531,6 +531,12 @@ version = "0.14.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
|
@ -579,9 +585,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.9.4"
|
||||
version = "1.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
|
||||
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
|
@ -597,9 +603,9 @@ checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026"
|
|||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "1.4.1"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05"
|
||||
checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
@ -631,9 +637,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba"
|
||||
checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
@ -644,7 +650,6 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -684,12 +689,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
||||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -698,6 +703,12 @@ version = "2.0.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
||||
|
||||
[[package]]
|
||||
name = "inventory"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
|
@ -749,9 +760,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
|||
|
||||
[[package]]
|
||||
name = "jni-toolbox"
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eeae2881d819e208fcfceea81eb5a8ca6c131c6fb1605dfe2f3a31dea061ec7c"
|
||||
checksum = "cce03cf89bc32b81de142a323a71e9903ee88127a0e04bbd7f215ab74ab6b10a"
|
||||
dependencies = [
|
||||
"jni",
|
||||
"jni-toolbox-macro",
|
||||
|
@ -760,20 +771,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "jni-toolbox-macro"
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e480850db18f0cc95120e7bf86af772c31b3c0f0dd3d3600682d8bd8399f4ae"
|
||||
checksum = "609491ce00edcf12946945a514d033bf6e8bfbab02c6a25a46ed8cd4749707da"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.70"
|
||||
version = "0.3.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
|
||||
checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
@ -796,9 +807,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.158"
|
||||
version = "0.2.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
|
@ -935,7 +946,7 @@ checksum = "13e6f40fa1fd8426285688f4a37b56beac69284743d057ee6db352b543f4b621"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -946,9 +957,9 @@ checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
|
|||
|
||||
[[package]]
|
||||
name = "napi"
|
||||
version = "2.16.10"
|
||||
version = "2.16.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04409e8c2d61995696e44d2181b79b68c1dd41f7e24a17cde60bbd9f54ddddef"
|
||||
checksum = "3a84fdaf64da2b2d86b1be5db1b81963353bf00f7bef4b9e2668bbe6f72e8eb3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"chrono",
|
||||
|
@ -979,7 +990,7 @@ dependencies = [
|
|||
"napi-derive-backend",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -994,7 +1005,7 @@ dependencies = [
|
|||
"quote",
|
||||
"regex",
|
||||
"semver",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1048,18 +1059,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.4"
|
||||
version = "0.36.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
|
||||
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
version = "1.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
|
@ -1118,27 +1129,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap 2.5.0",
|
||||
"indexmap 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.5"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
|
||||
checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.5"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1155,15 +1166,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.7.0"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
|
||||
checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
|
@ -1181,7 +1192,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1196,18 +1207,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
version = "1.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995"
|
||||
checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
|
@ -1215,9 +1226,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "prost-build"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302"
|
||||
checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck",
|
||||
|
@ -1230,40 +1241,41 @@ dependencies = [
|
|||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac"
|
||||
checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519"
|
||||
checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670"
|
||||
dependencies = [
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.22.3"
|
||||
version = "0.22.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15ee168e30649f7f234c3d49ef5a7a6cbf5134289bc46c29ff3155fa3221c225"
|
||||
checksum = "3d922163ba1f79c04bc49073ba7b32fd5a8d3b76a87c955921234b8e77333c51"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"indoc",
|
||||
"inventory",
|
||||
"libc",
|
||||
"memoffset",
|
||||
"once_cell",
|
||||
|
@ -1276,9 +1288,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.22.3"
|
||||
version = "0.22.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e61cef80755fe9e46bb8a0b8f20752ca7676dcc07a5277d8b7768c6172e529b3"
|
||||
checksum = "bc38c5feeb496c8321091edf3d63e9a6829eab4b863b4a6a65f26f3e9cc6b179"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"target-lexicon",
|
||||
|
@ -1286,9 +1298,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.22.3"
|
||||
version = "0.22.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67ce096073ec5405f5ee2b8b31f03a68e02aa10d5d4f565eca04acc41931fa1c"
|
||||
checksum = "94845622d88ae274d2729fcefc850e63d7a3ddff5e3ce11bd88486db9f1d357d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
|
@ -1296,27 +1308,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.22.3"
|
||||
version = "0.22.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2440c6d12bc8f3ae39f1e775266fa5122fd0c8891ce7520fa6048e683ad3de28"
|
||||
checksum = "e655aad15e09b94ffdb3ce3d217acf652e26bbc37697ef012f5e5e348c716e5e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.22.3"
|
||||
version = "0.22.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1be962f0e06da8f8465729ea2cb71a416d2257dff56cbe40a70d3e62a93ae5d1"
|
||||
checksum = "ae1e3f09eecd94618f60a455a23def79f79eba4dc561a97324bf9ac8c6df30ce"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"pyo3-build-config",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1360,18 +1372,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.4"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853"
|
||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.6"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
||||
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -1381,9 +1393,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
||||
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -1392,9 +1404,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
|
@ -1447,9 +1459,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.13"
|
||||
version = "0.23.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
|
||||
checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
|
@ -1462,9 +1474,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.7.3"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
|
||||
checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile",
|
||||
|
@ -1475,19 +1487,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "2.1.3"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
|
||||
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.8.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
||||
checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
|
@ -1502,9 +1513,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.17"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
|
||||
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
|
@ -1523,9 +1534,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.24"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b"
|
||||
checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
@ -1551,9 +1562,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.11.1"
|
||||
version = "2.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
|
||||
checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
|
@ -1592,7 +1603,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1701,9 +1712,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.77"
|
||||
version = "2.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1730,9 +1741,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.12.0"
|
||||
version = "3.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
|
||||
checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
|
@ -1743,22 +1754,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.63"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1795,7 +1806,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1845,16 +1856,16 @@ version = "0.19.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap 2.5.0",
|
||||
"indexmap 2.6.0",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.12.2"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6f6ba989e4b2c58ae83d862d3a3e27690b6e3ae630d0deb59f3697f32aa88ad"
|
||||
checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
|
@ -1877,7 +1888,7 @@ dependencies = [
|
|||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-stream",
|
||||
"tower",
|
||||
"tower 0.4.13",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
|
@ -1885,15 +1896,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tonic-build"
|
||||
version = "0.12.2"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe4ee8877250136bd7e3d2331632810a4df4ea5e004656990d8d66d2f5ee8a67"
|
||||
checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11"
|
||||
dependencies = [
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"prost-build",
|
||||
"prost-types",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1916,6 +1928,20 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"pin-project-lite",
|
||||
"sync_wrapper 0.1.2",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.3"
|
||||
|
@ -1947,7 +1973,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2080,9 +2106,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.93"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
|
||||
checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
|
@ -2091,24 +2117,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.93"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
|
||||
checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.93"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
|
||||
checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
@ -2116,22 +2142,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.93"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
||||
checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.93"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||
checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
@ -2354,7 +2380,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -51,7 +51,7 @@ napi = { version = "2.16", features = ["full"], optional = true }
|
|||
napi-derive = { version="2.16", optional = true}
|
||||
|
||||
# glue (python)
|
||||
pyo3 = { version = "0.22", features = ["extension-module"], optional = true}
|
||||
pyo3 = { version = "0.22", features = ["extension-module", "multiple-pymethods"], optional = true}
|
||||
|
||||
# extra
|
||||
async-trait = { version = "0.1", optional = true }
|
||||
|
|
33
dist/java/src/mp/code/Client.java
vendored
33
dist/java/src/mp/code/Client.java
vendored
|
@ -34,17 +34,17 @@ public final class Client {
|
|||
*/
|
||||
public static native Client connect(Config config) throws ConnectionException;
|
||||
|
||||
private static native User get_user(long self);
|
||||
private static native User current_user(long self);
|
||||
|
||||
/**
|
||||
* Gets information about the current user.
|
||||
* @return a {@link User} object representing the user
|
||||
*/
|
||||
public User getUser() {
|
||||
return get_user(this.ptr);
|
||||
public User currentUser() {
|
||||
return current_user(this.ptr);
|
||||
}
|
||||
|
||||
private static native Workspace join_workspace(long self, String workspaceId) throws ConnectionException;
|
||||
private static native Workspace attach_workspace(long self, String workspaceId) throws ConnectionException;
|
||||
|
||||
/**
|
||||
* Joins a {@link Workspace} and returns it.
|
||||
|
@ -52,8 +52,8 @@ public final class Client {
|
|||
* @return the relevant {@link Workspace}
|
||||
* @throws ConnectionException if an error occurs in communicating with the server
|
||||
*/
|
||||
public Workspace joinWorkspace(String workspaceId) throws ConnectionException {
|
||||
return join_workspace(this.ptr, workspaceId);
|
||||
public Workspace attachWorkspace(String workspaceId) throws ConnectionException {
|
||||
return attach_workspace(this.ptr, workspaceId);
|
||||
}
|
||||
|
||||
private static native void create_workspace(long self, String workspaceId) throws ConnectionRemoteException;
|
||||
|
@ -91,17 +91,26 @@ public final class Client {
|
|||
invite_to_workspace(this.ptr, workspaceId, user);
|
||||
}
|
||||
|
||||
private static native String[] list_workspaces(long self, boolean owned, boolean invited) throws ConnectionRemoteException;
|
||||
private static native String[] fetch_owned_workspaces(long self) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Lists available workspaces according to certain filters.
|
||||
* @param owned if owned workspaces should be included
|
||||
* @param invited if workspaces the user is invited to should be included
|
||||
* Lists workspaces owned by the current user.
|
||||
* @return an array of workspace IDs
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public String[] listWorkspaces(boolean owned, boolean invited) throws ConnectionRemoteException {
|
||||
return list_workspaces(this.ptr, owned, invited);
|
||||
public String[] fetchOwnedWorkspaces() throws ConnectionRemoteException {
|
||||
return fetch_owned_workspaces(this.ptr);
|
||||
}
|
||||
|
||||
private static native String[] fetch_joined_workspaces(long self) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Lists workspaces the current user has joined.
|
||||
* @return an array of workspace IDs
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public String[] fetchJoinedWorkspaces() throws ConnectionRemoteException {
|
||||
return fetch_joined_workspaces(this.ptr);
|
||||
}
|
||||
|
||||
private static native String[] active_workspaces(long self);
|
||||
|
|
86
dist/java/src/mp/code/Workspace.java
vendored
86
dist/java/src/mp/code/Workspace.java
vendored
|
@ -1,9 +1,10 @@
|
|||
package mp.code;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import lombok.Getter;
|
||||
import mp.code.data.User;
|
||||
import mp.code.exceptions.ConnectionException;
|
||||
import mp.code.exceptions.ConnectionRemoteException;
|
||||
import mp.code.exceptions.ControllerException;
|
||||
|
@ -24,24 +25,24 @@ public final class Workspace {
|
|||
Extensions.CLEANER.register(this, () -> free(ptr));
|
||||
}
|
||||
|
||||
private static native String get_workspace_id(long self);
|
||||
private static native String id(long self);
|
||||
|
||||
/**
|
||||
* Gets the unique identifier of the current workspace.
|
||||
* @return the identifier
|
||||
*/
|
||||
public String getWorkspaceId() {
|
||||
return get_workspace_id(this.ptr);
|
||||
public String id() {
|
||||
return id(this.ptr);
|
||||
}
|
||||
|
||||
private static native CursorController get_cursor(long self);
|
||||
private static native CursorController cursor(long self);
|
||||
|
||||
/**
|
||||
* Gets the {@link CursorController} for the current workspace.
|
||||
* @return the {@link CursorController}
|
||||
*/
|
||||
public CursorController getCursor() {
|
||||
return get_cursor(this.ptr);
|
||||
public CursorController cursor() {
|
||||
return cursor(this.ptr);
|
||||
}
|
||||
|
||||
private static native BufferController get_buffer(long self, String path);
|
||||
|
@ -56,17 +57,16 @@ public final class Workspace {
|
|||
return Optional.ofNullable(get_buffer(this.ptr, path));
|
||||
}
|
||||
|
||||
private static native String[] get_file_tree(long self, String filter, boolean strict);
|
||||
private static native String[] search_buffers(long self, String filter);
|
||||
|
||||
/**
|
||||
* Gets the file tree for this workspace, optionally filtering it.
|
||||
* @param filter applies an optional filter to the outputs
|
||||
* @param strict whether it should be a strict match (equals) or not (startsWith)
|
||||
* Searches for buffers matching the filter in this workspace.
|
||||
* @param filter the filter to apply
|
||||
* @return an array containing file tree as flat paths
|
||||
*/
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public String[] getFileTree(Optional<String> filter, boolean strict) {
|
||||
return get_file_tree(this.ptr, filter.orElse(null), strict);
|
||||
public String[] searchBuffers(Optional<String> filter) {
|
||||
return search_buffers(this.ptr, filter.orElse(null));
|
||||
}
|
||||
|
||||
private static native String[] active_buffers(long self);
|
||||
|
@ -101,7 +101,7 @@ public final class Workspace {
|
|||
create_buffer(this.ptr, path);
|
||||
}
|
||||
|
||||
private static native BufferController attach_to_buffer(long self, String path) throws ConnectionException;
|
||||
private static native BufferController attach_buffer(long self, String path) throws ConnectionException;
|
||||
|
||||
/**
|
||||
* Attaches to an existing buffer with the given path, if present.
|
||||
|
@ -109,52 +109,54 @@ public final class Workspace {
|
|||
* @return the {@link BufferController} associated with that path
|
||||
* @throws ConnectionException if an error occurs in communicating with the server, or if the buffer did not exist
|
||||
*/
|
||||
public BufferController attachToBuffer(String path) throws ConnectionException {
|
||||
return attach_to_buffer(ptr, path);
|
||||
public BufferController attachBuffer(String path) throws ConnectionException {
|
||||
return attach_buffer(ptr, path);
|
||||
}
|
||||
|
||||
private static native boolean detach_from_buffer(long self, String path);
|
||||
private static native boolean detach_buffer(long self, String path);
|
||||
|
||||
/**
|
||||
* Detaches from a given buffer.
|
||||
* @param path the path of the buffer to detach from
|
||||
* @return a boolean, true only if there are still dangling references preventing controller from stopping
|
||||
*/
|
||||
public boolean detachFromBuffer(String path) {
|
||||
return detach_from_buffer(this.ptr, path);
|
||||
public boolean detachBuffer(String path) {
|
||||
return detach_buffer(this.ptr, path);
|
||||
}
|
||||
|
||||
private static native void fetch_buffers(long self) throws ConnectionRemoteException;
|
||||
private static native String[] fetch_buffers(long self) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Updates the local list of buffers.
|
||||
* Updates and fetches the local list of buffers.
|
||||
* @return the updated list
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void fetchBuffers() throws ConnectionRemoteException {
|
||||
fetch_buffers(this.ptr);
|
||||
public String[] fetchBuffers() throws ConnectionRemoteException {
|
||||
return fetch_buffers(this.ptr);
|
||||
}
|
||||
|
||||
private static native void fetch_users(long self) throws ConnectionRemoteException;
|
||||
private static native User[] fetch_users(long self) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Updates the local list of users.
|
||||
* Updates and fetches the local list of users.
|
||||
* @return the updated list
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void fetchUsers() throws ConnectionRemoteException {
|
||||
fetch_buffers(this.ptr);
|
||||
public User[] fetchUsers() throws ConnectionRemoteException {
|
||||
return fetch_users(this.ptr);
|
||||
}
|
||||
|
||||
private static native UUID[] list_buffer_users(long self, String path) throws ConnectionRemoteException;
|
||||
private static native User[] fetch_buffer_users(long self, String path) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Lists the user attached to a certain buffer.
|
||||
* Fetches the users attached to a certain buffer.
|
||||
* The user must be attached to the buffer to perform this operation.
|
||||
* @param path the path of the buffer to search
|
||||
* @return an array of user {@link UUID UUIDs}
|
||||
* @return an array of {@link User}s
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server, or the user wasn't attached
|
||||
*/
|
||||
public UUID[] listBufferUsers(String path) throws ConnectionRemoteException {
|
||||
return list_buffer_users(this.ptr, path);
|
||||
public User[] fetchBufferUsers(String path) throws ConnectionRemoteException {
|
||||
return fetch_buffer_users(this.ptr, path);
|
||||
}
|
||||
|
||||
private static native void delete_buffer(long self, String path) throws ConnectionRemoteException;
|
||||
|
@ -234,7 +236,8 @@ public final class Workspace {
|
|||
* Represents a workspace-wide event.
|
||||
*/
|
||||
public static final class Event {
|
||||
private final Type type;
|
||||
/** The type of the event. */
|
||||
public final @Getter Type type;
|
||||
private final String argument;
|
||||
|
||||
Event(Type type, String argument) {
|
||||
|
@ -272,9 +275,24 @@ public final class Workspace {
|
|||
} else return Optional.empty();
|
||||
}
|
||||
|
||||
enum Type {
|
||||
/**
|
||||
* The type of workspace event.
|
||||
*/
|
||||
public enum Type {
|
||||
/**
|
||||
* Somebody joined a workspace.
|
||||
* @see #getUserJoined() to get the name
|
||||
*/
|
||||
USER_JOIN,
|
||||
/**
|
||||
* Somebody left a workspace
|
||||
* @see #getUserLeft() to get the name
|
||||
*/
|
||||
USER_LEAVE,
|
||||
/**
|
||||
* The filetree was updated.
|
||||
* @see #getChangedBuffer() to see the buffer that changed
|
||||
*/
|
||||
FILE_TREE_UPDATED
|
||||
}
|
||||
}
|
||||
|
|
11
dist/java/src/mp/code/data/TextChange.java
vendored
11
dist/java/src/mp/code/data/TextChange.java
vendored
|
@ -10,19 +10,18 @@ import lombok.ToString;
|
|||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public class TextChange {
|
||||
/**
|
||||
* The starting position of the change.
|
||||
* If negative, it is clamped to 0.
|
||||
*/
|
||||
public final long start;
|
||||
public final long startIdx;
|
||||
|
||||
/**
|
||||
* The ending position of the change.
|
||||
* If negative, it is clamped to 0.
|
||||
*/
|
||||
public final long end;
|
||||
public final long endIdx;
|
||||
|
||||
/**
|
||||
* The content of the change.
|
||||
|
@ -37,7 +36,7 @@ public class TextChange {
|
|||
* @return true if this change represents a deletion
|
||||
*/
|
||||
public boolean isDelete() {
|
||||
return this.start < this.end;
|
||||
return this.startIdx < this.endIdx;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,14 +63,14 @@ public class TextChange {
|
|||
* @return the mutated string
|
||||
*/
|
||||
public String apply(String input) {
|
||||
long preIndex = Math.min(this.start, input.length());
|
||||
long preIndex = Math.min(this.startIdx, input.length());
|
||||
String pre = "";
|
||||
try {
|
||||
pre = input.substring(0, (int) preIndex);
|
||||
} catch(IndexOutOfBoundsException ignored) {}
|
||||
String post = "";
|
||||
try {
|
||||
post = input.substring((int) this.end);
|
||||
post = input.substring((int) this.endIdx);
|
||||
} catch(IndexOutOfBoundsException ignored) {}
|
||||
return pre + this.content + post;
|
||||
}
|
||||
|
|
81
dist/lua/annotations.lua
vendored
81
dist/lua/annotations.lua
vendored
|
@ -158,16 +158,32 @@ function MaybeBufferUpdatePromise:cancel() end
|
|||
---invoke callback asynchronously as soon as promise is ready
|
||||
function MaybeBufferUpdatePromise:and_then(cb) end
|
||||
|
||||
---@class (exact) UserListPromise : Promise
|
||||
local UserListPromise = {}
|
||||
--- block until promise is ready and return value
|
||||
--- @return User[]
|
||||
function UserListPromise:await() end
|
||||
--- cancel promise execution
|
||||
function UserListPromise:cancel() end
|
||||
---@param cb fun(x: User[]) callback to invoke
|
||||
---invoke callback asynchronously as soon as promise is ready
|
||||
function UserListPromise:and_then(cb) end
|
||||
|
||||
-- [[ END ASYNC STUFF ]]
|
||||
|
||||
|
||||
---@class (exact) Client
|
||||
---@field id string uuid of local user
|
||||
---@field username string name of local user
|
||||
---@field active_workspaces string[] array of all currently active workspace names
|
||||
---the effective local client, handling connecting to codemp server
|
||||
local Client = {}
|
||||
|
||||
---@return User
|
||||
---current logged in user for this client
|
||||
function Client:current_user() end
|
||||
|
||||
---@return string[]
|
||||
---array of all currently active workspace names
|
||||
function Client:active_workspaces() end
|
||||
|
||||
---@return NilPromise
|
||||
---@async
|
||||
---@nodiscard
|
||||
|
@ -179,7 +195,7 @@ function Client:refresh() end
|
|||
---@async
|
||||
---@nodiscard
|
||||
---join requested workspace if possible and subscribe to event bus
|
||||
function Client:join_workspace(ws) end
|
||||
function Client:attach_workspace(ws) end
|
||||
|
||||
---@param ws string workspace id to create
|
||||
---@return NilPromise
|
||||
|
@ -207,13 +223,17 @@ function Client:delete_workspace(ws) end
|
|||
---grant user acccess to workspace
|
||||
function Client:invite_to_workspace(ws, user) end
|
||||
|
||||
---@param owned boolean? list owned workspaces, default true
|
||||
---@param invited boolean? list invited workspaces, default true
|
||||
---@return StringArrayPromise
|
||||
---@async
|
||||
---@nodiscard
|
||||
---grant user acccess to workspace
|
||||
function Client:list_workspaces(owned, invited) end
|
||||
---fetch and list owned workspaces
|
||||
function Client:fetch_owned_workspaces() end
|
||||
|
||||
---@return StringArrayPromise
|
||||
---@async
|
||||
---@nodiscard
|
||||
---fetch and list joined workspaces
|
||||
function Client:fetch_joined_workspaces() end
|
||||
|
||||
---@param ws string workspace id to get
|
||||
---@return Workspace?
|
||||
|
@ -222,26 +242,41 @@ function Client:get_workspace(ws) end
|
|||
|
||||
|
||||
|
||||
---@class User
|
||||
---@field id string user uuid
|
||||
---@field name string user display name
|
||||
|
||||
|
||||
|
||||
---@class (exact) Workspace
|
||||
---@field name string workspace name
|
||||
---@field cursor CursorController workspace cursor controller
|
||||
---@field active_buffers string[] array of all currently active buffer names
|
||||
---a joined codemp workspace
|
||||
local Workspace = {}
|
||||
|
||||
---@return string
|
||||
---workspace id
|
||||
function Workspace:id() end
|
||||
|
||||
---@return string[]
|
||||
---array of all currently active buffer names
|
||||
function Workspace:active_buffers() end
|
||||
|
||||
---@return CursorController
|
||||
---reference to workspace's CursorController
|
||||
function Workspace:cursor() end
|
||||
|
||||
---@param path string relative path ("name") of new buffer
|
||||
---@return NilPromise
|
||||
---@async
|
||||
---@nodiscard
|
||||
---create a new empty buffer
|
||||
function Workspace:create(path) end
|
||||
function Workspace:create_buffer(path) end
|
||||
|
||||
---@param path string relative path ("name") of buffer to delete
|
||||
---@return NilPromise
|
||||
---@async
|
||||
---@nodiscard
|
||||
---delete buffer from workspace
|
||||
function Workspace:delete(path) end
|
||||
function Workspace:delete_buffer(path) end
|
||||
|
||||
---@param path string relative path ("name") of buffer to get
|
||||
---@return BufferController?
|
||||
|
@ -253,20 +288,19 @@ function Workspace:get_buffer(path) end
|
|||
---@async
|
||||
---@nodiscard
|
||||
---attach to a remote buffer, synching content and changes and returning its controller
|
||||
function Workspace:attach(path) end
|
||||
function Workspace:attach_buffer(path) end
|
||||
|
||||
---@param path string relative path ("name") of buffer to detach from
|
||||
---@return boolean success
|
||||
---detach from an active buffer, closing all streams. returns false if there are still dangling references
|
||||
function Workspace:detach(path) end
|
||||
function Workspace:detach_buffer(path) end
|
||||
|
||||
---@param filter? string apply a filter to the return elements
|
||||
---@param strict? boolean whether to strictly match or just check whether it starts with it
|
||||
---@return string[]
|
||||
---return the list of available buffers in this workspace, as relative paths from workspace root
|
||||
function Workspace:filetree(filter, strict) end
|
||||
function Workspace:search_buffers(filter) end
|
||||
|
||||
---@return string[]
|
||||
---@return User[]
|
||||
---return all names of users currently in this workspace
|
||||
function Workspace:user_list() end
|
||||
|
||||
|
@ -282,6 +316,13 @@ function Workspace:fetch_buffers(path) end
|
|||
---force refresh users list from workspace
|
||||
function Workspace:fetch_users(path) end
|
||||
|
||||
---@param path string the buffer to look in
|
||||
---@return UserListPromise
|
||||
---@async
|
||||
---@nodiscard
|
||||
---fetch the list of users in the given buffer
|
||||
function Workspace:fetch_buffer_users(path) end
|
||||
|
||||
---@class (exact) WorkspaceEvent
|
||||
---@field type string
|
||||
---@field value string
|
||||
|
@ -320,8 +361,8 @@ local BufferController = {}
|
|||
|
||||
---@class TextChange
|
||||
---@field content string text content of change
|
||||
---@field start integer start index of change
|
||||
---@field finish integer end index of change
|
||||
---@field start_idx integer start index of change
|
||||
---@field end_idx integer end index of change
|
||||
local TextChange = {}
|
||||
|
||||
---@class (exact) BufferUpdate
|
||||
|
|
106
dist/py/src/codemp/codemp.pyi
vendored
106
dist/py/src/codemp/codemp.pyi
vendored
|
@ -7,6 +7,13 @@ class Driver:
|
|||
"""
|
||||
def stop(self) -> None: ...
|
||||
|
||||
class User:
|
||||
"""
|
||||
A remote user, with uuid and username
|
||||
"""
|
||||
id: str
|
||||
name: str
|
||||
|
||||
class Config:
|
||||
"""
|
||||
Configuration data structure for codemp clients
|
||||
|
@ -17,7 +24,7 @@ class Config:
|
|||
port: Optional[int]
|
||||
tls: Optional[bool]
|
||||
|
||||
def __new__(cls, *, username: str, password: str, **kwargs) -> Config: ...
|
||||
def __new__(cls, username: str, password: str, **kwargs) -> Config: ...
|
||||
|
||||
def init() -> Driver: ...
|
||||
def set_logger(logger_cb: Callable[[str], None], debug: bool) -> bool: ...
|
||||
|
@ -32,25 +39,25 @@ class Promise[T]:
|
|||
|
||||
It can either be used directly or you can wrap it inside a future python side.
|
||||
"""
|
||||
def wait(self) -> T: ...
|
||||
def is_done(self) -> bool: ...
|
||||
def wait(self) -> T: ...
|
||||
def is_done(self) -> bool: ...
|
||||
|
||||
class Client:
|
||||
"""
|
||||
Handle to the actual client that manages the session. It manages the connection
|
||||
to a server and joining/creating new workspaces
|
||||
"""
|
||||
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 attach_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 get_workspace(self, id: str) -> Workspace: ...
|
||||
def active_workspaces(self) -> list[str]: ...
|
||||
def user_id(self) -> str: ...
|
||||
def user_name(self) -> str: ...
|
||||
def refresh(self) -> Promise[None]: ...
|
||||
def fetch_owned_workspaces(self) -> Promise[list[str]]: ...
|
||||
def fetch_joined_workspaces(self) -> Promise[list[str]]: ...
|
||||
def leave_workspace(self, workspace: str) -> bool: ...
|
||||
def get_workspace(self, id: str) -> Workspace: ...
|
||||
def active_workspaces(self) -> list[str]: ...
|
||||
def current_user(self) -> User: ...
|
||||
def refresh(self) -> Promise[None]: ...
|
||||
|
||||
class Event:
|
||||
pass
|
||||
|
@ -60,22 +67,23 @@ class Workspace:
|
|||
Handle to a workspace inside codemp. It manages buffers.
|
||||
A cursor is tied to the single workspace.
|
||||
"""
|
||||
def create(self, path: str) -> Promise[None]: ...
|
||||
def attach(self, path: str) -> Promise[BufferController]: ...
|
||||
def detach(self, path: str) -> bool: ...
|
||||
def fetch_buffers(self) -> Promise[None]: ...
|
||||
def fetch_users(self) -> Promise[None]: ...
|
||||
def list_buffer_users(self, path: str) -> Promise[list[str]]: ...
|
||||
def delete(self, path: str) -> Promise[None]: ...
|
||||
def id(self) -> str: ...
|
||||
def cursor(self) -> CursorController: ...
|
||||
def buffer_by_name(self, path: str) -> Optional[BufferController]: ...
|
||||
def buffer_list(self) -> list[str]: ...
|
||||
def filetree(self, filter: Optional[str], strict: bool) -> list[str]: ...
|
||||
def recv(self) -> Promise[Event]: ...
|
||||
def try_recv(self) -> Promise[Optional[Event]]: ...
|
||||
def poll(self) -> Promise[None]: ...
|
||||
def clear_callback(self) -> None: ...
|
||||
def create_buffer(self, path: str) -> Promise[None]: ...
|
||||
def attach_buffer(self, path: str) -> Promise[BufferController]: ...
|
||||
def detach_buffer(self, path: str) -> bool: ...
|
||||
def fetch_buffers(self) -> Promise[list[str]]: ...
|
||||
def fetch_users(self) -> Promise[list[User]]: ...
|
||||
def fetch_buffer_users(self, path: str) -> Promise[list[User]]: ...
|
||||
def delete_buffer(self, path: str) -> Promise[None]: ...
|
||||
def id(self) -> str: ...
|
||||
def cursor(self) -> CursorController: ...
|
||||
def get_buffer(self, path: str) -> Optional[BufferController]: ...
|
||||
def user_list(self) -> list[User]: ...
|
||||
def active_buffers(self) -> list[str]: ...
|
||||
def search_buffers(self, filter: Optional[str]) -> list[str]: ...
|
||||
def recv(self) -> Promise[Event]: ...
|
||||
def try_recv(self) -> Promise[Optional[Event]]: ...
|
||||
def poll(self) -> Promise[None]: ...
|
||||
def clear_callback(self) -> None: ...
|
||||
def callback(self, cb: Callable[[Workspace], None]) -> None: ...
|
||||
|
||||
class TextChange:
|
||||
|
@ -87,10 +95,10 @@ class TextChange:
|
|||
end: int
|
||||
content: str
|
||||
|
||||
def is_delete(self) -> bool: ...
|
||||
def is_insert(self) -> bool: ...
|
||||
def is_empty(self) -> bool: ...
|
||||
def apply(self, txt: str) -> str: ...
|
||||
def is_delete(self) -> bool: ...
|
||||
def is_insert(self) -> bool: ...
|
||||
def is_empty(self) -> bool: ...
|
||||
def apply(self, txt: str) -> str: ...
|
||||
|
||||
class BufferUpdate:
|
||||
"""
|
||||
|
@ -106,19 +114,16 @@ class BufferController:
|
|||
Handle to the controller for a specific buffer, which manages the back and forth
|
||||
of operations to and from other peers.
|
||||
"""
|
||||
def path(self) -> str: ...
|
||||
def content(self) -> Promise[str]: ...
|
||||
def ack(self, v: list[int]) -> None: ...
|
||||
def send(self,
|
||||
start: int,
|
||||
end: int,
|
||||
txt: str) -> Promise[None]: ...
|
||||
def try_recv(self) -> Promise[Optional[TextChange]]: ...
|
||||
def recv(self) -> Promise[TextChange]: ...
|
||||
def poll(self) -> Promise[None]: ...
|
||||
def path(self) -> str: ...
|
||||
def content(self) -> Promise[str]: ...
|
||||
def ack(self, v: list[int]) -> None: ...
|
||||
def send(self, op: TextChange) -> None: ...
|
||||
def try_recv(self) -> Promise[Optional[TextChange]]: ...
|
||||
def recv(self) -> Promise[TextChange]: ...
|
||||
def poll(self) -> Promise[None]: ...
|
||||
def callback(self,
|
||||
cb: Callable[[BufferController], None]) -> None: ...
|
||||
def clear_callback(self) -> None: ...
|
||||
def clear_callback(self) -> None: ...
|
||||
|
||||
|
||||
|
||||
|
@ -143,14 +148,11 @@ class CursorController:
|
|||
Handle to the controller for a workspace, which manages the back and forth of
|
||||
cursor movements to and from other peers
|
||||
"""
|
||||
def send(self,
|
||||
path: str,
|
||||
start: Tuple[int, int],
|
||||
end: Tuple[int, int]) -> Promise[None]: ...
|
||||
def try_recv(self) -> Promise[Optional[Cursor]]: ...
|
||||
def recv(self) -> Promise[Cursor]: ...
|
||||
def poll(self) -> Promise[None]: ...
|
||||
def send(self, pos: Selection) -> None: ...
|
||||
def try_recv(self) -> Promise[Optional[Cursor]]: ...
|
||||
def recv(self) -> Promise[Cursor]: ...
|
||||
def poll(self) -> Promise[None]: ...
|
||||
def callback(self,
|
||||
cb: Callable[[CursorController], None]) -> None: ...
|
||||
def clear_callback(self) -> None: ...
|
||||
def clear_callback(self) -> None: ...
|
||||
|
||||
|
|
|
@ -31,18 +31,18 @@ pub struct BufferUpdate {
|
|||
/// ### Examples
|
||||
/// To insert 'a' after 4th character we should send:
|
||||
/// ```
|
||||
/// codemp::api::TextChange { start: 4, end: 4, content: "a".into() };
|
||||
/// codemp::api::TextChange { start_idx: 4, end_idx: 4, content: "a".into() };
|
||||
/// ```
|
||||
///
|
||||
/// To delete the fourth character we should send:
|
||||
/// ```
|
||||
/// codemp::api::TextChange { start: 3, end: 4, content: "".into() };
|
||||
/// codemp::api::TextChange { start_idx: 3, end_idx: 4, content: "".into() };
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// let change = codemp::api::TextChange {
|
||||
/// start: 6,
|
||||
/// end: 11,
|
||||
/// start_idx: 6,
|
||||
/// end_idx: 11,
|
||||
/// content: "mom".to_string()
|
||||
/// };
|
||||
/// let before = "hello world!";
|
||||
|
@ -55,10 +55,9 @@ pub struct BufferUpdate {
|
|||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct TextChange {
|
||||
/// Range start of text change, as char indexes in buffer previous state.
|
||||
pub start: u32,
|
||||
pub start_idx: u32,
|
||||
/// Range end of text change, as char indexes in buffer previous state.
|
||||
#[cfg_attr(feature = "serialize", serde(alias = "finish"))] // Lua uses `end` as keyword
|
||||
pub end: u32,
|
||||
pub end_idx: u32,
|
||||
/// New content of text inside span.
|
||||
pub content: String,
|
||||
}
|
||||
|
@ -66,7 +65,7 @@ pub struct TextChange {
|
|||
impl TextChange {
|
||||
/// Returns the [`std::ops::Range`] representing this change's span.
|
||||
pub fn span(&self) -> std::ops::Range<usize> {
|
||||
self.start as usize..self.end as usize
|
||||
self.start_idx as usize..self.end_idx as usize
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +75,7 @@ impl TextChange {
|
|||
///
|
||||
/// Note that this is is **not** mutually exclusive with [TextChange::is_insert].
|
||||
pub fn is_delete(&self) -> bool {
|
||||
self.start < self.end
|
||||
self.start_idx < self.end_idx
|
||||
}
|
||||
|
||||
/// Returns true if this [`TextChange`] adds new text.
|
||||
|
@ -93,9 +92,9 @@ impl TextChange {
|
|||
|
||||
/// Applies this text change to given text, returning a new string.
|
||||
pub fn apply(&self, txt: &str) -> String {
|
||||
let pre_index = std::cmp::min(self.start as usize, txt.len());
|
||||
let pre_index = std::cmp::min(self.start_idx as usize, txt.len());
|
||||
let pre = txt.get(..pre_index).unwrap_or("").to_string();
|
||||
let post = txt.get(self.end as usize..).unwrap_or("").to_string();
|
||||
let post = txt.get(self.end_idx as usize..).unwrap_or("").to_string();
|
||||
format!("{}{}{}", pre, self.content, post)
|
||||
}
|
||||
}
|
||||
|
@ -105,8 +104,8 @@ mod tests {
|
|||
#[test]
|
||||
fn textchange_apply_works_for_insertions() {
|
||||
let change = super::TextChange {
|
||||
start: 5,
|
||||
end: 5,
|
||||
start_idx: 5,
|
||||
end_idx: 5,
|
||||
content: " cruel".to_string(),
|
||||
};
|
||||
let result = change.apply("hello world!");
|
||||
|
@ -116,8 +115,8 @@ mod tests {
|
|||
#[test]
|
||||
fn textchange_apply_works_for_deletions() {
|
||||
let change = super::TextChange {
|
||||
start: 5,
|
||||
end: 11,
|
||||
start_idx: 5,
|
||||
end_idx: 11,
|
||||
content: "".to_string(),
|
||||
};
|
||||
let result = change.apply("hello cruel world!");
|
||||
|
@ -127,8 +126,8 @@ mod tests {
|
|||
#[test]
|
||||
fn textchange_apply_works_for_replacements() {
|
||||
let change = super::TextChange {
|
||||
start: 5,
|
||||
end: 11,
|
||||
start_idx: 5,
|
||||
end_idx: 11,
|
||||
content: " not very pleasant".to_string(),
|
||||
};
|
||||
let result = change.apply("hello cruel world!");
|
||||
|
@ -138,8 +137,8 @@ mod tests {
|
|||
#[test]
|
||||
fn textchange_apply_never_panics() {
|
||||
let change = super::TextChange {
|
||||
start: 100,
|
||||
end: 110,
|
||||
start_idx: 100,
|
||||
end_idx: 110,
|
||||
content: "a very long string \n which totally matters".to_string(),
|
||||
};
|
||||
let result = change.apply("a short text");
|
||||
|
@ -152,8 +151,8 @@ mod tests {
|
|||
#[test]
|
||||
fn empty_textchange_doesnt_alter_buffer() {
|
||||
let change = super::TextChange {
|
||||
start: 42,
|
||||
end: 42,
|
||||
start_idx: 42,
|
||||
end_idx: 42,
|
||||
content: "".to_string(),
|
||||
};
|
||||
let result = change.apply("some important text");
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
//! # Event
|
||||
//! Real time notification of changes in a workspace, to either users or buffers.
|
||||
#![allow(non_upper_case_globals, non_camel_case_types)] // pyo3 fix your shit
|
||||
|
||||
use codemp_proto::workspace::workspace_event::Event as WorkspaceEventInner;
|
||||
|
||||
/// Event in a [crate::Workspace].
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(any(feature = "py", feature = "py-noabi"), pyo3::pyclass)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serialize", serde(tag = "type"))]
|
||||
pub enum Event {
|
||||
/// Fired when the file tree changes.
|
||||
/// Contains the modified buffer path (deleted, created or renamed).
|
||||
FileTreeUpdated(String),
|
||||
FileTreeUpdated { path: String },
|
||||
/// Fired when an user joins the current workspace.
|
||||
UserJoin(String),
|
||||
UserJoin { name: String },
|
||||
/// Fired when an user leaves the current workspace.
|
||||
UserLeave(String),
|
||||
UserLeave { name: String },
|
||||
}
|
||||
|
||||
impl From<WorkspaceEventInner> for Event {
|
||||
fn from(event: WorkspaceEventInner) -> Self {
|
||||
match event {
|
||||
WorkspaceEventInner::Join(e) => Self::UserJoin(e.user.name),
|
||||
WorkspaceEventInner::Leave(e) => Self::UserLeave(e.user.name),
|
||||
WorkspaceEventInner::Create(e) => Self::FileTreeUpdated(e.path),
|
||||
WorkspaceEventInner::Delete(e) => Self::FileTreeUpdated(e.path),
|
||||
WorkspaceEventInner::Rename(e) => Self::FileTreeUpdated(e.after),
|
||||
WorkspaceEventInner::Join(e) => Self::UserJoin { name: e.user.name },
|
||||
WorkspaceEventInner::Leave(e) => Self::UserLeave { name: e.user.name },
|
||||
WorkspaceEventInner::Create(e) => Self::FileTreeUpdated { path: e.path },
|
||||
WorkspaceEventInner::Delete(e) => Self::FileTreeUpdated { path: e.path },
|
||||
WorkspaceEventInner::Rename(e) => Self::FileTreeUpdated { path: e.after },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,9 @@ pub mod event;
|
|||
/// data structure for remote users
|
||||
pub mod user;
|
||||
|
||||
pub use change::BufferUpdate;
|
||||
pub use change::TextChange;
|
||||
pub use change::{BufferUpdate, TextChange};
|
||||
pub use config::Config;
|
||||
pub use controller::Controller;
|
||||
pub use cursor::Cursor;
|
||||
pub use cursor::Selection;
|
||||
pub use controller::{AsyncReceiver, AsyncSender, Controller};
|
||||
pub use cursor::{Cursor, Selection};
|
||||
pub use event::Event;
|
||||
pub use user::User;
|
||||
|
|
|
@ -6,6 +6,7 @@ use uuid::Uuid;
|
|||
|
||||
/// Represents a service user
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(any(feature = "py", feature = "py-noabi"), pyo3::pyclass)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct User {
|
||||
/// User unique identifier, should never change.
|
||||
|
|
|
@ -160,8 +160,8 @@ impl BufferWorker {
|
|||
async fn handle_editor_change(&mut self, change: TextChange, tx: &mpsc::Sender<Operation>) {
|
||||
let last_ver = self.oplog.local_version();
|
||||
// clip to buffer extents
|
||||
let clip_start = change.start as usize;
|
||||
let mut clip_end = change.end as usize;
|
||||
let clip_start = change.start_idx as usize;
|
||||
let mut clip_end = change.end_idx as usize;
|
||||
let b_len = self.branch.len();
|
||||
if clip_end > b_len {
|
||||
tracing::warn!("clipping TextChange end span from {clip_end} to {b_len}");
|
||||
|
@ -170,8 +170,11 @@ impl BufferWorker {
|
|||
|
||||
// in case we have a "replace" span
|
||||
if change.is_delete() {
|
||||
self.branch
|
||||
.delete_without_content(&mut self.oplog, self.agent_id, clip_start..clip_end);
|
||||
self.branch.delete_without_content(
|
||||
&mut self.oplog,
|
||||
self.agent_id,
|
||||
clip_start..clip_end,
|
||||
);
|
||||
}
|
||||
|
||||
if change.is_insert() {
|
||||
|
@ -247,7 +250,9 @@ impl BufferWorker {
|
|||
{
|
||||
tracing::warn!(
|
||||
"Insert span ({}, {}) differs from effective content len ({})",
|
||||
dtop.start(), dtop.end(), dtop.content_as_str().unwrap_or_default().len()
|
||||
dtop.start(),
|
||||
dtop.end(),
|
||||
dtop.content_as_str().unwrap_or_default().len()
|
||||
);
|
||||
}
|
||||
crate::api::BufferUpdate {
|
||||
|
@ -257,8 +262,8 @@ impl BufferWorker {
|
|||
.map(|x| i64::from_ne_bytes(x.to_ne_bytes()))
|
||||
.collect(), // TODO this is wasteful
|
||||
change: crate::api::TextChange {
|
||||
start: dtop.start() as u32,
|
||||
end: dtop.start() as u32,
|
||||
start_idx: dtop.start() as u32,
|
||||
end_idx: dtop.start() as u32,
|
||||
content: dtop.content_as_str().unwrap_or_default().to_string(),
|
||||
},
|
||||
}
|
||||
|
@ -271,8 +276,8 @@ impl BufferWorker {
|
|||
.map(|x| i64::from_ne_bytes(x.to_ne_bytes()))
|
||||
.collect(), // TODO this is wasteful
|
||||
change: crate::api::TextChange {
|
||||
start: dtop.start() as u32,
|
||||
end: dtop.end() as u32,
|
||||
start_idx: dtop.start() as u32,
|
||||
end_idx: dtop.end() as u32,
|
||||
content: dtop.content_as_str().unwrap_or_default().to_string(),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -130,9 +130,18 @@ impl Client {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// List all available workspaces, also filtering between those owned and those invited to.
|
||||
pub async fn list_workspaces(&self, owned: bool, invited: bool) -> RemoteResult<Vec<String>> {
|
||||
let mut workspaces = self
|
||||
/// Fetch the names of all workspaces owned by the current user.
|
||||
pub async fn fetch_owned_workspaces(&self) -> RemoteResult<Vec<String>> {
|
||||
self.fetch_workspaces(true).await
|
||||
}
|
||||
|
||||
/// Fetch the names of all workspaces the current user has joined.
|
||||
pub async fn fetch_joined_workspaces(&self) -> RemoteResult<Vec<String>> {
|
||||
self.fetch_workspaces(false).await
|
||||
}
|
||||
|
||||
async fn fetch_workspaces(&self, owned: bool) -> RemoteResult<Vec<String>> {
|
||||
let workspaces = self
|
||||
.0
|
||||
.session
|
||||
.clone()
|
||||
|
@ -140,20 +149,18 @@ impl Client {
|
|||
.await?
|
||||
.into_inner();
|
||||
|
||||
let mut out = Vec::new();
|
||||
|
||||
if owned {
|
||||
out.append(&mut workspaces.owned)
|
||||
Ok(workspaces.owned)
|
||||
} else {
|
||||
Ok(workspaces.invited)
|
||||
}
|
||||
if invited {
|
||||
out.append(&mut workspaces.invited)
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Join and return a [`Workspace`].
|
||||
pub async fn join_workspace(&self, workspace: impl AsRef<str>) -> ConnectionResult<Workspace> {
|
||||
pub async fn attach_workspace(
|
||||
&self,
|
||||
workspace: impl AsRef<str>,
|
||||
) -> ConnectionResult<Workspace> {
|
||||
let token = self
|
||||
.0
|
||||
.session
|
||||
|
@ -203,7 +210,7 @@ impl Client {
|
|||
}
|
||||
|
||||
/// Get the currently logged in user.
|
||||
pub fn user(&self) -> &User {
|
||||
pub fn current_user(&self) -> &User {
|
||||
&self.0.user
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,7 @@ use jni::{objects::JObject, JNIEnv};
|
|||
use jni_toolbox::jni;
|
||||
|
||||
use crate::{
|
||||
api::{
|
||||
controller::{AsyncReceiver, AsyncSender},
|
||||
BufferUpdate, TextChange,
|
||||
},
|
||||
api::{AsyncReceiver, AsyncSender, BufferUpdate, TextChange},
|
||||
errors::ControllerError,
|
||||
};
|
||||
|
||||
|
|
|
@ -7,21 +7,21 @@ use crate::{
|
|||
use jni_toolbox::jni;
|
||||
|
||||
/// Connect using the given credentials to the default server, and return a [Client] to interact with it.
|
||||
#[jni(package = "mp.code", class = "Client", ptr)]
|
||||
#[jni(package = "mp.code", class = "Client")]
|
||||
fn connect(config: Config) -> Result<Client, ConnectionError> {
|
||||
super::tokio().block_on(Client::connect(config))
|
||||
}
|
||||
|
||||
/// Gets the current [crate::api::User].
|
||||
#[jni(package = "mp.code", class = "Client", ptr)]
|
||||
fn get_user(client: &mut Client) -> crate::api::User {
|
||||
client.user().clone()
|
||||
#[jni(package = "mp.code", class = "Client")]
|
||||
fn current_user(client: &mut Client) -> crate::api::User {
|
||||
client.current_user().clone()
|
||||
}
|
||||
|
||||
/// Join a [Workspace] and return a pointer to it.
|
||||
#[jni(package = "mp.code", class = "Client")]
|
||||
fn join_workspace(client: &mut Client, workspace: String) -> Result<Workspace, ConnectionError> {
|
||||
super::tokio().block_on(client.join_workspace(workspace))
|
||||
fn attach_workspace(client: &mut Client, workspace: String) -> Result<Workspace, ConnectionError> {
|
||||
super::tokio().block_on(client.attach_workspace(workspace))
|
||||
}
|
||||
|
||||
/// Create a workspace on server, if allowed to.
|
||||
|
@ -46,14 +46,16 @@ fn invite_to_workspace(
|
|||
super::tokio().block_on(client.invite_to_workspace(workspace, user))
|
||||
}
|
||||
|
||||
/// List available workspaces.
|
||||
/// List owned workspaces.
|
||||
#[jni(package = "mp.code", class = "Client")]
|
||||
fn list_workspaces(
|
||||
client: &mut Client,
|
||||
owned: bool,
|
||||
invited: bool,
|
||||
) -> Result<Vec<String>, RemoteError> {
|
||||
super::tokio().block_on(client.list_workspaces(owned, invited))
|
||||
fn fetch_owned_workspaces(client: &mut Client) -> Result<Vec<String>, RemoteError> {
|
||||
super::tokio().block_on(client.fetch_owned_workspaces())
|
||||
}
|
||||
|
||||
/// List joined workspaces.
|
||||
#[jni(package = "mp.code", class = "Client")]
|
||||
fn fetch_joined_workspaces(client: &mut Client) -> Result<Vec<String>, RemoteError> {
|
||||
super::tokio().block_on(client.fetch_joined_workspaces())
|
||||
}
|
||||
|
||||
/// List available workspaces.
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
use crate::{
|
||||
api::{
|
||||
controller::{AsyncReceiver, AsyncSender},
|
||||
Cursor, Selection,
|
||||
},
|
||||
api::{AsyncReceiver, AsyncSender, Cursor, Selection},
|
||||
errors::ControllerError,
|
||||
};
|
||||
use jni::{objects::JObject, JNIEnv};
|
||||
|
|
|
@ -170,9 +170,9 @@ impl<'j> jni_toolbox::IntoJavaObject<'j> for crate::api::Event {
|
|||
env: &mut jni::JNIEnv<'j>,
|
||||
) -> Result<jni::objects::JObject<'j>, jni::errors::Error> {
|
||||
let (ordinal, arg) = match self {
|
||||
crate::api::Event::UserJoin(arg) => (0, env.new_string(arg)?),
|
||||
crate::api::Event::UserLeave(arg) => (1, env.new_string(arg)?),
|
||||
crate::api::Event::FileTreeUpdated(arg) => (2, env.new_string(arg)?),
|
||||
crate::api::Event::UserJoin { name: arg } => (0, env.new_string(arg)?),
|
||||
crate::api::Event::UserLeave { name: arg } => (1, env.new_string(arg)?),
|
||||
crate::api::Event::FileTreeUpdated { path: arg } => (2, env.new_string(arg)?),
|
||||
};
|
||||
|
||||
let type_class = env.find_class("mp/code/Workspace$Event$Type")?;
|
||||
|
@ -242,8 +242,8 @@ impl<'j> jni_toolbox::IntoJavaObject<'j> for crate::api::TextChange {
|
|||
class,
|
||||
"(JJLjava/lang/String;)V",
|
||||
&[
|
||||
jni::objects::JValueGen::Long(self.start.into()),
|
||||
jni::objects::JValueGen::Long(self.end.into()),
|
||||
jni::objects::JValueGen::Long(self.start_idx.into()),
|
||||
jni::objects::JValueGen::Long(self.end_idx.into()),
|
||||
jni::objects::JValueGen::Object(&content),
|
||||
],
|
||||
)
|
||||
|
@ -438,11 +438,11 @@ impl<'j> jni_toolbox::FromJava<'j> for crate::api::TextChange {
|
|||
change: Self::From,
|
||||
) -> Result<Self, jni::errors::Error> {
|
||||
let start = env
|
||||
.get_field(&change, "start", "J")?
|
||||
.get_field(&change, "startIdx", "J")?
|
||||
.j()?
|
||||
.clamp(0, u32::MAX.into()) as u32;
|
||||
let end = env
|
||||
.get_field(&change, "end", "J")?
|
||||
.get_field(&change, "endIdx", "J")?
|
||||
.j()?
|
||||
.clamp(0, u32::MAX.into()) as u32;
|
||||
|
||||
|
@ -457,8 +457,8 @@ impl<'j> jni_toolbox::FromJava<'j> for crate::api::TextChange {
|
|||
};
|
||||
|
||||
Ok(Self {
|
||||
start,
|
||||
end,
|
||||
start_idx: start,
|
||||
end_idx: end,
|
||||
content,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
api::controller::AsyncReceiver,
|
||||
api::{controller::AsyncReceiver, User},
|
||||
errors::{ConnectionError, ControllerError, RemoteError},
|
||||
ffi::java::null_check,
|
||||
Workspace,
|
||||
|
@ -9,86 +9,86 @@ use jni_toolbox::jni;
|
|||
|
||||
/// Get the workspace id.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn get_workspace_id(workspace: &mut Workspace) -> String {
|
||||
fn id(workspace: &mut Workspace) -> String {
|
||||
workspace.id()
|
||||
}
|
||||
|
||||
/// Get a cursor controller by name and returns a pointer to it.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn get_cursor(workspace: &mut Workspace) -> crate::cursor::Controller {
|
||||
fn cursor(workspace: &mut Workspace) -> crate::cursor::Controller {
|
||||
workspace.cursor()
|
||||
}
|
||||
|
||||
/// Get a buffer controller by name and returns a pointer to it.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn get_buffer(workspace: &mut Workspace, path: String) -> Option<crate::buffer::Controller> {
|
||||
workspace.buffer_by_name(&path)
|
||||
workspace.get_buffer(&path)
|
||||
}
|
||||
|
||||
/// Get the filetree.
|
||||
/// Searches for buffers matching the filter.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn get_file_tree(workspace: &mut Workspace, filter: Option<String>, strict: bool) -> Vec<String> {
|
||||
workspace.filetree(filter.as_deref(), strict)
|
||||
fn search_buffers(workspace: &mut Workspace, filter: Option<String>) -> Vec<String> {
|
||||
workspace.search_buffers(filter.as_deref())
|
||||
}
|
||||
|
||||
/// Gets a list of the active buffers.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn active_buffers(workspace: &mut Workspace) -> Vec<String> {
|
||||
workspace.buffer_list()
|
||||
workspace.active_buffers()
|
||||
}
|
||||
|
||||
/// Gets a list of the active buffers.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn user_list(workspace: &mut Workspace) -> Vec<String> {
|
||||
fn user_list(workspace: &mut Workspace) -> Vec<User> {
|
||||
workspace.user_list()
|
||||
}
|
||||
|
||||
/// Create a new buffer.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn create_buffer(workspace: &mut Workspace, path: String) -> Result<(), RemoteError> {
|
||||
super::tokio().block_on(workspace.create(&path))
|
||||
super::tokio().block_on(workspace.create_buffer(&path))
|
||||
}
|
||||
|
||||
/// Attach to a buffer and return a pointer to its [crate::buffer::Controller].
|
||||
/// Attach to a buffer and return a pointer to its [`crate::buffer::Controller`].
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn attach_to_buffer(
|
||||
fn attach_buffer(
|
||||
workspace: &mut Workspace,
|
||||
path: String,
|
||||
) -> Result<crate::buffer::Controller, ConnectionError> {
|
||||
super::tokio().block_on(workspace.attach(&path))
|
||||
super::tokio().block_on(workspace.attach_buffer(&path))
|
||||
}
|
||||
|
||||
/// Detach from a buffer.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn detach_from_buffer(workspace: &mut Workspace, path: String) -> bool {
|
||||
workspace.detach(&path)
|
||||
fn detach_buffer(workspace: &mut Workspace, path: String) -> bool {
|
||||
workspace.detach_buffer(&path)
|
||||
}
|
||||
|
||||
/// Update the local buffer list.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn fetch_buffers(workspace: &mut Workspace) -> Result<(), RemoteError> {
|
||||
fn fetch_buffers(workspace: &mut Workspace) -> Result<Vec<String>, RemoteError> {
|
||||
super::tokio().block_on(workspace.fetch_buffers())
|
||||
}
|
||||
|
||||
/// Update the local user list.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn fetch_users(workspace: &mut Workspace) -> Result<(), RemoteError> {
|
||||
fn fetch_users(workspace: &mut Workspace) -> Result<Vec<User>, RemoteError> {
|
||||
super::tokio().block_on(workspace.fetch_users())
|
||||
}
|
||||
|
||||
/// List users attached to a buffer.
|
||||
/// Fetch users attached to a buffer.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn list_buffer_users(
|
||||
fn fetch_buffer_users(
|
||||
workspace: &mut Workspace,
|
||||
path: String,
|
||||
) -> Result<Vec<crate::api::User>, RemoteError> {
|
||||
super::tokio().block_on(workspace.list_buffer_users(&path))
|
||||
super::tokio().block_on(workspace.fetch_buffer_users(&path))
|
||||
}
|
||||
|
||||
/// Delete a buffer.
|
||||
#[jni(package = "mp.code", class = "Workspace")]
|
||||
fn delete_buffer(workspace: &mut Workspace, path: String) -> Result<(), RemoteError> {
|
||||
super::tokio().block_on(workspace.delete(&path))
|
||||
super::tokio().block_on(workspace.delete_buffer(&path))
|
||||
}
|
||||
|
||||
/// Block and receive a workspace event.
|
||||
|
|
|
@ -32,13 +32,13 @@ impl BufferController {
|
|||
}
|
||||
|
||||
/// Remove registered buffer callback
|
||||
#[napi(js_name = "clear_callback")]
|
||||
#[napi(js_name = "clearCallback")]
|
||||
pub fn js_clear_callback(&self) {
|
||||
self.clear_callback();
|
||||
}
|
||||
|
||||
/// Get buffer path
|
||||
#[napi(js_name = "get_path")]
|
||||
#[napi(js_name = "path")]
|
||||
pub fn js_path(&self) -> &str {
|
||||
self.path()
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ impl BufferController {
|
|||
}
|
||||
|
||||
/// Return next buffer event if present
|
||||
#[napi(js_name = "try_recv")]
|
||||
#[napi(js_name = "tryRecv")]
|
||||
pub async fn js_try_recv(&self) -> napi::Result<Option<BufferUpdate>> {
|
||||
Ok(self.try_recv().await?)
|
||||
}
|
||||
|
|
|
@ -34,29 +34,31 @@ pub async fn connect(config: crate::api::Config) -> napi::Result<crate::Client>
|
|||
|
||||
#[napi]
|
||||
impl Client {
|
||||
#[napi(js_name = "create_workspace")]
|
||||
#[napi(js_name = "createWorkspace")]
|
||||
/// 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")]
|
||||
#[napi(js_name = "deleteWorkspace")]
|
||||
/// 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 = "fetchOwnedWorkspaces")]
|
||||
/// fetch owned workspaces
|
||||
pub async fn js_fetch_owned_workspaces(&self) -> napi::Result<Vec<String>> {
|
||||
Ok(self.fetch_owned_workspaces().await?)
|
||||
}
|
||||
|
||||
#[napi(js_name = "invite_to_workspace")]
|
||||
#[napi(js_name = "fetchJoinedWorkspaces")]
|
||||
/// fetch joined workspaces
|
||||
pub async fn js_fetch_joined_workspaces(&self) -> napi::Result<Vec<String>> {
|
||||
Ok(self.fetch_joined_workspaces().await?)
|
||||
}
|
||||
|
||||
#[napi(js_name = "inviteToWorkspace")]
|
||||
/// invite user to given workspace, if able to
|
||||
pub async fn js_invite_to_workspace(
|
||||
&self,
|
||||
|
@ -66,31 +68,31 @@ impl Client {
|
|||
Ok(self.invite_to_workspace(workspace, user).await?)
|
||||
}
|
||||
|
||||
#[napi(js_name = "join_workspace")]
|
||||
#[napi(js_name = "attachWorkspace")]
|
||||
/// join workspace with given id (will start its cursor controller)
|
||||
pub async fn js_join_workspace(&self, workspace: String) -> napi::Result<Workspace> {
|
||||
Ok(self.join_workspace(workspace).await?)
|
||||
pub async fn js_attach_workspace(&self, workspace: String) -> napi::Result<Workspace> {
|
||||
Ok(self.attach_workspace(workspace).await?)
|
||||
}
|
||||
|
||||
#[napi(js_name = "leave_workspace")]
|
||||
#[napi(js_name = "leaveWorkspace")]
|
||||
/// leave workspace and disconnect, returns true if workspace was active
|
||||
pub async fn js_leave_workspace(&self, workspace: String) -> bool {
|
||||
self.leave_workspace(&workspace)
|
||||
}
|
||||
|
||||
#[napi(js_name = "get_workspace")]
|
||||
#[napi(js_name = "getWorkspace")]
|
||||
/// get workspace with given id, if it exists
|
||||
pub fn js_get_workspace(&self, workspace: String) -> Option<Workspace> {
|
||||
self.get_workspace(&workspace)
|
||||
}
|
||||
|
||||
#[napi(js_name = "user")]
|
||||
#[napi(js_name = "currentUser")]
|
||||
/// return current sessions's user id
|
||||
pub fn js_user(&self) -> JsUser {
|
||||
self.user().clone().into()
|
||||
pub fn js_current_user(&self) -> JsUser {
|
||||
self.current_user().clone().into()
|
||||
}
|
||||
|
||||
#[napi(js_name = "active_workspaces")]
|
||||
#[napi(js_name = "activeWorkspaces")]
|
||||
/// get list of all active workspaces
|
||||
pub fn js_active_workspaces(&self) -> Vec<String> {
|
||||
self.active_workspaces()
|
||||
|
|
|
@ -32,7 +32,7 @@ impl CursorController {
|
|||
}
|
||||
|
||||
/// Clear the registered callback
|
||||
#[napi(js_name = "clear_callback")]
|
||||
#[napi(js_name = "clearCallback")]
|
||||
pub fn js_clear_callback(&self) {
|
||||
self.clear_callback();
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ impl CursorController {
|
|||
}
|
||||
|
||||
/// Get next cursor event if available without blocking
|
||||
#[napi(js_name = "try_recv")]
|
||||
#[napi(js_name = "tryRecv")]
|
||||
pub async fn js_try_recv(&self) -> napi::Result<Option<crate::api::Cursor>> {
|
||||
Ok(self.try_recv().await?.map(crate::api::Cursor::from))
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ use napi::threadsafe_function::{
|
|||
};
|
||||
use napi_derive::napi;
|
||||
|
||||
use super::client::JsUser;
|
||||
|
||||
#[napi(object, js_name = "Event")]
|
||||
pub struct JsEvent {
|
||||
pub r#type: String,
|
||||
|
@ -17,15 +19,15 @@ pub struct JsEvent {
|
|||
impl From<crate::api::Event> for JsEvent {
|
||||
fn from(value: crate::api::Event) -> Self {
|
||||
match value {
|
||||
crate::api::Event::FileTreeUpdated(value) => Self {
|
||||
crate::api::Event::FileTreeUpdated { path: value } => Self {
|
||||
r#type: "filetree".into(),
|
||||
value,
|
||||
},
|
||||
crate::api::Event::UserJoin(value) => Self {
|
||||
crate::api::Event::UserJoin { name: value } => Self {
|
||||
r#type: "join".into(),
|
||||
value,
|
||||
},
|
||||
crate::api::Event::UserLeave(value) => Self {
|
||||
crate::api::Event::UserLeave { name: value } => Self {
|
||||
r#type: "leave".into(),
|
||||
value,
|
||||
},
|
||||
|
@ -42,21 +44,21 @@ impl Workspace {
|
|||
}
|
||||
|
||||
/// List all available buffers in this workspace
|
||||
#[napi(js_name = "filetree")]
|
||||
pub fn js_filetree(&self, filter: Option<&str>, strict: bool) -> Vec<String> {
|
||||
self.filetree(filter, strict)
|
||||
#[napi(js_name = "searchBuffers")]
|
||||
pub fn js_search_buffers(&self, filter: Option<&str>) -> Vec<String> {
|
||||
self.search_buffers(filter)
|
||||
}
|
||||
|
||||
/// List all user names currently in this workspace
|
||||
#[napi(js_name = "user_list")]
|
||||
pub fn js_user_list(&self) -> Vec<String> {
|
||||
self.user_list()
|
||||
#[napi(js_name = "userList")]
|
||||
pub fn js_user_list(&self) -> Vec<JsUser> {
|
||||
self.user_list().into_iter().map(JsUser::from).collect()
|
||||
}
|
||||
|
||||
/// List all currently active buffers
|
||||
#[napi(js_name = "buffer_list")]
|
||||
pub fn js_buffer_list(&self) -> Vec<String> {
|
||||
self.buffer_list()
|
||||
#[napi(js_name = "activeBuffers")]
|
||||
pub fn js_active_buffers(&self) -> Vec<String> {
|
||||
self.active_buffers()
|
||||
}
|
||||
|
||||
/// Get workspace's Cursor Controller
|
||||
|
@ -66,27 +68,27 @@ impl Workspace {
|
|||
}
|
||||
|
||||
/// Get a buffer controller by its name (path)
|
||||
#[napi(js_name = "buffer_by_name")]
|
||||
pub fn js_buffer_by_name(&self, path: String) -> Option<BufferController> {
|
||||
self.buffer_by_name(&path)
|
||||
#[napi(js_name = "getBuffer")]
|
||||
pub fn js_get_buffer(&self, path: String) -> Option<BufferController> {
|
||||
self.get_buffer(&path)
|
||||
}
|
||||
|
||||
/// Create a new buffer in the current workspace
|
||||
#[napi(js_name = "create")]
|
||||
pub async fn js_create(&self, path: String) -> napi::Result<()> {
|
||||
Ok(self.create(&path).await?)
|
||||
#[napi(js_name = "createBuffer")]
|
||||
pub async fn js_create_buffer(&self, path: String) -> napi::Result<()> {
|
||||
Ok(self.create_buffer(&path).await?)
|
||||
}
|
||||
|
||||
/// Attach to a workspace buffer, starting a BufferController
|
||||
#[napi(js_name = "attach")]
|
||||
pub async fn js_attach(&self, path: String) -> napi::Result<BufferController> {
|
||||
Ok(self.attach(&path).await?)
|
||||
#[napi(js_name = "attachBuffer")]
|
||||
pub async fn js_attach_buffer(&self, path: String) -> napi::Result<BufferController> {
|
||||
Ok(self.attach_buffer(&path).await?)
|
||||
}
|
||||
|
||||
/// Delete a buffer from workspace
|
||||
#[napi(js_name = "delete")]
|
||||
pub async fn js_delete(&self, path: String) -> napi::Result<()> {
|
||||
Ok(self.delete(&path).await?)
|
||||
#[napi(js_name = "deleteBuffer")]
|
||||
pub async fn js_delete_buffer(&self, path: String) -> napi::Result<()> {
|
||||
Ok(self.delete_buffer(&path).await?)
|
||||
}
|
||||
|
||||
#[napi(js_name = "recv")]
|
||||
|
@ -94,7 +96,7 @@ impl Workspace {
|
|||
Ok(JsEvent::from(self.recv().await?))
|
||||
}
|
||||
|
||||
#[napi(js_name = "try_recv")]
|
||||
#[napi(js_name = "tryRecv")]
|
||||
pub async fn js_try_recv(&self) -> napi::Result<Option<JsEvent>> {
|
||||
Ok(self.try_recv().await?.map(JsEvent::from))
|
||||
}
|
||||
|
@ -105,7 +107,7 @@ impl Workspace {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[napi(js_name = "clear_callback")]
|
||||
#[napi(js_name = "clearCallback")]
|
||||
pub fn js_clear_callback(&self) -> napi::Result<()> {
|
||||
self.clear_callback();
|
||||
Ok(())
|
||||
|
@ -119,7 +121,7 @@ impl Workspace {
|
|||
})?;
|
||||
self.callback(move |controller: Workspace| {
|
||||
tsfn.call(controller.clone(), ThreadsafeFunctionCallMode::Blocking); //check this with tracing also we could use Ok(event) to get the error
|
||||
// If it blocks the main thread too many time we have to change this
|
||||
// If it blocks the main thread too many time we have to change this
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -128,30 +130,35 @@ impl Workspace {
|
|||
/// Detach from an active buffer, stopping its underlying worker
|
||||
/// this method returns true if no reference or last reference was held, false if there are still
|
||||
/// dangling references to clear
|
||||
#[napi(js_name = "detach")]
|
||||
pub async fn js_detach(&self, path: String) -> bool {
|
||||
self.detach(&path)
|
||||
#[napi(js_name = "detachBuffer")]
|
||||
pub async fn js_detach_buffer(&self, path: String) -> bool {
|
||||
self.detach_buffer(&path)
|
||||
}
|
||||
|
||||
/// Re-fetch remote buffer list
|
||||
#[napi(js_name = "fetch_buffers")]
|
||||
pub async fn js_fetch_buffers(&self) -> napi::Result<()> {
|
||||
#[napi(js_name = "fetchBuffers")]
|
||||
pub async fn js_fetch_buffers(&self) -> napi::Result<Vec<String>> {
|
||||
Ok(self.fetch_buffers().await?)
|
||||
}
|
||||
/// Re-fetch the list of all users in the workspace.
|
||||
#[napi(js_name = "fetch_users")]
|
||||
pub async fn js_fetch_users(&self) -> napi::Result<()> {
|
||||
Ok(self.fetch_users().await?)
|
||||
#[napi(js_name = "fetchUsers")]
|
||||
pub async fn js_fetch_users(&self) -> napi::Result<Vec<JsUser>> {
|
||||
Ok(self
|
||||
.fetch_users()
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(JsUser::from)
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// List users attached to a specific buffer
|
||||
#[napi(js_name = "list_buffer_users")]
|
||||
pub async fn js_list_buffer_users(
|
||||
#[napi(js_name = "fetchBufferUsers")]
|
||||
pub async fn js_fetch_buffer_users(
|
||||
&self,
|
||||
path: String,
|
||||
) -> napi::Result<Vec<crate::ffi::js::client::JsUser>> {
|
||||
Ok(self
|
||||
.list_buffer_users(&path)
|
||||
.fetch_buffer_users(&path)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(super::client::JsUser::from)
|
||||
|
|
|
@ -3,7 +3,8 @@ use mlua::prelude::*;
|
|||
use mlua_codemp_patch as mlua;
|
||||
|
||||
use super::ext::a_sync::a_sync;
|
||||
use super::ext::from_lua_serde;
|
||||
|
||||
super::ext::impl_lua_serde! { CodempTextChange CodempBufferUpdate }
|
||||
|
||||
impl LuaUserData for CodempBufferController {
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
|
@ -38,36 +39,3 @@ impl LuaUserData for CodempBufferController {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
from_lua_serde! { CodempTextChange }
|
||||
impl LuaUserData for CodempTextChange {
|
||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("content", |_, this| Ok(this.content.clone()));
|
||||
fields.add_field_method_get("start", |_, this| Ok(this.start));
|
||||
fields.add_field_method_get("end", |_, this| Ok(this.end));
|
||||
// add a 'finish' accessor too because in Lua 'end' is reserved
|
||||
fields.add_field_method_get("finish", |_, this| Ok(this.end));
|
||||
}
|
||||
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| {
|
||||
Ok(format!("{:?}", this))
|
||||
});
|
||||
methods.add_method("apply", |_, this, (txt,): (String,)| Ok(this.apply(&txt)));
|
||||
}
|
||||
}
|
||||
|
||||
from_lua_serde! { CodempBufferUpdate }
|
||||
impl LuaUserData for CodempBufferUpdate {
|
||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("hash", |_, this| Ok(this.hash));
|
||||
fields.add_field_method_get("version", |_, this| Ok(this.version.clone()));
|
||||
fields.add_field_method_get("change", |_, this| Ok(this.change.clone()));
|
||||
}
|
||||
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| {
|
||||
Ok(format!("{:?}", this))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,28 +3,30 @@ use mlua::prelude::*;
|
|||
use mlua_codemp_patch as mlua;
|
||||
|
||||
use super::ext::a_sync::a_sync;
|
||||
use super::ext::from_lua_serde;
|
||||
|
||||
super::ext::impl_lua_serde! { CodempConfig CodempUser }
|
||||
|
||||
impl LuaUserData for CodempClient {
|
||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("id", |_, this| Ok(this.user().id.to_string()));
|
||||
fields.add_field_method_get("username", |_, this| Ok(this.user().name.clone()));
|
||||
fields.add_field_method_get("active_workspaces", |_, this| Ok(this.active_workspaces()));
|
||||
}
|
||||
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| {
|
||||
Ok(format!("{:?}", this))
|
||||
});
|
||||
|
||||
methods.add_method("current_user", |_, this, ()| {
|
||||
Ok(this.current_user().clone())
|
||||
});
|
||||
methods.add_method("active_workspaces", |_, this, ()| {
|
||||
Ok(this.active_workspaces())
|
||||
});
|
||||
|
||||
methods.add_method(
|
||||
"refresh",
|
||||
|_, this, ()| a_sync! { this => this.refresh().await? },
|
||||
);
|
||||
|
||||
methods.add_method(
|
||||
"join_workspace",
|
||||
|_, this, (ws,): (String,)| a_sync! { this => this.join_workspace(ws).await? },
|
||||
"attach_workspace",
|
||||
|_, this, (ws,): (String,)| a_sync! { this => this.attach_workspace(ws).await? },
|
||||
);
|
||||
|
||||
methods.add_method(
|
||||
|
@ -41,8 +43,14 @@ impl LuaUserData for CodempClient {
|
|||
a_sync! { this => this.invite_to_workspace(ws, user).await? }
|
||||
);
|
||||
|
||||
methods.add_method("list_workspaces", |_, this, (owned,invited):(Option<bool>,Option<bool>)|
|
||||
a_sync! { this => this.list_workspaces(owned.unwrap_or(true), invited.unwrap_or(true)).await? }
|
||||
methods.add_method(
|
||||
"fetch_owned_workspaces",
|
||||
|_, this, ()| a_sync! { this => this.fetch_owned_workspaces().await? },
|
||||
);
|
||||
|
||||
methods.add_method(
|
||||
"fetch_joined_workspaces",
|
||||
|_, this, ()| a_sync! { this => this.fetch_joined_workspaces().await? },
|
||||
);
|
||||
|
||||
methods.add_method("leave_workspace", |_, this, (ws,): (String,)| {
|
||||
|
@ -54,14 +62,3 @@ impl LuaUserData for CodempClient {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
from_lua_serde! { CodempConfig }
|
||||
impl LuaUserData for CodempConfig {
|
||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("username", |_, this| Ok(this.username.clone()));
|
||||
fields.add_field_method_get("password", |_, this| Ok(this.password.clone()));
|
||||
fields.add_field_method_get("host", |_, this| Ok(this.host.clone()));
|
||||
fields.add_field_method_get("port", |_, this| Ok(this.port));
|
||||
fields.add_field_method_get("tls", |_, this| Ok(this.tls));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@ use mlua::prelude::*;
|
|||
use mlua_codemp_patch as mlua;
|
||||
|
||||
use super::ext::a_sync::a_sync;
|
||||
use super::ext::from_lua_serde;
|
||||
|
||||
super::ext::impl_lua_serde! { CodempCursor CodempSelection }
|
||||
|
||||
impl LuaUserData for CodempCursorController {
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
|
@ -29,34 +30,3 @@ impl LuaUserData for CodempCursorController {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
from_lua_serde! { CodempCursor }
|
||||
impl LuaUserData for CodempCursor {
|
||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("user", |_, this| Ok(this.user.clone()));
|
||||
fields.add_field_method_get("sel", |_, this| Ok(this.sel.clone()));
|
||||
}
|
||||
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| {
|
||||
Ok(format!("{:?}", this))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
from_lua_serde! { CodempSelection }
|
||||
impl LuaUserData for CodempSelection {
|
||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("buffer", |_, this| Ok(this.buffer.clone()));
|
||||
fields.add_field_method_get("start_row", |_, this| Ok(this.start_row));
|
||||
fields.add_field_method_get("start_col", |_, this| Ok(this.start_col));
|
||||
fields.add_field_method_get("end_row", |_, this| Ok(this.end_row));
|
||||
fields.add_field_method_get("end_col", |_, this| Ok(this.end_col));
|
||||
}
|
||||
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| {
|
||||
Ok(format!("{:?}", this))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ macro_rules! callback_args {
|
|||
callback_args! {
|
||||
Str: String,
|
||||
VecStr: Vec<String>,
|
||||
VecUser: Vec<CodempUser>,
|
||||
Client: CodempClient,
|
||||
CursorController: CodempCursorController,
|
||||
BufferController: CodempBufferController,
|
||||
|
|
|
@ -5,7 +5,7 @@ pub mod log;
|
|||
pub(crate) use a_sync::tokio;
|
||||
pub(crate) use callback::callback;
|
||||
|
||||
macro_rules! from_lua_serde {
|
||||
macro_rules! impl_lua_serde {
|
||||
($($t:ty)*) => {
|
||||
$(
|
||||
impl FromLua for $t {
|
||||
|
@ -13,8 +13,14 @@ macro_rules! from_lua_serde {
|
|||
lua.from_value(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for $t {
|
||||
fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
|
||||
lua.to_value(&self)
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use from_lua_serde;
|
||||
pub(crate) use impl_lua_serde;
|
||||
|
|
|
@ -3,7 +3,8 @@ use mlua::prelude::*;
|
|||
use mlua_codemp_patch as mlua;
|
||||
|
||||
use super::ext::a_sync::a_sync;
|
||||
use super::ext::from_lua_serde;
|
||||
|
||||
super::ext::impl_lua_serde! { CodempEvent }
|
||||
|
||||
impl LuaUserData for CodempWorkspace {
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
|
@ -11,26 +12,26 @@ impl LuaUserData for CodempWorkspace {
|
|||
Ok(format!("{:?}", this))
|
||||
});
|
||||
methods.add_method(
|
||||
"create",
|
||||
|_, this, (name,): (String,)| a_sync! { this => this.create(&name).await? },
|
||||
"create_buffer",
|
||||
|_, this, (name,): (String,)| a_sync! { this => this.create_buffer(&name).await? },
|
||||
);
|
||||
|
||||
methods.add_method(
|
||||
"attach",
|
||||
|_, this, (name,): (String,)| a_sync! { this => this.attach(&name).await? },
|
||||
"attach_buffer",
|
||||
|_, this, (name,): (String,)| a_sync! { this => this.attach_buffer(&name).await? },
|
||||
);
|
||||
|
||||
methods.add_method("detach", |_, this, (name,): (String,)| {
|
||||
Ok(this.detach(&name))
|
||||
methods.add_method("detach_buffer", |_, this, (name,): (String,)| {
|
||||
Ok(this.detach_buffer(&name))
|
||||
});
|
||||
|
||||
methods.add_method(
|
||||
"delete",
|
||||
|_, this, (name,): (String,)| a_sync! { this => this.delete(&name).await? },
|
||||
"delete_buffer",
|
||||
|_, this, (name,): (String,)| a_sync! { this => this.delete_buffer(&name).await? },
|
||||
);
|
||||
|
||||
methods.add_method("get_buffer", |_, this, (name,): (String,)| {
|
||||
Ok(this.buffer_by_name(&name))
|
||||
Ok(this.get_buffer(&name))
|
||||
});
|
||||
|
||||
methods.add_method(
|
||||
|
@ -42,13 +43,19 @@ impl LuaUserData for CodempWorkspace {
|
|||
|_, this, ()| a_sync! { this => this.fetch_users().await? },
|
||||
);
|
||||
|
||||
methods.add_method(
|
||||
"filetree",
|
||||
|_, this, (filter, strict): (Option<String>, Option<bool>)| {
|
||||
Ok(this.filetree(filter.as_deref(), strict.unwrap_or(false)))
|
||||
},
|
||||
);
|
||||
methods.add_method("search_buffers", |_, this, (filter,): (Option<String>,)| {
|
||||
Ok(this.search_buffers(filter.as_deref()))
|
||||
});
|
||||
|
||||
methods.add_method("fetch_buffer_users", |_, this, (path,): (String,)| {
|
||||
a_sync! {
|
||||
this => this.fetch_buffer_users(&path).await?
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_method("id", |_, this, ()| Ok(this.id()));
|
||||
methods.add_method("cursor", |_, this, ()| Ok(this.cursor()));
|
||||
methods.add_method("active_buffers", |_, this, ()| Ok(this.active_buffers()));
|
||||
methods.add_method("user_list", |_, this, ()| Ok(this.user_list()));
|
||||
|
||||
methods.add_method("recv", |_, this, ()| a_sync! { this => this.recv().await? });
|
||||
|
@ -68,33 +75,4 @@ impl LuaUserData for CodempWorkspace {
|
|||
|
||||
methods.add_method("clear_callback", |_, this, ()| Ok(this.clear_callback()));
|
||||
}
|
||||
|
||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("name", |_, this| Ok(this.id()));
|
||||
fields.add_field_method_get("cursor", |_, this| Ok(this.cursor()));
|
||||
fields.add_field_method_get("active_buffers", |_, this| Ok(this.buffer_list()));
|
||||
// fields.add_field_method_get("users", |_, this| Ok(this.0.users())); // TODO
|
||||
}
|
||||
}
|
||||
|
||||
from_lua_serde! { CodempEvent }
|
||||
impl LuaUserData for CodempEvent {
|
||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| {
|
||||
Ok(format!("{:?}", this))
|
||||
});
|
||||
}
|
||||
|
||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("type", |_, this| match this {
|
||||
CodempEvent::FileTreeUpdated(_) => Ok("filetree"),
|
||||
CodempEvent::UserJoin(_) => Ok("join"),
|
||||
CodempEvent::UserLeave(_) => Ok("leave"),
|
||||
});
|
||||
fields.add_field_method_get("value", |_, this| match this {
|
||||
CodempEvent::FileTreeUpdated(x)
|
||||
| CodempEvent::UserJoin(x)
|
||||
| CodempEvent::UserLeave(x) => Ok(x.clone()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,26 +5,26 @@
|
|||
//! ```no_run
|
||||
//! # async {
|
||||
//! use codemp::api::controller::{AsyncReceiver, AsyncSender}; // needed for send/recv trait methods
|
||||
//!
|
||||
//!
|
||||
//! // connect first, api.code.mp is managed by hexed.technology
|
||||
//! let client = codemp::Client::connect(codemp::api::Config::new(
|
||||
//! "mail@example.net", "dont-use-this-password"
|
||||
//! )).await?;
|
||||
//!
|
||||
//!
|
||||
//! // create and join a workspace
|
||||
//! client.create_workspace("some-workspace").await?;
|
||||
//! let workspace = client.join_workspace("some-workspace").await?;
|
||||
//!
|
||||
//! let workspace = client.attach_workspace("some-workspace").await?;
|
||||
//!
|
||||
//! // create a new buffer in this workspace and attach to it
|
||||
//! workspace.create("/my/file.txt").await?;
|
||||
//! let buffer = workspace.attach("/my/file.txt").await?;
|
||||
//!
|
||||
//! workspace.create_buffer("/my/file.txt").await?;
|
||||
//! let buffer = workspace.attach_buffer("/my/file.txt").await?;
|
||||
//!
|
||||
//! // write `hello!` at the beginning of this buffer
|
||||
//! buffer.send(codemp::api::TextChange {
|
||||
//! start: 0, end: 0,
|
||||
//! start_idx: 0, end_idx: 0,
|
||||
//! content: "hello!".to_string(),
|
||||
//! })?;
|
||||
//!
|
||||
//!
|
||||
//! // wait for cursor movements
|
||||
//! loop {
|
||||
//! let event = workspace.cursor().recv().await?;
|
||||
|
@ -42,26 +42,26 @@
|
|||
//!
|
||||
//! ```js
|
||||
//! import * as codemp from 'codemp';
|
||||
//!
|
||||
//!
|
||||
//! // connect first, api.code.mp is managed by hexed.technology
|
||||
//! let client = await codemp.connect({
|
||||
//! username: "mail@example.net", password: "dont-use-this-password"
|
||||
//! });
|
||||
//!
|
||||
//!
|
||||
//! // create and join a workspace
|
||||
//! await client.create_workspace("some-workspace");
|
||||
//! let workspace = await client.join_workspace("some-workspace");
|
||||
//!
|
||||
//! await client.createWorkspace("some-workspace");
|
||||
//! let workspace = await client.attachWorkspace("some-workspace");
|
||||
//!
|
||||
//! // create a new buffer in this workspace and attach to it
|
||||
//! await workspace.create("/my/file.txt");
|
||||
//! let buffer = await workspace.attach("/my/file.txt");
|
||||
//!
|
||||
//! await workspace.createBuffer("/my/file.txt");
|
||||
//! let buffer = await workspace.attachBuffer("/my/file.txt");
|
||||
//!
|
||||
//! // write `hello!` at the beginning of this buffer
|
||||
//! await buffer.send({
|
||||
//! start: 0, end: 0,
|
||||
//! start_idx: 0, end_idx: 0,
|
||||
//! content: "hello!",
|
||||
//! });
|
||||
//!
|
||||
//!
|
||||
//! // wait for cursor movements
|
||||
//! while (true) {
|
||||
//! let event = await workspace.cursor().recv();
|
||||
|
@ -78,30 +78,31 @@
|
|||
//!
|
||||
//! ```py
|
||||
//! import codemp
|
||||
//!
|
||||
//!
|
||||
//! # connect first, api.code.mp is managed by hexed.technology
|
||||
//! config = codemp.get_default_config()
|
||||
//! config.username = "mail@example.net"
|
||||
//! config.password = "dont-use-this-password"
|
||||
//! client = codemp.connect(config).wait()
|
||||
//!
|
||||
//! client = codemp.connect(
|
||||
//! codemp.Config('mail@example.net', 'dont-use-this-password')
|
||||
//! ).wait()
|
||||
//!
|
||||
//! # create and join a workspace
|
||||
//! client.create_workspace("some-workspace").wait()
|
||||
//! workspace = client.join_workspace("some-workspace").wait()
|
||||
//!
|
||||
//! workspace = client.attach_workspace("some-workspace").wait()
|
||||
//!
|
||||
//! # create a new buffer in this workspace and attach to it
|
||||
//! workspace.create("/my/file.txt").wait()
|
||||
//! buffer = workspace.attach("/my/file.txt").wait()
|
||||
//!
|
||||
//! buffer = workspace.attach_buffer("/my/file.txt").wait()
|
||||
//!
|
||||
//! # write `hello!` at the beginning of this buffer
|
||||
//! buffer.send(
|
||||
//! 0, 0, "hello!"
|
||||
//! ).wait()
|
||||
//!
|
||||
//! buffer.send(codemp.TextChange(
|
||||
//! start_idx=0, end_idx=0,
|
||||
//! content="hello!"
|
||||
//! )).wait()
|
||||
//!
|
||||
//! # wait for cursor movements
|
||||
//! while true:
|
||||
//! event = workspace.cursor().recv().wait()
|
||||
//! print(f"user {event.user} moved on buffer {event.buffer}")
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
//! ## Lua
|
||||
|
@ -124,26 +125,26 @@
|
|||
//!
|
||||
//! ```lua
|
||||
//! CODEMP = require('codemp')
|
||||
//!
|
||||
//!
|
||||
//! -- connect first, api.code.mp is managed by hexed.technology
|
||||
//! local client = CODEMP.connect({
|
||||
//! username = "mail@example.net", password = "dont-use-this-password"
|
||||
//! }):await()
|
||||
//!
|
||||
//!
|
||||
//! -- create and join a workspace
|
||||
//! client:create_workspace("my-workspace"):await()
|
||||
//! local workspace = client:join_workspace("my-workspace"):await()
|
||||
//!
|
||||
//! local workspace = client:attach_workspace("my-workspace"):await()
|
||||
//!
|
||||
//! -- create a new buffer in this workspace and attach to it
|
||||
//! workspace:create_buffer("/my/file.txt"):await()
|
||||
//! local buffer = workspace:attach_buffer("/my/file.txt"):await()
|
||||
//!
|
||||
//!
|
||||
//! -- write `hello!` at the beginning of this buffer
|
||||
//! buffer:send({
|
||||
//! start = 0, finish = 0,
|
||||
//! start_idx = 0, end_idx = 0,
|
||||
//! content = "hello!"
|
||||
//! }):await()
|
||||
//!
|
||||
//!
|
||||
//! -- wait for cursor movements
|
||||
//! while true do
|
||||
//! local event = workspace.cursor:recv():await()
|
||||
|
@ -162,29 +163,29 @@
|
|||
//!
|
||||
//! ```java
|
||||
//! import mp.code.*;
|
||||
//!
|
||||
//!
|
||||
//! // connect first, api.code.mp is managed by hexed.technology
|
||||
//! Client client = Client.connect(
|
||||
//! new data.Config("mail@example.net", "dont-use-this-password")
|
||||
//! );
|
||||
//!
|
||||
//!
|
||||
//! // create and join a workspace
|
||||
//! client.createWorkspace("some-workspace");
|
||||
//! Workspace workspace = client.joinWorkspace("some-workspace");
|
||||
//!
|
||||
//! Workspace workspace = client.attachWorkspace("some-workspace");
|
||||
//!
|
||||
//! // create a new buffer in this workspace and attach to it
|
||||
//! workspace.createBuffer("/my/file.txt");
|
||||
//! BufferController buffer = workspace.attachToBuffer("/my/file.txt");
|
||||
//!
|
||||
//! BufferController buffer = workspace.attachBuffer("/my/file.txt");
|
||||
//!
|
||||
//! // write `hello!` at the beginning of this buffer
|
||||
//! buffer.send(new data.TextChange(
|
||||
//! 0, 0, "hello!",
|
||||
//! java.util.OptionalLong.empty() // optional, used for error detection
|
||||
//! ));
|
||||
//!
|
||||
//!
|
||||
//! // wait for cursor movements
|
||||
//! while (true) {
|
||||
//! data.Cursor event = workspace.getCursor().recv();
|
||||
//! data.Cursor event = workspace.cursor().recv();
|
||||
//! System.out.printf("user %s moved on buffer %s\n", event.user, event.buffer);
|
||||
//! }
|
||||
//! ```
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::a_sync_allow_threads;
|
||||
use super::Client;
|
||||
use crate::api::User;
|
||||
use crate::workspace::Workspace;
|
||||
use pyo3::prelude::*;
|
||||
|
||||
|
@ -14,11 +15,11 @@ impl Client {
|
|||
// super::tokio().block_on(Client::connect(host, username, password))
|
||||
// }
|
||||
|
||||
#[pyo3(name = "join_workspace")]
|
||||
fn pyjoin_workspace(&self, py: Python<'_>, workspace: String) -> PyResult<super::Promise> {
|
||||
#[pyo3(name = "attach_workspace")]
|
||||
fn pyattach_workspace(&self, py: Python<'_>, workspace: String) -> PyResult<super::Promise> {
|
||||
tracing::info!("attempting to join the workspace {}", workspace);
|
||||
let this = self.clone();
|
||||
a_sync_allow_threads!(py, this.join_workspace(workspace).await)
|
||||
a_sync_allow_threads!(py, this.attach_workspace(workspace).await)
|
||||
// let this = self.clone();
|
||||
// Ok(super::Promise(Some(tokio().spawn(async move {
|
||||
// Ok(this
|
||||
|
@ -54,16 +55,18 @@ impl Client {
|
|||
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");
|
||||
#[pyo3(name = "fetch_owned_workspaces")]
|
||||
fn pyfetch_owned_workspaces(&self, py: Python<'_>) -> PyResult<super::Promise> {
|
||||
tracing::info!("attempting to fetch owned workspaces");
|
||||
let this = self.clone();
|
||||
a_sync_allow_threads!(py, this.list_workspaces(owned, invited).await)
|
||||
a_sync_allow_threads!(py, this.fetch_owned_workspaces().await)
|
||||
}
|
||||
|
||||
#[pyo3(name = "fetch_joined_workspaces")]
|
||||
fn pyfetch_joined_workspaces(&self, py: Python<'_>) -> PyResult<super::Promise> {
|
||||
tracing::info!("attempting to fetch joined workspaces");
|
||||
let this = self.clone();
|
||||
a_sync_allow_threads!(py, this.fetch_joined_workspaces().await)
|
||||
}
|
||||
|
||||
#[pyo3(name = "leave_workspace")]
|
||||
|
@ -82,14 +85,9 @@ impl Client {
|
|||
self.active_workspaces()
|
||||
}
|
||||
|
||||
#[pyo3(name = "user_id")]
|
||||
fn pyuser_id(&self) -> String {
|
||||
self.user().id.to_string()
|
||||
}
|
||||
|
||||
#[pyo3(name = "user_name")]
|
||||
fn pyuser_name(&self) -> String {
|
||||
self.user().name.clone()
|
||||
#[pyo3(name = "current_user")]
|
||||
fn pycurrent_user(&self) -> User {
|
||||
self.current_user().clone()
|
||||
}
|
||||
|
||||
#[pyo3(name = "refresh")]
|
||||
|
|
|
@ -13,22 +13,8 @@ use super::Promise;
|
|||
#[pymethods]
|
||||
impl CursorController {
|
||||
#[pyo3(name = "send")]
|
||||
fn pysend(
|
||||
&self,
|
||||
_py: Python,
|
||||
path: String,
|
||||
start: (i32, i32),
|
||||
end: (i32, i32),
|
||||
) -> PyResult<()> {
|
||||
let pos = Selection {
|
||||
start_row: start.0,
|
||||
start_col: start.1,
|
||||
end_row: end.0,
|
||||
end_col: end.1,
|
||||
buffer: path,
|
||||
};
|
||||
let this = self.clone();
|
||||
this.send(pos)?;
|
||||
fn pysend(&self, _py: Python, pos: Selection) -> PyResult<()> {
|
||||
self.send(pos)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -86,12 +72,7 @@ impl BufferController {
|
|||
}
|
||||
|
||||
#[pyo3(name = "send")]
|
||||
fn pysend(&self, _py: Python, start: u32, end: u32, txt: String) -> PyResult<()> {
|
||||
let op = TextChange {
|
||||
start,
|
||||
end,
|
||||
content: txt,
|
||||
};
|
||||
fn pysend(&self, _py: Python, op: TextChange) -> PyResult<()> {
|
||||
let this = self.clone();
|
||||
this.send(op)?;
|
||||
Ok(())
|
||||
|
|
|
@ -3,15 +3,15 @@ pub mod controllers;
|
|||
pub mod workspace;
|
||||
|
||||
use crate::{
|
||||
api::{Config, Cursor, TextChange},
|
||||
api::{BufferUpdate, Config, Cursor, Selection, TextChange, User},
|
||||
buffer::Controller as BufferController,
|
||||
cursor::Controller as CursorController,
|
||||
Client, Workspace,
|
||||
};
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::{
|
||||
exceptions::{PyConnectionError, PyRuntimeError, PySystemError},
|
||||
prelude::*,
|
||||
types::PyDict,
|
||||
};
|
||||
|
||||
|
@ -153,13 +153,37 @@ fn init() -> PyResult<Driver> {
|
|||
Ok(Driver(Some(rt_stop_tx)))
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_default_config() -> crate::api::Config {
|
||||
let mut conf = crate::api::Config::new("".to_string(), "".to_string());
|
||||
conf.host = Some(conf.host().to_string());
|
||||
conf.port = Some(conf.port());
|
||||
conf.tls = Some(false);
|
||||
conf
|
||||
#[pymethods]
|
||||
impl User {
|
||||
#[getter]
|
||||
fn get_id(&self) -> pyo3::PyResult<String> {
|
||||
Ok(self.id.to_string())
|
||||
}
|
||||
|
||||
#[setter]
|
||||
fn set_id(&mut self, value: String) -> pyo3::PyResult<()> {
|
||||
self.id = value
|
||||
.parse()
|
||||
.map_err(|x: <uuid::Uuid as std::str::FromStr>::Err| {
|
||||
pyo3::exceptions::PyRuntimeError::new_err(x.to_string())
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[getter]
|
||||
fn get_name(&self) -> pyo3::PyResult<String> {
|
||||
Ok(self.name.clone())
|
||||
}
|
||||
|
||||
#[setter]
|
||||
fn set_name(&mut self, value: String) -> pyo3::PyResult<()> {
|
||||
self.name = value;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn __str__(&self) -> String {
|
||||
format!("{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
|
@ -176,7 +200,7 @@ impl Config {
|
|||
let port = kwgs.get_item("port")?.and_then(|e| e.extract().ok());
|
||||
let tls = kwgs.get_item("tls")?.and_then(|e| e.extract().ok());
|
||||
|
||||
Ok(Config {
|
||||
Ok(Self {
|
||||
username,
|
||||
password,
|
||||
host,
|
||||
|
@ -184,9 +208,119 @@ impl Config {
|
|||
tls,
|
||||
})
|
||||
} else {
|
||||
Ok(Config::new(username, password))
|
||||
Ok(Self::new(username, password))
|
||||
}
|
||||
}
|
||||
|
||||
fn __str__(&self) -> String {
|
||||
format!("{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl Cursor {
|
||||
fn __str__(&self) -> String {
|
||||
format!("{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl Selection {
|
||||
#[new]
|
||||
#[pyo3(signature = (**kwds))]
|
||||
pub fn py_new(kwds: Option<&Bound<'_, PyDict>>) -> PyResult<Self> {
|
||||
if let Some(kwds) = kwds {
|
||||
let start_row = if let Some(e) = kwds.get_item("start_row")? {
|
||||
e.extract()?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let start_col = if let Some(e) = kwds.get_item("start_col")? {
|
||||
e.extract()?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let end_row = if let Some(e) = kwds.get_item("end_row")? {
|
||||
e.extract()?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let end_col = if let Some(e) = kwds.get_item("end_col")? {
|
||||
e.extract()?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let buffer = if let Some(e) = kwds.get_item("buffer")? {
|
||||
e.extract()?
|
||||
} else {
|
||||
String::default()
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
start_row,
|
||||
start_col,
|
||||
end_row,
|
||||
end_col,
|
||||
buffer,
|
||||
})
|
||||
} else {
|
||||
Ok(Self::default())
|
||||
}
|
||||
}
|
||||
|
||||
fn __str__(&self) -> String {
|
||||
format!("{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl BufferUpdate {
|
||||
fn __str__(&self) -> String {
|
||||
format!("{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl TextChange {
|
||||
#[new]
|
||||
#[pyo3(signature = (**kwds))]
|
||||
pub fn py_new(kwds: Option<&Bound<'_, PyDict>>) -> PyResult<Self> {
|
||||
if let Some(kwds) = kwds {
|
||||
let start_idx = if let Some(e) = kwds.get_item("start")? {
|
||||
e.extract()?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let end_idx = if let Some(e) = kwds.get_item("end")? {
|
||||
e.extract()?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let content = if let Some(e) = kwds.get_item("content")? {
|
||||
e.extract()?
|
||||
} else {
|
||||
String::default()
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
start_idx,
|
||||
end_idx,
|
||||
content,
|
||||
})
|
||||
} else {
|
||||
Ok(Self::default())
|
||||
}
|
||||
}
|
||||
|
||||
fn __str__(&self) -> String {
|
||||
format!("{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
@ -254,27 +388,24 @@ impl From<crate::errors::ControllerError> for PyErr {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPy<PyObject> for crate::api::User {
|
||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||
self.id.to_string().into_py(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
fn codemp(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
m.add_function(wrap_pyfunction!(version, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(init, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(get_default_config, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(connect, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(set_logger, m)?)?;
|
||||
m.add_class::<Driver>()?;
|
||||
|
||||
m.add_class::<BufferUpdate>()?;
|
||||
m.add_class::<TextChange>()?;
|
||||
m.add_class::<BufferController>()?;
|
||||
|
||||
m.add_class::<Cursor>()?;
|
||||
m.add_class::<Selection>()?;
|
||||
m.add_class::<CursorController>()?;
|
||||
|
||||
m.add_class::<User>()?;
|
||||
|
||||
m.add_class::<Workspace>()?;
|
||||
m.add_class::<Client>()?;
|
||||
m.add_class::<Config>()?;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::api::controller::AsyncReceiver;
|
||||
use crate::api::User;
|
||||
use crate::buffer::Controller as BufferController;
|
||||
use crate::cursor::Controller as CursorController;
|
||||
use crate::workspace::Workspace;
|
||||
|
@ -11,21 +12,21 @@ use super::Promise;
|
|||
#[pymethods]
|
||||
impl Workspace {
|
||||
// join a workspace
|
||||
#[pyo3(name = "create")]
|
||||
fn pycreate(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||
#[pyo3(name = "create_buffer")]
|
||||
fn pycreate_buffer(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||
let this = self.clone();
|
||||
a_sync_allow_threads!(py, this.create(path.as_str()).await)
|
||||
a_sync_allow_threads!(py, this.create_buffer(path.as_str()).await)
|
||||
}
|
||||
|
||||
#[pyo3(name = "attach")]
|
||||
fn pyattach(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||
#[pyo3(name = "attach_buffer")]
|
||||
fn pyattach_buffer(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||
let this = self.clone();
|
||||
a_sync_allow_threads!(py, this.attach(path.as_str()).await)
|
||||
a_sync_allow_threads!(py, this.attach_buffer(path.as_str()).await)
|
||||
}
|
||||
|
||||
#[pyo3(name = "detach")]
|
||||
fn pydetach(&self, path: String) -> bool {
|
||||
self.detach(path.as_str())
|
||||
#[pyo3(name = "detach_buffer")]
|
||||
fn pydetach_buffer(&self, path: String) -> bool {
|
||||
self.detach_buffer(path.as_str())
|
||||
}
|
||||
|
||||
#[pyo3(name = "fetch_buffers")]
|
||||
|
@ -40,17 +41,17 @@ impl Workspace {
|
|||
a_sync_allow_threads!(py, this.fetch_users().await)
|
||||
}
|
||||
|
||||
#[pyo3(name = "list_buffer_users")]
|
||||
fn pylist_buffer_users(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||
#[pyo3(name = "fetch_buffer_users")]
|
||||
fn pyfetch_buffer_users(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||
// crate::Result<Vec<crate::api::User>>
|
||||
let this = self.clone();
|
||||
a_sync_allow_threads!(py, this.list_buffer_users(path.as_str()).await)
|
||||
a_sync_allow_threads!(py, this.fetch_buffer_users(path.as_str()).await)
|
||||
}
|
||||
|
||||
#[pyo3(name = "delete")]
|
||||
fn pydelete(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||
#[pyo3(name = "delete_buffer")]
|
||||
fn pydelete_buffer(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||
let this = self.clone();
|
||||
a_sync_allow_threads!(py, this.delete(path.as_str()).await)
|
||||
a_sync_allow_threads!(py, this.delete_buffer(path.as_str()).await)
|
||||
}
|
||||
|
||||
#[pyo3(name = "id")]
|
||||
|
@ -63,24 +64,24 @@ impl Workspace {
|
|||
self.cursor()
|
||||
}
|
||||
|
||||
#[pyo3(name = "buffer_by_name")]
|
||||
fn pybuffer_by_name(&self, path: String) -> Option<BufferController> {
|
||||
self.buffer_by_name(path.as_str())
|
||||
#[pyo3(name = "get_buffer")]
|
||||
fn pyget_buffer(&self, path: String) -> Option<BufferController> {
|
||||
self.get_buffer(path.as_str())
|
||||
}
|
||||
|
||||
#[pyo3(name = "buffer_list")]
|
||||
fn pybuffer_list(&self) -> Vec<String> {
|
||||
self.buffer_list()
|
||||
#[pyo3(name = "active_buffers")]
|
||||
fn pyactive_buffers(&self) -> Vec<String> {
|
||||
self.active_buffers()
|
||||
}
|
||||
|
||||
#[pyo3(name = "filetree")]
|
||||
#[pyo3(signature = (filter=None, strict=false))]
|
||||
fn pyfiletree(&self, filter: Option<&str>, strict: bool) -> Vec<String> {
|
||||
self.filetree(filter, strict)
|
||||
#[pyo3(name = "search_buffers")]
|
||||
#[pyo3(signature = (filter=None))]
|
||||
fn pysearch_buffers(&self, filter: Option<&str>) -> Vec<String> {
|
||||
self.search_buffers(filter)
|
||||
}
|
||||
|
||||
#[pyo3(name = "user_list")]
|
||||
fn pyuser_list(&self) -> Vec<String> {
|
||||
fn pyuser_list(&self) -> Vec<User> {
|
||||
self.user_list()
|
||||
}
|
||||
|
||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -32,13 +32,13 @@
|
|||
//! ```
|
||||
//!
|
||||
//! A [`Client`] can acquire a [`Workspace`] handle by joining an existing one it can access with
|
||||
//! [`Client::join_workspace`] or create a new one with [`Client::create_workspace`].
|
||||
//! [`Client::attach_workspace`] or create a new one with [`Client::create_workspace`].
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # async {
|
||||
//! # let client = codemp::Client::connect(codemp::api::Config::new("", "")).await.unwrap();
|
||||
//! client.create_workspace("my-workspace").await.expect("failed to create workspace!");
|
||||
//! let workspace = client.join_workspace("my-workspace").await.expect("failed to attach!");
|
||||
//! let workspace = client.attach_workspace("my-workspace").await.expect("failed to attach!");
|
||||
//! # };
|
||||
//! ```
|
||||
//!
|
||||
|
@ -49,7 +49,7 @@
|
|||
//! # async {
|
||||
//! # let client = codemp::Client::connect(codemp::api::Config::new("", "")).await.unwrap();
|
||||
//! # client.create_workspace("").await.unwrap();
|
||||
//! # let workspace = client.join_workspace("").await.unwrap();
|
||||
//! # let workspace = client.attach_workspace("").await.unwrap();
|
||||
//! use codemp::api::controller::{AsyncSender, AsyncReceiver}; // needed to access trait methods
|
||||
//! let cursor = workspace.cursor();
|
||||
//! let event = cursor.recv().await.expect("disconnected while waiting for event!");
|
||||
|
@ -65,14 +65,14 @@
|
|||
//! # async {
|
||||
//! # let client = codemp::Client::connect(codemp::api::Config::new("", "")).await.unwrap();
|
||||
//! # client.create_workspace("").await.unwrap();
|
||||
//! # let workspace = client.join_workspace("").await.unwrap();
|
||||
//! # let workspace = client.attach_workspace("").await.unwrap();
|
||||
//! # use codemp::api::controller::{AsyncSender, AsyncReceiver};
|
||||
//! let buffer = workspace.attach("/some/file.txt").await.expect("failed to attach");
|
||||
//! let buffer = workspace.attach_buffer("/some/file.txt").await.expect("failed to attach");
|
||||
//! buffer.content(); // force-sync
|
||||
//! if let Some(mut update) = buffer.try_recv().await.unwrap() {
|
||||
//! println!(
|
||||
//! "content: {}, span: {}-{}",
|
||||
//! update.change.content, update.change.start, update.change.end
|
||||
//! update.change.content, update.change.start_idx, update.change.end_idx
|
||||
//! );
|
||||
//! buffer.ack(update.version);
|
||||
//! } // if None, no changes are currently available
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//! All-in-one renamed imports with `use codemp::prelude::*`.
|
||||
|
||||
pub use crate::api::{
|
||||
controller::AsyncReceiver as CodempAsyncReceiver, controller::AsyncSender as CodempAsyncSender,
|
||||
AsyncReceiver as CodempAsyncReceiver, AsyncSender as CodempAsyncSender,
|
||||
BufferUpdate as CodempBufferUpdate, Config as CodempConfig, Controller as CodempController,
|
||||
Cursor as CodempCursor, Event as CodempEvent, Selection as CodempSelection,
|
||||
TextChange as CodempTextChange, User as CodempUser,
|
||||
|
|
|
@ -26,7 +26,7 @@ use codemp_proto::{
|
|||
};
|
||||
|
||||
use dashmap::{DashMap, DashSet};
|
||||
use std::{collections::BTreeSet, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, mpsc::error::TryRecvError};
|
||||
use tonic::Streaming;
|
||||
use uuid::Uuid;
|
||||
|
@ -140,7 +140,7 @@ impl Workspace {
|
|||
}
|
||||
|
||||
/// Create a new buffer in the current workspace.
|
||||
pub async fn create(&self, path: &str) -> RemoteResult<()> {
|
||||
pub async fn create_buffer(&self, path: &str) -> RemoteResult<()> {
|
||||
let mut workspace_client = self.0.services.ws();
|
||||
workspace_client
|
||||
.create_buffer(tonic::Request::new(BufferNode {
|
||||
|
@ -158,7 +158,7 @@ impl Workspace {
|
|||
}
|
||||
|
||||
/// Attach to a buffer and return a handle to it.
|
||||
pub async fn attach(&self, path: &str) -> ConnectionResult<buffer::Controller> {
|
||||
pub async fn attach_buffer(&self, path: &str) -> ConnectionResult<buffer::Controller> {
|
||||
let mut worskspace_client = self.0.services.ws();
|
||||
let request = tonic::Request::new(BufferNode {
|
||||
path: path.to_string(),
|
||||
|
@ -190,7 +190,7 @@ impl Workspace {
|
|||
/// If this method returns `false` you have a dangling ref, maybe just waiting for garbage
|
||||
/// collection or maybe preventing the controller from being dropped completely
|
||||
#[allow(clippy::redundant_pattern_matching)] // all cases are clearer this way
|
||||
pub fn detach(&self, path: &str) -> bool {
|
||||
pub fn detach_buffer(&self, path: &str) -> bool {
|
||||
match self.0.buffers.remove(path) {
|
||||
None => true, // noop: we werent attached in the first place
|
||||
Some((_name, controller)) => match Arc::into_inner(controller.0) {
|
||||
|
@ -201,45 +201,48 @@ impl Workspace {
|
|||
}
|
||||
|
||||
/// Re-fetch the list of available buffers in the workspace.
|
||||
pub async fn fetch_buffers(&self) -> RemoteResult<()> {
|
||||
pub async fn fetch_buffers(&self) -> RemoteResult<Vec<String>> {
|
||||
let mut workspace_client = self.0.services.ws();
|
||||
let buffers = workspace_client
|
||||
let resp = workspace_client
|
||||
.list_buffers(tonic::Request::new(Empty {}))
|
||||
.await?
|
||||
.into_inner()
|
||||
.buffers;
|
||||
.into_inner();
|
||||
|
||||
let mut out = Vec::new();
|
||||
|
||||
self.0.filetree.clear();
|
||||
for b in buffers {
|
||||
self.0.filetree.insert(b.path);
|
||||
for b in resp.buffers {
|
||||
self.0.filetree.insert(b.path.clone());
|
||||
out.push(b.path);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Re-fetch the list of all users in the workspace.
|
||||
pub async fn fetch_users(&self) -> RemoteResult<()> {
|
||||
pub async fn fetch_users(&self) -> RemoteResult<Vec<User>> {
|
||||
let mut workspace_client = self.0.services.ws();
|
||||
let users = BTreeSet::from_iter(
|
||||
workspace_client
|
||||
.list_users(tonic::Request::new(Empty {}))
|
||||
.await?
|
||||
.into_inner()
|
||||
.users
|
||||
.into_iter()
|
||||
.map(User::from),
|
||||
);
|
||||
let users = workspace_client
|
||||
.list_users(tonic::Request::new(Empty {}))
|
||||
.await?
|
||||
.into_inner()
|
||||
.users
|
||||
.into_iter()
|
||||
.map(User::from);
|
||||
|
||||
let mut result = Vec::new();
|
||||
|
||||
self.0.users.clear();
|
||||
for u in users {
|
||||
self.0.users.insert(u.id, u);
|
||||
self.0.users.insert(u.id, u.clone());
|
||||
result.push(u);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Get a list of the [User]s attached to a specific buffer.
|
||||
pub async fn list_buffer_users(&self, path: &str) -> RemoteResult<Vec<User>> {
|
||||
/// Fetch a list of the [User]s attached to a specific buffer.
|
||||
pub async fn fetch_buffer_users(&self, path: &str) -> RemoteResult<Vec<User>> {
|
||||
let mut workspace_client = self.0.services.ws();
|
||||
let buffer_users = workspace_client
|
||||
.list_buffer_users(tonic::Request::new(BufferNode {
|
||||
|
@ -256,8 +259,8 @@ impl Workspace {
|
|||
}
|
||||
|
||||
/// Delete a buffer.
|
||||
pub async fn delete(&self, path: &str) -> RemoteResult<()> {
|
||||
self.detach(path); // just in case
|
||||
pub async fn delete_buffer(&self, path: &str) -> RemoteResult<()> {
|
||||
self.detach_buffer(path); // just in case
|
||||
|
||||
let mut workspace_client = self.0.services.ws();
|
||||
workspace_client
|
||||
|
@ -285,13 +288,13 @@ impl Workspace {
|
|||
|
||||
/// Return a handle to the [buffer::Controller] with the given path, if present.
|
||||
// #[cfg_attr(feature = "js", napi)] // https://github.com/napi-rs/napi-rs/issues/1120
|
||||
pub fn buffer_by_name(&self, path: &str) -> Option<buffer::Controller> {
|
||||
pub fn get_buffer(&self, path: &str) -> Option<buffer::Controller> {
|
||||
self.0.buffers.get(path).map(|x| x.clone())
|
||||
}
|
||||
|
||||
/// Get a list of all the currently attached buffers.
|
||||
// #[cfg_attr(feature = "js", napi)] // https://github.com/napi-rs/napi-rs/issues/1120
|
||||
pub fn buffer_list(&self) -> Vec<String> {
|
||||
pub fn active_buffers(&self) -> Vec<String> {
|
||||
self.0
|
||||
.buffers
|
||||
.iter()
|
||||
|
@ -300,31 +303,23 @@ impl Workspace {
|
|||
}
|
||||
|
||||
/// Get all names of users currently in this workspace
|
||||
pub fn user_list(&self) -> Vec<String> {
|
||||
pub fn user_list(&self) -> Vec<User> {
|
||||
self.0
|
||||
.users
|
||||
.iter()
|
||||
.map(|elem| elem.value().name.clone())
|
||||
.map(|elem| elem.value().clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Get the filetree as it is currently cached.
|
||||
/// A filter may be applied, and it may be strict (equality check) or not (starts_with check).
|
||||
// #[cfg_attr(feature = "js", napi)] // https://github.com/napi-rs/napi-rs/issues/1120
|
||||
pub fn filetree(&self, filter: Option<&str>, strict: bool) -> Vec<String> {
|
||||
pub fn search_buffers(&self, filter: Option<&str>) -> Vec<String> {
|
||||
let mut tree = self
|
||||
.0
|
||||
.filetree
|
||||
.iter()
|
||||
.filter(|f| {
|
||||
filter.map_or(true, |flt| {
|
||||
if strict {
|
||||
f.as_str() == flt
|
||||
} else {
|
||||
f.starts_with(flt)
|
||||
}
|
||||
})
|
||||
})
|
||||
.filter(|f| filter.map_or(true, |flt| f.starts_with(flt)))
|
||||
.map(|f| f.clone())
|
||||
.collect::<Vec<String>>();
|
||||
tree.sort();
|
||||
|
|
Loading…
Reference in a new issue