feat: v0.1.8
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -571,7 +571,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "room-rs"
|
name = "room-rs"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "room-rs"
|
name = "room-rs"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
authors = ["Hatter Jiang@Pixelbook <jht5945@gmail.com>"]
|
authors = ["Hatter Jiang@Pixelbook <jht5945@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|||||||
30
README.md
30
README.md
@@ -25,6 +25,11 @@ Enter room:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
```
|
||||||
|
.enter room-id:<roomid> client-id:<clientid>
|
||||||
|
```
|
||||||
|
|
||||||
Exit room:
|
Exit room:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -32,6 +37,11 @@ Exit room:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
```
|
||||||
|
.exit
|
||||||
|
```
|
||||||
|
|
||||||
Destroy room:
|
Destroy room:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -39,6 +49,11 @@ Destroy room:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
```
|
||||||
|
.destroy
|
||||||
|
```
|
||||||
|
|
||||||
List room peers:
|
List room peers:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -46,6 +61,11 @@ List room peers:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
```
|
||||||
|
.list-peers
|
||||||
|
```
|
||||||
|
|
||||||
Broadcast room message:
|
Broadcast room message:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -54,6 +74,11 @@ Broadcast room message:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
```
|
||||||
|
.broadcast data:<message>
|
||||||
|
```
|
||||||
|
|
||||||
Send room peer message:
|
Send room peer message:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -63,6 +88,11 @@ Send room peer message:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
```
|
||||||
|
.peer peer-id:<peerclientid> data:<message>
|
||||||
|
```
|
||||||
|
|
||||||
Test with command line:
|
Test with command line:
|
||||||
> WebSocket cat: https://www.npmjs.com/package/wscat
|
> WebSocket cat: https://www.npmjs.com/package/wscat
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ fn handle_text_message(handle_context: &mut HandleContext, tx: &Tx, addr: Socket
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let room_message = match serde_json::from_str::<RoomMessage>(&msg) {
|
let room_message = match RoomMessage::parse(&msg) {
|
||||||
Ok(room_message) => room_message,
|
Ok(room_message) => room_message,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warning!("Parse message: from: {:?} - {:?}, failed: {}", handle_context.room_id, handle_context.client_id, e);
|
warning!("Parse message: from: {:?} - {:?}, failed: {}", handle_context.room_id, handle_context.client_id, e);
|
||||||
|
|||||||
126
src/msg.rs
126
src/msg.rs
@@ -1,7 +1,9 @@
|
|||||||
|
use rust_util::XResult;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::types::{Tx, TxSendMessage};
|
use crate::types::{Tx, TxSendMessage};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub enum RoomMessageType {
|
pub enum RoomMessageType {
|
||||||
#[serde(rename = "Enter")]
|
#[serde(rename = "Enter")]
|
||||||
CreateOrEnter,
|
CreateOrEnter,
|
||||||
@@ -39,6 +41,21 @@ pub struct RoomMessage {
|
|||||||
pub data: Option<String>,
|
pub data: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RoomMessage {
|
||||||
|
pub fn parse(msg: &str) -> XResult<Self> {
|
||||||
|
if let Ok(room_message) = serde_json::from_str::<RoomMessage>(msg) {
|
||||||
|
return Ok(room_message);
|
||||||
|
}
|
||||||
|
if msg.starts_with('.') {
|
||||||
|
let msg_parts = parse_message_parts(msg);
|
||||||
|
if !msg_parts.is_empty() {
|
||||||
|
return parse_message_parts_to_room_message(&msg_parts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
simple_error!("Not valid room message.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct RoomMessageDown {
|
pub struct RoomMessageDown {
|
||||||
@@ -138,3 +155,110 @@ impl RoomMessageDown {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_message_parts_to_room_message(msg_parts: &[String]) -> XResult<RoomMessage> {
|
||||||
|
let room_message_type = get_room_message_type(&msg_parts[0])?;
|
||||||
|
let mut message_id = None;
|
||||||
|
let mut room_id = None;
|
||||||
|
let mut client_id = None;
|
||||||
|
let mut peer_id = None;
|
||||||
|
let mut data = None;
|
||||||
|
|
||||||
|
msg_parts.iter().skip(1).for_each(|part| {
|
||||||
|
let before_colon = part.chars().take_while(|c| *c != ':').collect::<String>();
|
||||||
|
let after_colon = part.chars().skip_while(|c| *c != ':').skip(1).collect::<String>();
|
||||||
|
match before_colon.as_str() {
|
||||||
|
"message_id" | "message-id" => { message_id = Some(after_colon); }
|
||||||
|
"room_id" | "room-id" => { room_id = Some(after_colon); }
|
||||||
|
"client_id" | "client-id" => { client_id = Some(after_colon); }
|
||||||
|
"peer_id" | "peer-id" => { peer_id = Some(after_colon); }
|
||||||
|
"data" => { data = Some(after_colon); }
|
||||||
|
_ => debugging!("Unknown key: {}", before_colon),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(RoomMessage {
|
||||||
|
r#type: room_message_type,
|
||||||
|
message_id,
|
||||||
|
room_id,
|
||||||
|
client_id,
|
||||||
|
peer_id,
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_room_message_type(first_part: &str) -> XResult<RoomMessageType> {
|
||||||
|
let room_message_type = match first_part {
|
||||||
|
"create-or-enter" | "enter" => RoomMessageType::CreateOrEnter,
|
||||||
|
"exit" => RoomMessageType::Exit,
|
||||||
|
"destroy" => RoomMessageType::Destroy,
|
||||||
|
"listpeers" | "list-peers" => RoomMessageType::ListPeers,
|
||||||
|
"broadcast" => RoomMessageType::Broadcast,
|
||||||
|
"peer" => RoomMessageType::Peer,
|
||||||
|
_ => return simple_error!("Unknown message type: {}", first_part),
|
||||||
|
};
|
||||||
|
Ok(room_message_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_message_parts(msg: &str) -> Vec<String> {
|
||||||
|
let mut msg_parts = vec![];
|
||||||
|
let mut in_quote = false;
|
||||||
|
let mut is_back_slash = false;
|
||||||
|
let mut last_part = vec![];
|
||||||
|
for c in msg.chars().skip(1) {
|
||||||
|
if is_back_slash {
|
||||||
|
last_part.push(c);
|
||||||
|
is_back_slash = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
match c {
|
||||||
|
' ' if in_quote => {
|
||||||
|
last_part.push(c);
|
||||||
|
}
|
||||||
|
' ' => {
|
||||||
|
if !last_part.is_empty() {
|
||||||
|
msg_parts.push(last_part.iter().collect::<String>());
|
||||||
|
last_part.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'\\' => {
|
||||||
|
is_back_slash = true;
|
||||||
|
}
|
||||||
|
'\'' => {
|
||||||
|
in_quote = !in_quote;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
last_part.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !last_part.is_empty() {
|
||||||
|
msg_parts.push(last_part.iter().collect::<String>());
|
||||||
|
}
|
||||||
|
msg_parts
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_room_message_parse() {
|
||||||
|
let room_message = RoomMessage::parse(".enter").unwrap();
|
||||||
|
assert_eq!(RoomMessageType::CreateOrEnter, room_message.r#type);
|
||||||
|
assert_eq!(None, room_message.message_id);
|
||||||
|
assert_eq!(None, room_message.room_id);
|
||||||
|
assert_eq!(None, room_message.client_id);
|
||||||
|
assert_eq!(None, room_message.peer_id);
|
||||||
|
assert_eq!(None, room_message.data);
|
||||||
|
let room_message = RoomMessage::parse(".enter message-id:123 room-id:'ROOM ID'").unwrap();
|
||||||
|
assert_eq!(RoomMessageType::CreateOrEnter, room_message.r#type);
|
||||||
|
assert_eq!(Some("123".to_string()), room_message.message_id);
|
||||||
|
assert_eq!(Some("ROOM ID".to_string()), room_message.room_id);
|
||||||
|
assert_eq!(None, room_message.client_id);
|
||||||
|
assert_eq!(None, room_message.peer_id);
|
||||||
|
assert_eq!(None, room_message.data);
|
||||||
|
let room_message = RoomMessage::parse(".peer client-id:'CLIENT ID' peer_id:PEER 'data:DATA ---'").unwrap();
|
||||||
|
assert_eq!(RoomMessageType::Peer, room_message.r#type);
|
||||||
|
assert_eq!(None, room_message.message_id);
|
||||||
|
assert_eq!(None, room_message.room_id);
|
||||||
|
assert_eq!(Some("CLIENT ID".to_string()), room_message.client_id);
|
||||||
|
assert_eq!(Some("PEER".to_string()), room_message.peer_id);
|
||||||
|
assert_eq!(Some("DATA ---".to_string()), room_message.data);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user