use ws::{Message, Sender}; use serde_cbor::{from_slice, to_vec}; use uuid::Uuid; use failure::Error; use failure::err_msg; use net::Db; use cryp::{Cryp, spawn}; use battle::{Battle}; use combat::{pve}; use account::{Account, create, login, from_token}; pub struct Rpc; impl Rpc { pub fn receive(&self, msg: Message, db: Db, out: &Sender) -> Result { // consume the ws data into bytes let data = msg.into_data(); // cast the msg to this type to receive method name match from_slice::(&data) { Ok(v) => { let account: Option = match v.token { Some(t) => Some(from_token(t, &db)?), None => None, }; println!("{:?}", account); // now we have the method name // match on that to determine what fn to call match v.method.as_ref() { "cryp_spawn" => { match from_slice::(&data) { Ok(v) => { match account { Some(u) => Ok(RpcResponse { method: v.method, params: RpcResult::SpawnCryp(spawn(v.params, db, u)?) }), None => Err(err_msg("auth required")), } } Err(_e) => Err(err_msg("invalid params")), } }, "combat_pve" => { let send = |b: &Battle| -> Result<(), Error> { let reply = RpcResponse { method: "combat_pve".to_string(), params: RpcResult::Pve(b.clone()) }; let response = to_vec(&reply)?; match out.send(response) { Ok(()) => Ok(()), Err(e) => Err(err_msg(e)) } }; match from_slice::(&data) { Ok(v) => { match account { Some(u) => Ok(RpcResponse { method: v.method, params: RpcResult::Pve(pve(v.params, db, u, send)?) }), None => Err(err_msg("auth required")), } } Err(_e) => Err(err_msg("invalid params")), } }, "account_create" => { match from_slice::(&data) { Ok(v) => Ok(RpcResponse { method: v.method, params: create(v.params, db)? }), Err(_e) => Err(err_msg("invalid params")), } }, "account_login" => { match from_slice::(&data) { Ok(v) => Ok(RpcResponse { method: v.method, params: login(v.params, db)? }), Err(_e) => Err(err_msg("invalid params")), } }, _ => Err(err_msg("unknown method")), } }, Err(_e) => Err(err_msg("invalid message")), } } } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct RpcResponse { method: String, params: RpcResult, } #[derive(Debug,Clone,Serialize,Deserialize)] pub enum RpcResult { SpawnCryp(Cryp), Account(Account), Pve(Battle), } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct RpcMessage { method: String, token: Option, } #[derive(Debug,Clone,Serialize,Deserialize)] struct CrypSpawnMsg { method: String, params: CrypSpawnParams, } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct CrypSpawnParams { pub name: String, } #[derive(Debug,Clone,Serialize,Deserialize)] struct CombatPveMsg { method: String, params: CombatPveParams, } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct CombatPveParams { pub id: Uuid, } #[derive(Debug,Clone,Serialize,Deserialize)] struct AccountCreateMsg { method: String, params: AccountCreateParams, } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct AccountCreateParams { pub name: String, pub password: String, } #[derive(Debug,Clone,Serialize,Deserialize)] struct AccountLoginMsg { method: String, params: AccountLoginParams, } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct AccountLoginParams { pub name: String, pub password: String, } // #[cfg(test)] // mod tests { // use super::*; // use serde_cbor::to_vec; // #[test] // fn rpc_parse() { // let rpc = Rpc {}; // let msg = GenerateMsg { method: "cryp_generate".to_string(), params: GenerateParams { level: 64 } }; // let v = to_vec(&msg).unwrap(); // let received = rpc.receive(Message::Binary(v)); // } // }