mirror of
https://github.com/hexedtech/codemp-proto.git
synced 2024-11-21 23:14:52 +01:00
First commit of codemp-proto in new repo
This commit is contained in:
commit
5ecd52d237
10 changed files with 249 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "codemp-proto"
|
||||||
|
version = "0.6.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "codemp_proto"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
prost = "0.12.3"
|
||||||
|
tonic = "0.11.0"
|
||||||
|
uuid = "1.7.0"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tonic-build = "0.11.0"
|
15
build.rs
Normal file
15
build.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
tonic_build::configure()
|
||||||
|
.compile(
|
||||||
|
&[
|
||||||
|
"proto/common.proto",
|
||||||
|
"proto/cursor.proto",
|
||||||
|
"proto/files.proto",
|
||||||
|
"proto/auth.proto",
|
||||||
|
"proto/workspace.proto",
|
||||||
|
"proto/buffer.proto",
|
||||||
|
],
|
||||||
|
&["proto"],
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
20
proto/auth.proto
Normal file
20
proto/auth.proto
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
package auth;
|
||||||
|
|
||||||
|
// authenticates users, issuing tokens
|
||||||
|
service Auth {
|
||||||
|
// send credentials and join a workspace, returns ready to use token
|
||||||
|
rpc Login (WorkspaceJoinRequest) returns (Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Token {
|
||||||
|
required string token = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO one-request-to-do-it-all from login to workspace access
|
||||||
|
message WorkspaceJoinRequest {
|
||||||
|
required string username = 1;
|
||||||
|
required string password = 2;
|
||||||
|
optional string workspace_id = 3;
|
||||||
|
}
|
20
proto/buffer.proto
Normal file
20
proto/buffer.proto
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
import "common.proto";
|
||||||
|
|
||||||
|
package buffer;
|
||||||
|
|
||||||
|
// handle buffer changes, keep in sync users
|
||||||
|
service Buffer {
|
||||||
|
// attach to a buffer and receive operations
|
||||||
|
rpc Attach (stream Operation) returns (stream BufferEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Operation {
|
||||||
|
required bytes data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BufferEvent {
|
||||||
|
required Operation op = 1;
|
||||||
|
required common.Identity user = 2;
|
||||||
|
}
|
18
proto/common.proto
Normal file
18
proto/common.proto
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
package common;
|
||||||
|
|
||||||
|
|
||||||
|
// a wrapper payload representing an uuid
|
||||||
|
message Identity {
|
||||||
|
// uuid bytes, as string
|
||||||
|
required string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a collection of identities
|
||||||
|
message IdentityList {
|
||||||
|
repeated Identity users = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//generic Empty message
|
||||||
|
message Empty { }
|
36
proto/cursor.proto
Normal file
36
proto/cursor.proto
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
package cursor;
|
||||||
|
import "common.proto";
|
||||||
|
import "files.proto";
|
||||||
|
|
||||||
|
// handle cursor events and broadcast to all users
|
||||||
|
service Cursor {
|
||||||
|
// subscribe to a workspace's cursor events
|
||||||
|
rpc Attach (stream cursor.CursorPosition) returns (stream cursor.CursorEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// a tuple indicating row and column
|
||||||
|
message RowCol {
|
||||||
|
required int32 row = 1;
|
||||||
|
required int32 col = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cursor position object
|
||||||
|
message CursorPosition {
|
||||||
|
// path of current buffer this cursor is into
|
||||||
|
required files.BufferNode buffer = 1;
|
||||||
|
// cursor start position
|
||||||
|
required RowCol start = 2;
|
||||||
|
// cursor end position
|
||||||
|
required RowCol end = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cursor event, with user id and cursor position
|
||||||
|
message CursorEvent {
|
||||||
|
// user moving the cursor
|
||||||
|
required common.Identity user = 1;
|
||||||
|
// new cursor position
|
||||||
|
required CursorPosition position = 2;
|
||||||
|
}
|
11
proto/files.proto
Normal file
11
proto/files.proto
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
package files;
|
||||||
|
|
||||||
|
message BufferNode {
|
||||||
|
required string path = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BufferTree {
|
||||||
|
repeated BufferNode buffers = 1;
|
||||||
|
}
|
54
proto/workspace.proto
Normal file
54
proto/workspace.proto
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
package workspace;
|
||||||
|
|
||||||
|
import "common.proto";
|
||||||
|
import "files.proto";
|
||||||
|
import "auth.proto";
|
||||||
|
|
||||||
|
service Workspace {
|
||||||
|
rpc Attach (common.Empty) returns (stream WorkspaceEvent);
|
||||||
|
|
||||||
|
rpc CreateBuffer (files.BufferNode) returns (common.Empty);
|
||||||
|
rpc AccessBuffer (files.BufferNode) returns (BufferCredentials);
|
||||||
|
rpc DeleteBuffer (files.BufferNode) returns (common.Empty);
|
||||||
|
|
||||||
|
rpc ListBuffers (common.Empty) returns (files.BufferTree);
|
||||||
|
rpc ListUsers (common.Empty) returns (common.IdentityList);
|
||||||
|
rpc ListBufferUsers (files.BufferNode) returns (common.IdentityList);
|
||||||
|
}
|
||||||
|
|
||||||
|
message WorkspaceEvent {
|
||||||
|
message UserJoin {
|
||||||
|
required common.Identity user = 1;
|
||||||
|
}
|
||||||
|
message UserLeave {
|
||||||
|
required common.Identity user = 1;
|
||||||
|
}
|
||||||
|
message FileCreate {
|
||||||
|
required string path = 1;
|
||||||
|
}
|
||||||
|
message FileRename {
|
||||||
|
required string before = 1;
|
||||||
|
required string after = 2;
|
||||||
|
}
|
||||||
|
message FileDelete {
|
||||||
|
required string path = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
oneof event {
|
||||||
|
UserJoin join = 1;
|
||||||
|
UserLeave leave = 2;
|
||||||
|
FileCreate create = 3;
|
||||||
|
FileRename rename = 4;
|
||||||
|
FileDelete delete = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this is very ugly because we can't just return a new token (which is already smelly but whatev), we also need to tell the underlying id so that
|
||||||
|
// the client can put it as metadata while attaching, because it can't really know the underlying id that the server is using for each buffer without
|
||||||
|
// parsing the token itself. meehhhhhh, this bleeds underlying implementation to the upper levels, how can we avoid this??
|
||||||
|
message BufferCredentials {
|
||||||
|
required common.Identity id = 1;
|
||||||
|
required auth.Token token = 2;
|
||||||
|
}
|
58
src/lib.rs
Normal file
58
src/lib.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub mod proto {
|
||||||
|
pub mod common {
|
||||||
|
tonic::include_proto!("common");
|
||||||
|
|
||||||
|
impl From<uuid::Uuid> for Identity {
|
||||||
|
fn from(id: uuid::Uuid) -> Self {
|
||||||
|
Identity { id: id.to_string() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&uuid::Uuid> for Identity {
|
||||||
|
fn from(id: &uuid::Uuid) -> Self {
|
||||||
|
Identity { id: id.to_string() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Identity> for uuid::Uuid {
|
||||||
|
fn from(value: Identity) -> Self {
|
||||||
|
uuid::Uuid::parse_str(&value.id).expect("invalid uuid in identity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Identity> for uuid::Uuid {
|
||||||
|
fn from(value: &Identity) -> Self {
|
||||||
|
uuid::Uuid::parse_str(&value.id).expect("invalid uuid in identity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub mod files {
|
||||||
|
tonic::include_proto!("files");
|
||||||
|
|
||||||
|
impl From<String> for BufferNode {
|
||||||
|
fn from(value: String) -> Self {
|
||||||
|
BufferNode { path: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for BufferNode {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
BufferNode { path: value.to_string() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<BufferNode> for String {
|
||||||
|
fn from(value: BufferNode) -> Self {
|
||||||
|
value.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod buffer { tonic::include_proto!("buffer"); }
|
||||||
|
pub mod cursor { tonic::include_proto!("cursor"); }
|
||||||
|
pub mod workspace { tonic::include_proto!("workspace"); }
|
||||||
|
pub mod auth { tonic::include_proto!("auth"); }
|
||||||
|
}
|
Loading…
Reference in a new issue