cargo fmt
This commit is contained in:
parent
ed11799bf5
commit
c4eece7ffd
8 changed files with 113 additions and 53 deletions
|
@ -13,11 +13,11 @@
|
|||
|
||||
use crate::room::Room;
|
||||
|
||||
use std::cmp::{PartialEq, Eq};
|
||||
use simple_websockets::{Message, Responder};
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::{Eq, PartialEq};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use simple_websockets::{Responder, Message};
|
||||
|
||||
pub struct DiscordInfo {
|
||||
pub username: String,
|
||||
|
@ -47,7 +47,9 @@ pub enum ClientInfo {
|
|||
impl ClientInfo {
|
||||
fn id(&self) -> u64 {
|
||||
match self {
|
||||
Self::Ws { id, discord_info, .. } => match discord_info {
|
||||
Self::Ws {
|
||||
id, discord_info, ..
|
||||
} => match discord_info {
|
||||
// Discord-verified websocket connection
|
||||
Some(discord_info) => discord_info.id,
|
||||
// Anonymous websocket connection
|
||||
|
@ -93,7 +95,9 @@ impl Client {
|
|||
pub fn send(&self, message: Message) -> bool {
|
||||
match &self.info {
|
||||
ClientInfo::Ws { responder, .. } => responder.send(message),
|
||||
ClientInfo::Discord { .. } => unimplemented!("no networking implementation for Discord connections"),
|
||||
ClientInfo::Discord { .. } => {
|
||||
unimplemented!("no networking implementation for Discord connections")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::word::Word;
|
||||
|
||||
use derive_more::From;
|
||||
use rusqlite::{params, Connection, Result};
|
||||
use std::path::PathBuf;
|
||||
use rusqlite::{Connection, Result, params};
|
||||
|
||||
pub struct Database {
|
||||
conn: Connection,
|
||||
|
@ -46,10 +46,11 @@ impl Database {
|
|||
.prepare("SELECT id FROM word ORDER BY id DESC LIMIT 1")?
|
||||
.query_map(params![], |row| row.get(0))?
|
||||
.collect::<Result<Vec<i64>>>()?
|
||||
.first() {
|
||||
Some(id) => *id,
|
||||
None => 0, // first database entry is id 1
|
||||
};
|
||||
.first()
|
||||
{
|
||||
Some(id) => *id,
|
||||
None => 0, // first database entry is id 1
|
||||
};
|
||||
Ok(Self { conn, last_word_id })
|
||||
}
|
||||
|
||||
|
@ -70,10 +71,7 @@ impl Database {
|
|||
pub fn add_word(&mut self, word: &Word) -> Result<()> {
|
||||
self.conn.execute(
|
||||
"INSERT INTO word (word, reading) VALUES (?1, ?2)",
|
||||
params![
|
||||
word.word,
|
||||
word.reading,
|
||||
],
|
||||
params![word.word, word.reading,],
|
||||
)?;
|
||||
self.last_word_id += 1;
|
||||
Ok(())
|
||||
|
|
|
@ -2,7 +2,8 @@ use wana_kana::{ConvertJapanese, IsJapaneseStr};
|
|||
|
||||
fn raw_lookup(input: &str) -> Option<&jisho::Entry> {
|
||||
let input = input.trim();
|
||||
jisho::lookup(input).into_iter().find(|&word| (
|
||||
jisho::lookup(input).into_iter().find(|&word| {
|
||||
(
|
||||
// If input has no kanji,
|
||||
// we can just compare the input to the reading verbatim
|
||||
// ensuring both are hiragana
|
||||
|
@ -11,7 +12,9 @@ fn raw_lookup(input: &str) -> Option<&jisho::Entry> {
|
|||
// is verbosely the same.
|
||||
// However, this will cause problems for some words.
|
||||
// For example, 照り焼き will be accepted but 照焼 won't.
|
||||
(input == word.kanji)))
|
||||
(input == word.kanji)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lookup(query: &str) -> Option<jisho::Entry> {
|
||||
|
|
|
@ -11,7 +11,11 @@ use crate::server::{Server, ServerSettings};
|
|||
|
||||
fn main() {
|
||||
let settings = ServerSettings::default();
|
||||
let mut server = Server::new(&settings)
|
||||
.unwrap_or_else(|error| panic!("Failed to start server at port {}: {:?}", settings.port, error));
|
||||
let mut server = Server::new(&settings).unwrap_or_else(|error| {
|
||||
panic!(
|
||||
"Failed to start server at port {}: {:?}",
|
||||
settings.port, error
|
||||
)
|
||||
});
|
||||
server.run();
|
||||
}
|
||||
|
|
27
src/room.rs
27
src/room.rs
|
@ -11,10 +11,10 @@
|
|||
use crate::database::{Database, DatabaseCreationError, DatabaseSettings};
|
||||
use crate::dictionary::lookup;
|
||||
use crate::response::MessageResponseData;
|
||||
use crate::utils::{get_starting_mora, get_final_mora};
|
||||
use crate::utils::{get_final_mora, get_starting_mora};
|
||||
use crate::word::Word;
|
||||
|
||||
use wana_kana::{IsJapaneseStr, ConvertJapanese};
|
||||
use wana_kana::{ConvertJapanese, IsJapaneseStr};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RoomSettings {
|
||||
|
@ -41,11 +41,16 @@ impl Room {
|
|||
}
|
||||
|
||||
pub fn get_history(&self) -> rusqlite::Result<Vec<Word>> {
|
||||
self.database.load_words_before(self.database.last_word_id + 1)
|
||||
self.database
|
||||
.load_words_before(self.database.last_word_id + 1)
|
||||
}
|
||||
|
||||
// Err(&str) will be converted to MessageResponseData::Error
|
||||
pub fn handle_query(&mut self, query: &str, client_id: u64) -> Result<MessageResponseData, &str> {
|
||||
pub fn handle_query(
|
||||
&mut self,
|
||||
query: &str,
|
||||
client_id: u64,
|
||||
) -> Result<MessageResponseData, &str> {
|
||||
// Ensure query isn't from last player
|
||||
if Some(client_id) == self.last_client_id {
|
||||
return Err("It's not your turn!");
|
||||
|
@ -70,9 +75,19 @@ impl Room {
|
|||
// Send result
|
||||
match dictionary_result {
|
||||
Some(entry) => {
|
||||
if entry.reading.chars().last().unwrap().to_string().to_hiragana() == "ん" {
|
||||
if entry
|
||||
.reading
|
||||
.chars()
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.to_hiragana()
|
||||
== "ん"
|
||||
{
|
||||
Err("Can't end with ん!")
|
||||
} else if self.next_mora.is_none() || get_starting_mora(&entry.reading).eq(self.next_mora.as_deref().unwrap()) {
|
||||
} else if self.next_mora.is_none()
|
||||
|| get_starting_mora(&entry.reading).eq(self.next_mora.as_deref().unwrap())
|
||||
{
|
||||
let word: Word = entry.clone().into();
|
||||
self.next_mora = Some(get_final_mora(&word.reading));
|
||||
self.database.add_word(&word).unwrap(); // TODO: replace .unwrap() with ?
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use crate::client::{Client, ClientInfo};
|
||||
use crate::database::{DatabaseSettings, DatabaseType, DatabaseCreationError};
|
||||
use crate::database::{DatabaseCreationError, DatabaseSettings, DatabaseType};
|
||||
use crate::response::MessageResponseData;
|
||||
use crate::room::{Room, RoomSettings};
|
||||
|
||||
use derive_more::From;
|
||||
use simple_websockets::{Event, EventHub, Message, Responder};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use simple_websockets::{Event, Responder, Message, EventHub};
|
||||
use derive_more::From;
|
||||
|
||||
#[derive(From, Debug)]
|
||||
pub enum ServerCreationError {
|
||||
|
@ -66,27 +66,36 @@ impl Server {
|
|||
pub fn run(&mut self) {
|
||||
loop {
|
||||
match match self.event_hub.poll_event() {
|
||||
Event::Connect(client_id, responder) => self.handle_connection(client_id, responder),
|
||||
Event::Connect(client_id, responder) => {
|
||||
self.handle_connection(client_id, responder)
|
||||
}
|
||||
Event::Disconnect(client_id) => self.handle_disconnection(client_id),
|
||||
Event::Message(client_id, message) => self.handle_message(client_id, message),
|
||||
} {
|
||||
Ok(()) => {},
|
||||
Ok(()) => {}
|
||||
Err(error) => println!("{:?}", error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn new_client(&mut self, client_id: u64, responder: Responder) -> &Client {
|
||||
let client = Client::new(ClientInfo::Ws {
|
||||
id: client_id,
|
||||
responder,
|
||||
discord_info: None,
|
||||
}, self.lobby.clone());
|
||||
let client = Client::new(
|
||||
ClientInfo::Ws {
|
||||
id: client_id,
|
||||
responder,
|
||||
discord_info: None,
|
||||
},
|
||||
self.lobby.clone(),
|
||||
);
|
||||
self.clients.insert(client_id, client);
|
||||
self.clients.get(&client_id).unwrap()
|
||||
}
|
||||
|
||||
fn handle_connection(&mut self, client_id: u64, responder: Responder) -> Result<(), ServerError> {
|
||||
fn handle_connection(
|
||||
&mut self,
|
||||
client_id: u64,
|
||||
responder: Responder,
|
||||
) -> Result<(), ServerError> {
|
||||
// Debug
|
||||
println!("A client connected with id #{}", client_id);
|
||||
|
||||
|
@ -98,15 +107,21 @@ impl Server {
|
|||
let room = client.room.borrow();
|
||||
|
||||
// Send client greeting
|
||||
client.send(MessageResponseData::Greeting {
|
||||
id: client_id,
|
||||
next_mora: room.next_mora().clone(),
|
||||
}.into_message());
|
||||
client.send(
|
||||
MessageResponseData::Greeting {
|
||||
id: client_id,
|
||||
next_mora: room.next_mora().clone(),
|
||||
}
|
||||
.into_message(),
|
||||
);
|
||||
|
||||
// Sent recent message history
|
||||
client.send(MessageResponseData::History {
|
||||
words: room.get_history()?,
|
||||
}.into_message());
|
||||
client.send(
|
||||
MessageResponseData::History {
|
||||
words: room.get_history()?,
|
||||
}
|
||||
.into_message(),
|
||||
);
|
||||
}
|
||||
|
||||
// Number of clients on Rc<RefCell<Room>> reference counter will be one more
|
||||
|
@ -133,7 +148,11 @@ impl Server {
|
|||
}
|
||||
|
||||
fn for_client_in_room(&self, room: &Rc<RefCell<Room>>, mut closure: impl FnMut(&Client) -> ()) {
|
||||
for (_id, client) in self.clients.iter().filter(|(_id, client)| Rc::<RefCell<Room>>::ptr_eq(room, &client.room)) {
|
||||
for (_id, client) in self
|
||||
.clients
|
||||
.iter()
|
||||
.filter(|(_id, client)| Rc::<RefCell<Room>>::ptr_eq(room, &client.room))
|
||||
{
|
||||
closure(client);
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +164,10 @@ impl Server {
|
|||
}
|
||||
|
||||
fn broadcast_player_count(&self, room: &Rc<RefCell<Room>>) {
|
||||
let response = MessageResponseData::PlayerCount { players: self.client_count_in_room(room) as u64 }.into_response();
|
||||
let response = MessageResponseData::PlayerCount {
|
||||
players: self.client_count_in_room(room) as u64,
|
||||
}
|
||||
.into_response();
|
||||
for (_id, client) in self.clients.iter() {
|
||||
client.send(response.to_message());
|
||||
}
|
||||
|
@ -163,13 +185,19 @@ impl Server {
|
|||
let message = match message {
|
||||
Message::Text(message) => {
|
||||
// Debug
|
||||
println!("Received a message from client #{}: {:?}", client_id, message);
|
||||
println!(
|
||||
"Received a message from client #{}: {:?}",
|
||||
client_id, message
|
||||
);
|
||||
|
||||
message
|
||||
}
|
||||
Message::Binary(message) => {
|
||||
// Debug
|
||||
println!("Received a binary message from client #{}: {:?}", client_id, message);
|
||||
println!(
|
||||
"Received a binary message from client #{}: {:?}",
|
||||
client_id, message
|
||||
);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -182,7 +210,12 @@ impl Server {
|
|||
Ok(response) => self.announce_to_room(&client.room, response),
|
||||
// Send errors to only this client
|
||||
Err(message) => {
|
||||
client.send(MessageResponseData::Error { message: message.to_string() }.into_message());
|
||||
client.send(
|
||||
MessageResponseData::Error {
|
||||
message: message.to_string(),
|
||||
}
|
||||
.into_message(),
|
||||
);
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
|
|
11
src/utils.rs
11
src/utils.rs
|
@ -38,10 +38,13 @@ pub fn get_final_mora(word: &str) -> String {
|
|||
let mut iter = word.chars().rev();
|
||||
let final_char = iter.next().unwrap();
|
||||
match final_char {
|
||||
'ゃ' | 'ゅ' | 'ょ' => format!("{}{final_char}", match iter.next() {
|
||||
Some(c) => c.to_string(),
|
||||
None => String::from(""),
|
||||
}),
|
||||
'ゃ' | 'ゅ' | 'ょ' => format!(
|
||||
"{}{final_char}",
|
||||
match iter.next() {
|
||||
Some(c) => c.to_string(),
|
||||
None => String::from(""),
|
||||
}
|
||||
),
|
||||
_ => final_char.to_string(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use serde::Serialize;
|
||||
use jisho::Entry;
|
||||
use serde::Serialize;
|
||||
use std::convert::From;
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
|
Loading…
Add table
Reference in a new issue