new msg macro
This commit is contained in:
+1
-1
Submodule iris updated: a648c62aa2...e817bc83af
+40
-25
@@ -1,9 +1,9 @@
|
|||||||
use crate::{Client, ClientEvent, ClientSender, Rsc, session::Session};
|
use crate::{Client, ClientSender, Rsc, session::Session};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use iris::prelude::DefaultRsc;
|
use iris::prelude::DefaultRsc;
|
||||||
use openworm::net::{
|
use openworm::net::{
|
||||||
ClientMsg, ClientMsgInst, RecvHandler, RequestId, RequestMsg, SERVER_NAME, ServerMsg,
|
ClientMsg, ClientMsgInst, RecvHandler, ReqErr, RequestId, RequestMsg, SERVER_NAME, ServerMsg,
|
||||||
ServerMsgInst, SkipServerVerification, recv_uni, send_uni,
|
ServerResp, SkipServerVerification, recv_uni, send_uni,
|
||||||
};
|
};
|
||||||
use quinn::{
|
use quinn::{
|
||||||
ClientConfig, Connection, Endpoint, IdleTimeout, TransportConfig,
|
ClientConfig, Connection, Endpoint, IdleTimeout, TransportConfig,
|
||||||
@@ -31,16 +31,16 @@ pub struct NetHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NetResult<T> = Result<T, String>;
|
type NetResult<T> = Result<T, String>;
|
||||||
type SyncReqFn = Box<dyn FnOnce(ServerMsg, &mut Rsc) + Send + Sync>;
|
type SyncReqFn = Box<dyn FnOnce(ServerResp, &mut Rsc) + Send + Sync>;
|
||||||
|
|
||||||
pub enum NetCtrlMsg {
|
pub enum NetCtrlMsg {
|
||||||
Send(ClientMsg),
|
Send(ClientMsg),
|
||||||
Request(ClientMsg, oneshot::Sender<ServerMsg>),
|
Request(ClientMsg, oneshot::Sender<ServerResp>),
|
||||||
RequestSync(ClientMsg, SyncReqFn),
|
RequestSync(ClientMsg, SyncReqFn),
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Resp<R: RequestMsg> = Result<R::Result, ()>;
|
type Resp<R> = Result<<R as RequestMsg>::Result, Error>;
|
||||||
|
|
||||||
// TODO: move into iris?
|
// TODO: move into iris?
|
||||||
pub trait MainDataCallback<Data, State>:
|
pub trait MainDataCallback<Data, State>:
|
||||||
@@ -52,6 +52,12 @@ impl<F: FnOnce(Data, &mut DefaultRsc<State>) + Sync + Send + 'static, Data, Stat
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Error {
|
||||||
|
Req(ReqErr),
|
||||||
|
InvalidResp,
|
||||||
|
Connection,
|
||||||
|
}
|
||||||
|
|
||||||
impl NetHandle {
|
impl NetHandle {
|
||||||
fn send_(&self, msg: NetCtrlMsg) {
|
fn send_(&self, msg: NetCtrlMsg) {
|
||||||
let _ = self.send.send(msg);
|
let _ = self.send.send(msg);
|
||||||
@@ -64,26 +70,32 @@ impl NetHandle {
|
|||||||
pub async fn request<R: RequestMsg>(&self, msg: R) -> Resp<R> {
|
pub async fn request<R: RequestMsg>(&self, msg: R) -> Resp<R> {
|
||||||
let (send, recv) = oneshot::channel();
|
let (send, recv) = oneshot::channel();
|
||||||
self.send_(NetCtrlMsg::Request(msg.into(), send));
|
self.send_(NetCtrlMsg::Request(msg.into(), send));
|
||||||
let Ok(recv) = recv.await else { return Err(()) };
|
let Ok(recv) = recv.await else {
|
||||||
if let Some(res) = R::result(recv) {
|
return Err(Error::Connection);
|
||||||
Ok(res)
|
};
|
||||||
} else {
|
match recv {
|
||||||
Err(())
|
ServerResp::Ok(resp) => match R::result(resp) {
|
||||||
|
Some(val) => Ok(val),
|
||||||
|
None => Err(Error::InvalidResp),
|
||||||
|
},
|
||||||
|
ServerResp::Err(err) => Err(Error::Req(err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_sync<R: RequestMsg>(
|
pub fn request_sync<R: RequestMsg>(
|
||||||
&self,
|
&self,
|
||||||
msg: R,
|
msg: R,
|
||||||
callback: impl MainDataCallback<Result<R::Result, ()>, Client>,
|
callback: impl MainDataCallback<Result<R::Result, Error>, Client>,
|
||||||
) {
|
) {
|
||||||
self.send_(NetCtrlMsg::RequestSync(
|
self.send_(NetCtrlMsg::RequestSync(
|
||||||
msg.into(),
|
msg.into(),
|
||||||
Box::new(move |msg, rsc| {
|
Box::new(move |msg, rsc| {
|
||||||
let res = if let Some(res) = R::result(msg) {
|
let res = match msg {
|
||||||
Ok(res)
|
ServerResp::Ok(resp) => match R::result(resp) {
|
||||||
} else {
|
Some(val) => Ok(val),
|
||||||
Err(())
|
None => Err(Error::InvalidResp),
|
||||||
|
},
|
||||||
|
ServerResp::Err(err) => Err(Error::Req(err)),
|
||||||
};
|
};
|
||||||
callback(res, rsc);
|
callback(res, rsc);
|
||||||
}),
|
}),
|
||||||
@@ -104,7 +116,7 @@ impl<R: RequestMsg> SyncRecv<R> {
|
|||||||
match self.recv.try_recv() {
|
match self.recv.try_recv() {
|
||||||
Ok(res) => Some(res),
|
Ok(res) => Some(res),
|
||||||
Err(oneshot::error::TryRecvError::Empty) => None,
|
Err(oneshot::error::TryRecvError::Empty) => None,
|
||||||
Err(oneshot::error::TryRecvError::Closed) => Some(Err(())),
|
Err(oneshot::error::TryRecvError::Closed) => Some(Err(Error::Connection)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,22 +264,25 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ServerRecv {
|
struct ServerRecv {
|
||||||
requests: DashMap<RequestId, oneshot::Sender<ServerMsg>>,
|
requests: DashMap<RequestId, oneshot::Sender<ServerResp>>,
|
||||||
requests_sync: DashMap<RequestId, SyncReqFn>,
|
requests_sync: DashMap<RequestId, SyncReqFn>,
|
||||||
event_sender: ClientSender,
|
event_sender: ClientSender,
|
||||||
id: usize,
|
id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RecvHandler<ServerMsgInst> for ServerRecv {
|
impl RecvHandler<ServerMsg> for ServerRecv {
|
||||||
async fn msg(&self, resp: ServerMsgInst) {
|
async fn msg(&self, resp: ServerMsg) {
|
||||||
if let Some(id) = resp.id {
|
match resp {
|
||||||
|
ServerMsg::Response { id, msg } => {
|
||||||
if let Some((_, send)) = self.requests.remove(&id) {
|
if let Some((_, send)) = self.requests.remove(&id) {
|
||||||
let _ = send.send(resp.msg);
|
let _ = send.send(msg);
|
||||||
} else if let Some((_, f)) = self.requests_sync.remove(&id) {
|
} else if let Some((_, f)) = self.requests_sync.remove(&id) {
|
||||||
self.event_sender.run(|rsc| f(resp.msg, rsc));
|
self.event_sender.run(|rsc| f(msg, rsc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ServerMsg::Notif(notif) => {
|
||||||
|
Session::handle(&self.event_sender, self.id, notif);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Session::handle(&self.event_sender, self.id, resp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
|
|
||||||
use iris::prelude::*;
|
use iris::prelude::*;
|
||||||
use openworm::net::{ServerMsgInst, UserId};
|
use openworm::net::{ServerNotif, UserId};
|
||||||
|
|
||||||
use crate::{ClientSender, Rsc, net::NetHandle, ui::UserCache};
|
use crate::{ClientSender, Rsc, net::NetHandle, ui::UserCache};
|
||||||
|
|
||||||
@@ -39,8 +39,8 @@ impl Session {
|
|||||||
span
|
span
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle(sender: &ClientSender, id: usize, inst: ServerMsgInst) {
|
pub fn handle(sender: &ClientSender, id: usize, notif: ServerNotif) {
|
||||||
match inst.msg {
|
match notif {
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unknown server message recieved");
|
println!("Unknown server message recieved");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ impl Session {
|
|||||||
s.con
|
s.con
|
||||||
.request_sync(RequestUserInfo { id }, move |resp, rsc| {
|
.request_sync(RequestUserInfo { id }, move |resp, rsc| {
|
||||||
if let Ok(info) = resp {
|
if let Ok(info) = resp {
|
||||||
|
let info = info.info;
|
||||||
let s = &mut session.get().cache;
|
let s = &mut session.get().cache;
|
||||||
for &widget in s.widgets.get(&id).into_iter().flatten() {
|
for &widget in s.widgets.get(&id).into_iter().flatten() {
|
||||||
*rsc[widget].content = info.username.clone();
|
*rsc[widget].content = info.username.clone();
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ impl ClientHandler {
|
|||||||
if let ClientState::Authed(uid) = &*self.state.read().await {
|
if let ClientState::Authed(uid) = &*self.state.read().await {
|
||||||
Some(*uid)
|
Some(*uid)
|
||||||
} else {
|
} else {
|
||||||
reply!(NotLoggedIn);
|
reply!(ReqErr::NotLoggedIn);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let check_user = async || {
|
let check_user = async || {
|
||||||
@@ -49,10 +49,10 @@ impl ClientHandler {
|
|||||||
if let Some(user) = self.db.users.get(uid) {
|
if let Some(user) = self.db.users.get(uid) {
|
||||||
Some((*uid, user))
|
Some((*uid, user))
|
||||||
} else {
|
} else {
|
||||||
reply!(InvalidUser);
|
reply!(ReqErr::InvalidUser);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reply!(NotLoggedIn);
|
reply!(ReqErr::NotLoggedIn);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let check_server_perms = async |perms| {
|
let check_server_perms = async |perms| {
|
||||||
@@ -63,7 +63,7 @@ impl ClientHandler {
|
|||||||
.get(&id)
|
.get(&id)
|
||||||
.is_some_and(|u| !u.server_perms.contains(perms))
|
.is_some_and(|u| !u.server_perms.contains(perms))
|
||||||
{
|
{
|
||||||
reply!(NoPermission);
|
reply!(ReqErr::NoPermission);
|
||||||
} else {
|
} else {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ impl ClientHandler {
|
|||||||
loop {
|
loop {
|
||||||
let mut tx = db.write_tx();
|
let mut tx = db.write_tx();
|
||||||
let Some(mut user) = tx.get(&db.users, &user_id) else {
|
let Some(mut user) = tx.get(&db.users, &user_id) else {
|
||||||
reply!(InvalidUser);
|
reply!(ReqErr::InvalidUser);
|
||||||
};
|
};
|
||||||
let Some(other_id) = tx.get(&db.usernames, &info.username) else {
|
let Some(other_id) = tx.get(&db.usernames, &info.username) else {
|
||||||
reply!(AddFriendResp::UnknownUser);
|
reply!(AddFriendResp::UnknownUser);
|
||||||
@@ -265,11 +265,13 @@ impl ClientHandler {
|
|||||||
ClientMsg::RequestUserInfo(info) => {
|
ClientMsg::RequestUserInfo(info) => {
|
||||||
check_user().await?;
|
check_user().await?;
|
||||||
let Some(other_user) = db.users.get(&info.id) else {
|
let Some(other_user) = db.users.get(&info.id) else {
|
||||||
reply!(InvalidUser);
|
reply!(ReqErr::InvalidUser);
|
||||||
};
|
};
|
||||||
// TODO: check perms... (privacy settings)
|
// TODO: check perms... (privacy settings)
|
||||||
reply!(UserInfo {
|
reply!(RequestUserInfoResp {
|
||||||
|
info: UserInfo {
|
||||||
username: other_user.username
|
username: other_user.username
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-10
@@ -1,6 +1,6 @@
|
|||||||
use openworm::net::{
|
use openworm::net::{
|
||||||
ClientMsgInst, RecvHandler, RequestId, SERVER_NAME, SendResult, ServerMsg, ServerMsgInst,
|
ClientMsgInst, RecvHandler, RequestId, ServerResp, SERVER_NAME, SendResult, ServerMsg, recv_uni,
|
||||||
recv_uni, send_uni,
|
send_uni,
|
||||||
};
|
};
|
||||||
use quinn::{
|
use quinn::{
|
||||||
Connection, Endpoint, ServerConfig,
|
Connection, Endpoint, ServerConfig,
|
||||||
@@ -65,11 +65,7 @@ impl ClientSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&self, msg: impl Into<ServerMsg>) -> SendResult {
|
pub async fn send(&self, msg: impl Into<ServerMsg>) -> SendResult {
|
||||||
let msg = ServerMsgInst {
|
send_uni(&self.conn, msg.into()).await
|
||||||
id: None,
|
|
||||||
msg: msg.into(),
|
|
||||||
};
|
|
||||||
send_uni(&self.conn, msg).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,9 +75,9 @@ pub struct ClientReplier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ClientReplier {
|
impl ClientReplier {
|
||||||
pub async fn send(&self, msg: impl Into<ServerMsg>) {
|
pub async fn send(&self, msg: impl Into<ServerResp>) {
|
||||||
let msg = ServerMsgInst {
|
let msg = ServerMsg::Response {
|
||||||
id: Some(self.req_id),
|
id: self.req_id,
|
||||||
msg: msg.into(),
|
msg: msg.into(),
|
||||||
};
|
};
|
||||||
let _ = send_uni(&self.conn, msg).await;
|
let _ = send_uni(&self.conn, msg).await;
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
|
#![feature(macro_metavar_expr_concat)]
|
||||||
|
|
||||||
pub mod net;
|
pub mod net;
|
||||||
pub mod rsc;
|
pub mod rsc;
|
||||||
|
|||||||
-100
@@ -1,22 +1,3 @@
|
|||||||
use iris::core::util::HashSet;
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct CreateChannel {
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub enum CreateChannelResp {
|
|
||||||
Ok,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct RequestUserInfo {
|
|
||||||
pub id: UserId,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type RequestUserInfoResp = UserInfo;
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
pub struct UserInfo {
|
pub struct UserInfo {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
@@ -25,92 +6,18 @@ pub struct UserInfo {
|
|||||||
pub type UserId = u64;
|
pub type UserId = u64;
|
||||||
pub type AccountToken = String;
|
pub type AccountToken = String;
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct CreateAccount {
|
|
||||||
pub username: String,
|
|
||||||
pub password: String,
|
|
||||||
pub token: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub enum CreateAccountResp {
|
|
||||||
Ok { id: UserId },
|
|
||||||
UsernameExists,
|
|
||||||
InvalidToken,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct Login {
|
|
||||||
pub username: String,
|
|
||||||
pub password: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub enum LoginResp {
|
|
||||||
Ok { id: UserId },
|
|
||||||
UnknownUsername,
|
|
||||||
InvalidPassword,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct RequestUsers;
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct RequestUsersResp {
|
|
||||||
pub users: Vec<ServerUser>,
|
|
||||||
}
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
pub struct ServerUser {
|
pub struct ServerUser {
|
||||||
pub id: UserId,
|
pub id: UserId,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct RequestFriends;
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct RequestFriendsResp {
|
|
||||||
pub current: HashSet<UserId>,
|
|
||||||
pub incoming: HashSet<UserId>,
|
|
||||||
pub outgoing: HashSet<UserId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct AddFriend {
|
|
||||||
pub username: String,
|
|
||||||
}
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub enum AddFriendResp {
|
|
||||||
Ok,
|
|
||||||
UnknownUser,
|
|
||||||
CannotAddSelf,
|
|
||||||
AlreadySent,
|
|
||||||
AlreadyFriends,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct RemoveFriend {
|
|
||||||
pub id: UserId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct AnswerFriendRequest {
|
|
||||||
pub id: UserId,
|
|
||||||
pub action: FriendRequestAction,
|
|
||||||
}
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
pub enum FriendRequestAction {
|
pub enum FriendRequestAction {
|
||||||
Accept,
|
Accept,
|
||||||
Deny,
|
Deny,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct GenerateToken {
|
|
||||||
pub perms: ServerPerms,
|
|
||||||
}
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct GenerateTokenResp {
|
|
||||||
pub token: AccountToken,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, bitcode::Encode, bitcode::Decode)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, bitcode::Encode, bitcode::Decode)]
|
||||||
pub struct ServerPerms(u32);
|
pub struct ServerPerms(u32);
|
||||||
impl ServerPerms {
|
impl ServerPerms {
|
||||||
@@ -123,10 +30,3 @@ impl ServerPerms {
|
|||||||
(self.0 & other.0) == other.0
|
(self.0 & other.0) == other.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct NotLoggedIn;
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct NoPermission;
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct InvalidUser;
|
|
||||||
|
|||||||
+194
-41
@@ -1,57 +1,210 @@
|
|||||||
|
use crate::net::RequestId;
|
||||||
|
|
||||||
use super::{RequestMsg, data::*};
|
use super::{RequestMsg, data::*};
|
||||||
|
use iris::core::util::HashSet;
|
||||||
|
|
||||||
msg_type!(ClientMsg: {
|
def_msgs! {
|
||||||
0: CreateAccount => CreateAccountResp,
|
ClientMsg => ClientMsgResp {
|
||||||
1: Login => LoginResp,
|
0: CreateAccount {
|
||||||
2: RequestUsers => RequestUsersResp,
|
username: String,
|
||||||
3: RequestFriends => RequestFriendsResp,
|
password: String,
|
||||||
4: AddFriend => AddFriendResp,
|
token: String,
|
||||||
5: RemoveFriend,
|
} => enum {
|
||||||
6: AnswerFriendRequest,
|
Ok { id: UserId },
|
||||||
7: GenerateToken => GenerateTokenResp,
|
UsernameExists,
|
||||||
8: RequestUserInfo => RequestUserInfoResp,
|
InvalidToken,
|
||||||
9: CreateChannel => CreateChannelResp,
|
},
|
||||||
});
|
|
||||||
msg_type!(ServerMsg: {
|
1: Login {
|
||||||
0: NotLoggedIn,
|
username: String,
|
||||||
1: NoPermission,
|
password: String,
|
||||||
2: InvalidUser,
|
} => enum {
|
||||||
3: CreateAccountResp,
|
Ok { id: UserId },
|
||||||
4: LoginResp,
|
UnknownUsername,
|
||||||
5: RequestUsersResp,
|
InvalidPassword,
|
||||||
6: RequestFriendsResp,
|
},
|
||||||
7: AddFriendResp,
|
|
||||||
8: GenerateTokenResp,
|
2: RequestUsers; => struct {
|
||||||
9: RequestUserInfoResp,
|
users: Vec<ServerUser>,
|
||||||
10: CreateChannelResp,
|
},
|
||||||
});
|
|
||||||
|
3: RequestFriends; => struct {
|
||||||
|
current: HashSet<UserId>,
|
||||||
|
incoming: HashSet<UserId>,
|
||||||
|
outgoing: HashSet<UserId>,
|
||||||
|
},
|
||||||
|
|
||||||
|
4: AddFriend {
|
||||||
|
username: String,
|
||||||
|
} => enum {
|
||||||
|
Ok,
|
||||||
|
UnknownUser,
|
||||||
|
CannotAddSelf,
|
||||||
|
AlreadySent,
|
||||||
|
AlreadyFriends,
|
||||||
|
},
|
||||||
|
|
||||||
|
5: RemoveFriend {
|
||||||
|
id: UserId,
|
||||||
|
} => struct;,
|
||||||
|
|
||||||
|
6: AnswerFriendRequest {
|
||||||
|
id: UserId,
|
||||||
|
action: FriendRequestAction,
|
||||||
|
} => struct;,
|
||||||
|
|
||||||
|
7: GenerateToken {
|
||||||
|
perms: ServerPerms,
|
||||||
|
} => struct {
|
||||||
|
token: AccountToken,
|
||||||
|
},
|
||||||
|
|
||||||
|
8: RequestUserInfo {
|
||||||
|
id: UserId,
|
||||||
|
} => struct {
|
||||||
|
info: UserInfo,
|
||||||
|
},
|
||||||
|
|
||||||
|
9: CreateChannel {
|
||||||
|
name: String,
|
||||||
|
} => enum {
|
||||||
|
Ok
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ServerNotif {
|
||||||
|
0: struct Dummy;,
|
||||||
|
}
|
||||||
|
RequestMsg, ServerResp
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
|
pub enum ServerResp {
|
||||||
|
Ok(ClientMsgResp),
|
||||||
|
Err(ReqErr),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
|
pub enum ReqErr {
|
||||||
|
UnknownRequest,
|
||||||
|
NotLoggedIn,
|
||||||
|
NoPermission,
|
||||||
|
InvalidUser,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(u32)]
|
||||||
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
|
pub enum ServerMsg {
|
||||||
|
Response { id: RequestId, msg: ServerResp } = 0,
|
||||||
|
Notif(ServerNotif),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ReqErr> for ServerResp {
|
||||||
|
fn from(value: ReqErr) -> Self {
|
||||||
|
Self::Err(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! def_msgs {
|
||||||
|
(
|
||||||
|
$c_msg:ident => $s_resp:ident {
|
||||||
|
$($c_num:literal: $c_name:ident $c_def:tt => $c_resp_kind:tt $c_resp_def:tt,)*
|
||||||
|
}
|
||||||
|
$s_notif:ident {
|
||||||
|
$($s_num:literal: $s_kind:tt $s_name:ident $s_def:tt,)*
|
||||||
|
}
|
||||||
|
$req_t:ident, $resp:ident
|
||||||
|
) => {
|
||||||
|
msg_type! { $c_msg;
|
||||||
|
$($c_num: struct $c_name $c_def,)*
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_type! { $s_resp;
|
||||||
|
$($c_num: $c_resp_kind ${concat($c_name, Resp)} $c_resp_def,)*
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_type! { $s_notif;
|
||||||
|
$($s_num: $s_kind $s_name $s_def,)*
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! msg_type {
|
|
||||||
($msg:ident: {$($num:literal: $name:ident $(=> $resp:ident)?,)*}) => {
|
|
||||||
#[repr(u32)]
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub enum $msg {$(
|
|
||||||
$name($name) = $num,
|
|
||||||
)*}
|
|
||||||
$(
|
$(
|
||||||
impl From<$name> for $msg {
|
impl From<${concat($c_name, Resp)}> for $resp {
|
||||||
fn from(value: $name) -> Self {
|
fn from(value: ${concat($c_name, Resp)}) -> Self {
|
||||||
Self::$name(value)
|
Self::Ok(value.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$(
|
impl $req_t for $c_name {
|
||||||
impl RequestMsg for $name {
|
type Result = ${concat($c_name, Resp)};
|
||||||
type Result = $resp;
|
fn result(msg: $s_resp) -> Option<Self::Result> {
|
||||||
fn result(msg: ServerMsg) -> Option<Self::Result> {
|
if let $s_resp::${concat($c_name, Resp)}(res) = msg {
|
||||||
if let ServerMsg::$resp(res) = msg {
|
|
||||||
Some(res)
|
Some(res)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)?
|
|
||||||
)*
|
)*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
use def_msgs;
|
||||||
|
|
||||||
|
macro_rules! msg_type {
|
||||||
|
(
|
||||||
|
@finish
|
||||||
|
$msg:ident {$($num:literal: $name:ident,)*}
|
||||||
|
) => {
|
||||||
|
#[repr(u32)]
|
||||||
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
|
pub enum $msg {
|
||||||
|
$(
|
||||||
|
$name($name) = $num,
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
$(
|
||||||
|
impl From<$name> for $msg {
|
||||||
|
fn from(value: $name) -> Self {
|
||||||
|
Self::$name(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
@derive $item:item
|
||||||
|
) => {
|
||||||
|
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
||||||
|
$item
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
@def struct $name:ident {$($field:ident: $ty:ty,)*}
|
||||||
|
) => {
|
||||||
|
msg_type!(@derive pub struct $name {$(pub $field: $ty,)*});
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
@def struct $name:ident ($($ty:ty $(,)?)*)
|
||||||
|
) => {
|
||||||
|
msg_type!(@derive pub struct $name ($(pub $ty, )*););
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
@def struct $name:ident;
|
||||||
|
) => {
|
||||||
|
msg_type!(@derive pub struct $name;);
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
@def enum $name:ident $rest:tt
|
||||||
|
) => {
|
||||||
|
msg_type!(@derive pub enum $name $rest);
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
$msg:ident;
|
||||||
|
$($num:literal: $kind:tt $name:tt $def:tt,)*
|
||||||
|
) => {
|
||||||
|
$(msg_type!(@def $kind $name $def);)*
|
||||||
|
msg_type!(@finish $msg {$($num: $name,)*});
|
||||||
|
};
|
||||||
|
}
|
||||||
use msg_type;
|
use msg_type;
|
||||||
|
|||||||
+1
-7
@@ -24,13 +24,7 @@ pub struct ClientMsgInst {
|
|||||||
pub msg: ClientMsg,
|
pub msg: ClientMsg,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
|
|
||||||
pub struct ServerMsgInst {
|
|
||||||
pub id: Option<RequestId>,
|
|
||||||
pub msg: ServerMsg,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait RequestMsg: Into<ClientMsg> {
|
pub trait RequestMsg: Into<ClientMsg> {
|
||||||
type Result: Send + Sync + 'static;
|
type Result: Send + Sync + 'static;
|
||||||
fn result(msg: ServerMsg) -> Option<Self::Result>;
|
fn result(msg: ClientMsgResp) -> Option<Self::Result>;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user