more changes

This commit is contained in:
Piyush मिश्रः 2021-02-16 00:23:11 +05:30
parent e9b44b8351
commit e7f8217822
16 changed files with 374 additions and 164 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target
/vecmap/target

5
Cargo.lock generated
View File

@ -1067,6 +1067,7 @@ dependencies = [
"rand 0.8.3",
"serde",
"serde_json",
"vecmap",
]
[[package]]
@ -1975,6 +1976,10 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "vecmap"
version = "0.1.0"
[[package]]
name = "version_check"
version = "0.1.5"

View File

@ -19,3 +19,4 @@ serde = "1.0.123"
serde_json = "1.0.62"
rand = "0.8.3"
futures = "0.3.12"
vecmap = { path = "vecmap" }

13
api.txt
View File

@ -1,7 +1,9 @@
Set name:
Set Info:
{
cmd: "name",
name: name
cmd: "seinfo",
name: name,
kunjika: kunjika,
tags: tags
}
Join Grih:
@ -22,4 +24,9 @@ Send Message:
text: message
}
RandomUser:
{
cmd: "rnd"
}

View File

@ -4,6 +4,7 @@ use std::collections::HashMap;
use actix::prelude::*;
use actix_broker::BrokerSubscribe;
use vecmap::VecMap;
use ws_sansad::WsSansad;
use crate::{errors, ws_sansad, messages as ms};
@ -11,8 +12,8 @@ use crate::{errors, ws_sansad, messages as ms};
#[allow(dead_code)]
pub struct ChatPinnd {
grih: HashMap<String, Grih>, // id, Grih
vyaktigat_waitlist: Vec<Addr<ws_sansad::WsSansad>>,
vyakti: Vec<Vyakti> // id, tags
vyaktigat_waitlist: Vec<VyaktiWatchlist>,
vyakti: VecMap<String, Vyakti> // id, vayakti
}
pub struct Grih {
@ -20,11 +21,17 @@ pub struct Grih {
loog: Vec<Addr<ws_sansad::WsSansad>>
}
#[derive(Clone)]
pub struct Vyakti {
kunjika: String,
name: String,
tags: Vec<String>
}
pub struct VyaktiWatchlist {
kunjika: String,
addr: Addr<ws_sansad::WsSansad>
}
impl Actor for ChatPinnd {
type Context = Context<Self>;
@ -34,34 +41,44 @@ impl Actor for ChatPinnd {
}
}
impl Handler<ms::SetKunjikaUser> for ChatPinnd {
type Result = Result<(), errors::AlreadyExistError>;
impl Handler<ms::SetInfoVyakti> for ChatPinnd {
type Result = Option<String>;
fn handle(&mut self, msg: ms::SetKunjikaUser, ctx: &mut Self::Context) -> Self::Result {
let kunjika = msg.kunjika;
let vyakti = self.vyakti.iter().find(|a| a.kunjika == kunjika);
Ok(())
fn handle(&mut self, msg: ms::SetInfoVyakti, _: &mut Self::Context) -> Self::Result {
if !msg.modify {
if self.vyakti.key_exist(&msg.kunjika) {
return Some("Kunjika Exists".to_owned());
}
}
self.vyakti.insert(msg.kunjika, Vyakti {
name: msg.name,
tags: msg.tags
});
None
}
}
impl Handler<ms::JoinUser> for ChatPinnd {
impl Handler<ms::JoinGrih> for ChatPinnd {
type Result = Result<(), errors::GrihFullError>;
fn handle(&mut self, msg: ms::JoinUser, _: &mut Self::Context) -> Self::Result {
fn handle(&mut self, msg: ms::JoinGrih, _: &mut Self::Context) -> Self::Result {
match self.grih.get_mut(&msg.grih_kunjika) {
Some(grih) =>{
if let Some(n) = grih.length {
println!("length check {}, {}, {}", grih.loog.len(), n,grih.loog.len() >= n);
if grih.loog.len() >= n {
return Err(errors::GrihFullError);
}
}
grih.loog.push(msg.addr);
let username = msg.name.clone();
let username = self.vyakti.get(&msg.kunjika).unwrap().name.to_owned();
let kunjika = msg.kunjika.clone();
grih.loog.iter().for_each(move |a: &Addr<WsSansad>| {
a.do_send(ms::WsConnected {
user: username.clone()
name: username.clone(),
kunjika: kunjika.clone()
})
});
}, None => {
@ -70,7 +87,8 @@ impl Handler<ms::JoinUser> for ChatPinnd {
loog: vec![msg.addr.clone()]
});
msg.addr.do_send(ms::WsConnected {
user: msg.name
name: self.vyakti.get(&msg.kunjika).unwrap().name.to_owned(),
kunjika: msg.kunjika.clone()
});
}
}
@ -79,6 +97,40 @@ impl Handler<ms::JoinUser> for ChatPinnd {
}
}
impl Handler<ms::JoinRandom> for ChatPinnd {
type Result = Option<()>;
fn handle(&mut self, msg: ms::JoinRandom, _: &mut Self::Context) -> Self::Result {
if self.vyaktigat_waitlist.len() == 0 {
self.vyaktigat_waitlist.push(VyaktiWatchlist {
kunjika: msg.kunjika,
addr: msg.addr
});
return None;
}
let vayakti_watchlist = self.vyaktigat_waitlist.remove(0);
let vayakti1 = self.vyakti.get(&msg.kunjika).unwrap();
let vayakti2 = self.vyakti.get(&vayakti_watchlist.kunjika).unwrap();
let group_kunjika = format!("gupt_{}>{}",msg.kunjika, vayakti_watchlist.kunjika);
self.grih.insert(group_kunjika.clone(), Grih {
length: Some(2),
loog: vec![msg.addr.clone(), vayakti_watchlist.addr.clone()]
});
msg.addr.do_send(ms::WsConnectedRandom {
ajnyat_name: vayakti2.name.clone(),
grih_kunjika: group_kunjika.clone()
});
vayakti_watchlist.addr.do_send(ms::WsConnectedRandom {
ajnyat_name: vayakti1.name.clone(),
grih_kunjika: group_kunjika.clone()
});
Some(())
}
}
impl Handler<ms::SendText> for ChatPinnd {
type Result = ();
@ -86,7 +138,7 @@ impl Handler<ms::SendText> for ChatPinnd {
if let Some(grih) = self.grih.get(&msg.grih_kunjika) {
grih.loog.iter().for_each(|c| {
c.do_send(ms::WsMessage {
sender: msg.sender_name.clone(),
sender: msg.kunjika.clone(),
text: msg.text.clone(),
});
});
@ -108,7 +160,7 @@ impl Handler<ms::LeaveUser> for ChatPinnd {
} else {
grih.loog.iter().for_each(|a| {
a.do_send(ms::WsDisconnected {
user: "u".to_owned()
kunjika: msg.kunjika.clone()
})
});
}
@ -121,7 +173,7 @@ impl Default for ChatPinnd {
ChatPinnd {
grih: HashMap::new(),
vyaktigat_waitlist: Vec::new(),
vyakti: Vec::new()
vyakti: VecMap::new()
}
}
}

View File

@ -12,7 +12,7 @@ impl Config {
.author(env!("CARGO_PKG_AUTHORS"))
.about(env!("CARGO_PKG_DESCRIPTION"))
.arg(Arg::with_name("static_path")
.short("b")
.short("s")
.long("static_path")
.value_name("DIR")
.help("Path of directory with index.html")

View File

@ -1,6 +1,5 @@
mod grih_full_error;
mod user_kunjika_error;
pub mod vayakti_list_error;
pub use grih_full_error::GrihFullError;
pub use user_kunjika_error::AlreadyExistError;

View File

@ -8,7 +8,6 @@ mod errors;
mod messages;
mod ws_sansad;
mod chat_pinnd;
mod vyakti_list;
#[actix_web::main]
async fn main() -> std::io::Result<()> {

View File

@ -4,27 +4,38 @@ use actix::prelude::*;
use crate::ws_sansad::WsSansad;
use crate::errors;
// For ChatPinnd
//################################################## For ChatPinnd ##################################################
#[derive(Clone, Message)]
#[rtype(result = "Result<(), errors::AlreadyExistError>")]
pub struct SetKunjikaUser {
pub kunjika: String
#[rtype(result = "Option<String>")] // None if no error
pub struct SetInfoVyakti {
pub kunjika: String,
pub name: String,
pub tags: Vec<String>,
pub modify: bool
}
#[derive(Clone, Message)]
#[rtype(result = "Result<(), errors::GrihFullError>")]
pub struct JoinUser {
pub struct JoinGrih {
pub grih_kunjika: String,
pub length: Option<usize>,
pub addr: Addr<WsSansad>,
pub name: String
pub kunjika: String
}
#[derive(Clone, Message)]
#[rtype(result = "Option<()>")]
pub struct JoinRandom {
pub addr: Addr<WsSansad>,
pub kunjika: String
}
#[derive(Clone, Message)]
#[rtype(result = "()")]
pub struct SendText {
pub grih_kunjika: String,
pub sender_name: String,
pub kunjika: String,
pub text: String
}
@ -32,17 +43,11 @@ pub struct SendText {
#[rtype(result = "()")]
pub struct LeaveUser {
pub grih_kunjika: String,
pub kunjika: String,
pub addr: Addr<WsSansad>
}
#[derive(Clone, Message)]
#[rtype(result = "()")]
pub struct AddUserKunjika {
pub old_kunjika: Option<String>,
pub kunjika: String
}
// For WsSansad
//################################################## For WsSansad ##################################################
#[derive(Clone, Message)]
#[rtype(result = "()")]
pub struct WsMessage {
@ -53,13 +58,14 @@ pub struct WsMessage {
#[derive(Clone, Message)]
#[rtype(result = "()")]
pub struct WsConnected {
pub user: String
pub name: String,
pub kunjika: String
}
#[derive(Clone, Message)]
#[rtype(result = "()")]
pub struct WsDisconnected {
pub user: String
pub kunjika: String
}
#[derive(Clone, Message)]
@ -68,3 +74,12 @@ pub struct WsResponse {
pub result: String,
pub message: String
}
#[derive(Clone, Message)]
#[rtype(result = "()")]
pub struct WsConnectedRandom {
pub ajnyat_name: String,
pub grih_kunjika: String
}

View File

@ -1,98 +0,0 @@
use std::error::Error;
use crate::errors::vayakti_list_error as er;
#[derive(Debug, Clone)]
pub struct VecMap<K: Clone + PartialEq,V: Clone>(Vec<VecMapElement<K,V>>);
#[derive(Debug, Clone)]
pub struct VecMapElement<K: PartialEq,V: Clone> {
key: K,
value: V
}
impl<K: Clone + PartialEq, V: Clone> IntoIterator for VecMap<K, V> {
type IntoIter = std::vec::IntoIter<VecMapElement<K,V>>;
type Item = VecMapElement<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<K: Clone + PartialEq,V: Clone> VecMap<K,V> {
pub fn new() -> VecMap<K,V> {
VecMap(Vec::new())
}
pub fn insert(&mut self, key: K, value: V) {
let key_tmp = key.clone();
match self.0.iter_mut().find(move |a| {
a.key == key_tmp
}) {
Some(i) => {
i.value = value.clone();
}
None => {
self.0.push(VecMapElement {
key,
value
});
}
}
}
pub fn get(&self, key: K) -> Option<&V> {
match self.0.iter().find(|a| {
a.key == key
}) {
Some(v) => Some(&v.value),
None => None
}
}
pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
match self.0.iter_mut().find(move |a| {
a.key == key
}) {
Some(v) => Some(&mut v.value),
None => None
}
}
pub fn remove(&mut self, key: K) -> Result<(), er::ElementNotFount> {
match self.0.iter().position(move |a| {
a.key == key
}) {
Some(i) => {
self.0.remove(i);
}
None => {
return Err(er::ElementNotFount);
}
}
Ok(())
}
pub fn change_key(&mut self, key: K, new_key: K) -> Result<(), &dyn Error> {
let key_tmp = key.clone();
if let Some(_) = self.0.iter().position(move |a| {
a.key == key_tmp
}) {
return Err(&er::KeyAlreadyExist);
}
match self.0.iter_mut().find(move |a| {
a.key == key
}) {
Some(i) => {
i.key = new_key;
}
None => {
return Err(&er::ElementNotFount);
}
}
Ok(())
}
}

View File

@ -8,17 +8,16 @@ use crate::{chat_pinnd::ChatPinnd, messages as ms};
use crate::errors;
pub struct WsSansad {
name: String,
kunjika: Option<String>,
isthiti: Isthiti,
addr: Option<Addr<Self>>,
}
#[allow(dead_code)]
#[derive(Debug)]
enum Isthiti {
None,
Grih(String),
// VraktigatWaitlist
VraktigatWaitlist
}
impl Actor for WsSansad {
@ -55,7 +54,7 @@ impl Handler<ms::WsMessage> for WsSansad {
let json = json!({
"cmd": "text",
"text": msg.text,
"sender": msg.sender
"kunjika": msg.sender // Sender's kunjuka
});
ctx.text(json.to_string());
}
@ -78,7 +77,8 @@ impl Handler<ms::WsConnected> for WsSansad {
fn handle(&mut self, msg: ms::WsConnected, ctx: &mut Self::Context) -> Self::Result {
let json = json!({
"cmd": "connected",
"user": msg.user
"name": msg.name,
"kunjika": msg.kunjika
});
ctx.text(json.to_string());
}
@ -89,17 +89,30 @@ impl Handler<ms::WsDisconnected> for WsSansad {
fn handle(&mut self, msg: ms::WsDisconnected, ctx: &mut Self::Context) -> Self::Result {
let json = json!({
"cmd": "disconnected",
"user": msg.user
"name": msg.kunjika
});
ctx.text(json.to_string());
}
}
impl Handler<ms::WsConnectedRandom> for WsSansad {
type Result = ();
fn handle(&mut self, msg: ms::WsConnectedRandom, ctx: &mut Self::Context) -> Self::Result {
self.isthiti = Isthiti::Grih(msg.grih_kunjika);
let json = json!({
"cmd": "connected",
"ajnyat": msg.ajnyat_name
});
ctx.text(json.to_string());
}
}
impl WsSansad {
pub fn new() -> Self {
WsSansad {
name: "()".to_owned(),
kunjika: None,
isthiti: Isthiti::None,
addr: None,
@ -107,12 +120,11 @@ impl WsSansad {
}
async fn parse_text_handle(&mut self, msg: String) {
println!("{}", msg);
if let Ok(val) = serde_json::from_str::<Value>(&msg) {
match val.get("cmd").unwrap().as_str().unwrap() {
"name" => { self.set_name(val).await },
"kunjika" => { self.set_kunjika(val).await },
"seinfo" => { self.set_info(val).await },
"join" => { self.join_grih(val).await },
"rand" => { self.join_random().await },
"text" => { self.send_text(val).await },
"leave" => { self.leave_grih().await },
_ => ()
@ -134,14 +146,79 @@ impl WsSansad {
});
}
async fn set_name(&mut self, val: Value) {
self.name = val.get("name").unwrap().as_str().unwrap().to_owned();
async fn set_info(&mut self, val: Value) {
let kunjika = match val.get("kunjika") {
Some(val ) => val.as_str().unwrap().to_owned(),
None => {
self.send_err_response("Invalid request");
return;
}
};
let name = match val.get("name") {
Some(val ) => val.as_str().unwrap().to_owned(),
None => {
self.send_err_response("Invalid request");
return;
}
};
let tags = match val.get("tags") {
Some(val ) => {
let mut v = Vec::new();
for x in val.as_str().unwrap().split_ascii_whitespace() {
v.push(x.to_owned());
}
v
},
None => {
self.send_err_response("Invalid request");
return;
}
};
let modify = self.kunjika == Some(kunjika.clone());
let result: Option<String> = ChatPinnd::from_registry().send(ms::SetInfoVyakti {
kunjika: kunjika.clone(),
name,
tags,
modify
}).await.unwrap();
if let Some(msg) = result {
self.send_err_response(&msg);
return;
}
self.kunjika = Some(kunjika);
self.send_ok_response();
}
async fn set_kunjika(&mut self, val: Value) {
self.name = val.get("name").unwrap().as_str().unwrap().to_owned();
self.send_ok_response();
async fn join_random(&mut self) {
if let None = self.kunjika {
self.send_err_response("No user kunjika set");
return;
}
if let Isthiti::VraktigatWaitlist = self.isthiti {
self.addr.clone().unwrap().do_send(ms::WsResponse {
result: "Ok".to_owned(),
message: "watchlist".to_owned()
});
return;
}
let result: Option<()> = ChatPinnd::from_registry().send(ms::JoinRandom{
addr: self.addr.clone().unwrap(),
kunjika: self.kunjika.clone().unwrap()
}).await.unwrap();
if let None = result {
self.addr.clone().unwrap().do_send(ms::WsResponse {
result: "Ok".to_owned(),
message: "watchlist".to_owned()
});
self.isthiti = Isthiti::VraktigatWaitlist;
}
}
async fn join_grih(&mut self, val: Value) {
@ -150,28 +227,34 @@ impl WsSansad {
return;
}
let kunjika = match val.get("kunjika") {
let grih_kunjika = match val.get("kunjika") {
Some(val) => val,
None => {
self.send_err_response("Invalid request");
return;
}
}.as_str().unwrap().to_owned();
if grih_kunjika.starts_with("gupt_") {
self.send_err_response("Such grih kunjika is restricted");
return;
}
let length: Option<usize> = match val.get("length") {
Some(val) => Some(val.as_i64().unwrap() as usize),
None => None
};
let result: Result<(), errors::GrihFullError> = ChatPinnd::from_registry().send(ms::JoinUser {
grih_kunjika: kunjika.clone(),
let result: Result<(), errors::GrihFullError> = ChatPinnd::from_registry().send(ms::JoinGrih {
grih_kunjika: grih_kunjika.clone(),
length,
addr: self.addr.clone().unwrap(),
name: self.name.clone()
kunjika: self.kunjika.clone().unwrap()
}).await.unwrap();
match result {
Ok(_) => {
self.isthiti = Isthiti::Grih(kunjika);
self.isthiti = Isthiti::Grih(grih_kunjika);
self.send_ok_response()
},
Err(e) => self.send_err_response(&format!("{}", e))
@ -179,6 +262,16 @@ impl WsSansad {
}
async fn send_text(&mut self, val: Value) {
if let None = self.kunjika {
self.send_err_response("No user kunjika set");
return;
}
if let Isthiti::None = self.isthiti {
self.send_err_response("Grih not connected");
return;
}
let text = match val.get("text") {
Some(val) => val,
None => {
@ -189,13 +282,13 @@ impl WsSansad {
let grih_kunjika = match &self.isthiti {
Isthiti::Grih(g) => {
g.clone()
}, Isthiti::None => {
}, _ => {
return;
}
};
Broker::<SystemBroker>::issue_async(ms::SendText {
grih_kunjika,
sender_name: self.name.clone(),
kunjika: self.kunjika.clone().unwrap(),
text
});
}
@ -204,6 +297,7 @@ impl WsSansad {
if let Isthiti::Grih(val) = &mut self.isthiti {
Broker::<SystemBroker>::issue_async(ms::LeaveUser {
grih_kunjika: val.clone(),
kunjika: self.kunjika.clone().unwrap(),
addr: self.addr.clone().unwrap()
});

View File

@ -46,10 +46,18 @@ function send(t) {
}));
}
function name(t) {
function info(k, n, t) {
socket.send(JSON.stringify({
cmd: "name",
name: t
cmd: "seinfo",
kunjika: k,
name: n,
tags: t
}));
}
function joinrand() {
socket.send(JSON.stringify({
cmd: "rand"
}));
}

5
vecmap/Cargo.lock generated Normal file
View File

@ -0,0 +1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "hashmap_mod"
version = "0.1.0"

9
vecmap/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "vecmap"
version = "0.1.0"
authors = ["piyush"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

113
vecmap/src/lib.rs Normal file
View File

@ -0,0 +1,113 @@
use std::error::Error;
pub mod errors;
#[derive(Debug, Clone)]
pub struct VecMap<K: Clone + PartialEq,V: Clone>(Vec<VecMapElement<K,V>>);
#[derive(Debug, Clone)]
pub struct VecMapElement<K: PartialEq,V: Clone> {
key: K,
value: V
}
impl<K: Clone + PartialEq, V: Clone> IntoIterator for VecMap<K, V> {
type IntoIter = std::vec::IntoIter<VecMapElement<K,V>>;
type Item = VecMapElement<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<K: Clone + PartialEq,V: Clone> VecMap<K,V> {
pub fn new() -> VecMap<K,V> {
VecMap(Vec::new())
}
pub fn insert(&mut self, key: K, value: V) {
let key_tmp = key.clone();
match self.0.iter_mut().find(move |a| a.key == key_tmp) {
Some(i) => {
i.value = value.clone();
}
None => {
self.0.push(VecMapElement {
key,
value
});
}
}
}
pub fn get(&self, key: &K) -> Option<&V> {
match self.0.iter().find(|a| &a.key == key) {
Some(v) => Some(&v.value),
None => None
}
}
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
match self.0.iter_mut().find(move |a| &a.key == key) {
Some(v) => Some(&mut v.value),
None => None
}
}
pub fn remove(&mut self, key: &K) -> Result<(), errors::ElementNotFount> {
match self.0.iter().position(move |a| &a.key == key) {
Some(i) => {
self.0.remove(i);
}
None => {
return Err(errors::ElementNotFount);
}
}
Ok(())
}
pub fn change_key(&mut self, key: &K, new_key: &K) -> Result<(), &dyn Error> {
let key_tmp = key.clone();
if let Some(_) = self.0.iter().position(move |a| a.key == key_tmp) {
return Err(&errors::KeyAlreadyExist);
}
match self.0.iter_mut().find(move |a| &a.key == key) {
Some(i) => {
i.key = new_key.to_owned();
}
None => {
return Err(&errors::ElementNotFount);
}
}
Ok(())
}
pub fn key_exist(&self, key: &K) -> bool {
match self.0.iter().position(move |a| &a.key == key) {
Some(_) => true,
None => false
}
}
}
#[cfg(test)]
mod tests {
use crate::VecMap;
#[test]
fn it_works() {
let mut a: VecMap<i32, i32> = super::VecMap::new();
a.insert(1, 5);
a.insert(2, 10);
a.change_key(1, 2).unwrap();
a.insert(2, 15);
a.into_iter().enumerate().for_each(|(i,e)| {
println!("{}\t-> {:?}", i,e);
});
}
}