1 use std::{ |
1 use std::{ |
2 fs::{File, OpenOptions}, |
2 fs::{File, OpenOptions}, |
3 io::{Error, ErrorKind, Read, Result, Write}, |
3 io::{Error, ErrorKind, Read, Result, Write}, |
|
4 sync::mpsc, |
|
5 thread, |
4 }; |
6 }; |
5 |
7 |
6 pub trait HWServerIO { |
8 use crate::server::{ |
7 fn write_file(&mut self, name: &str, content: &str) -> Result<()>; |
9 database::Database, |
8 fn read_file(&mut self, name: &str) -> Result<String>; |
10 handlers::{IoResult, IoTask}, |
|
11 }; |
|
12 use mio::{Evented, Poll, PollOpt}; |
|
13 use mio_extras::channel; |
|
14 |
|
15 pub type RequestId = u32; |
|
16 |
|
17 pub struct IOThread { |
|
18 core_tx: mpsc::Sender<(RequestId, IoTask)>, |
|
19 core_rx: channel::Receiver<(RequestId, IoResult)>, |
9 } |
20 } |
10 |
21 |
11 pub struct EmptyServerIO {} |
22 impl IOThread { |
|
23 pub fn new() -> Self { |
|
24 let (core_tx, io_rx) = mpsc::channel(); |
|
25 let (io_tx, core_rx) = channel::channel(); |
12 |
26 |
13 impl EmptyServerIO { |
27 let mut db = Database::new(); |
14 pub fn new() -> Self { |
28 db.connect("localhost"); |
15 Self {} |
29 |
|
30 thread::spawn(move || { |
|
31 while let Ok((request_id, task)) = io_rx.try_recv() { |
|
32 match task { |
|
33 IoTask::GetAccount { |
|
34 nick, |
|
35 protocol, |
|
36 password_hash, |
|
37 client_salt, |
|
38 server_salt, |
|
39 } => { |
|
40 if let Ok(account) = db.get_account( |
|
41 &nick, |
|
42 protocol, |
|
43 &password_hash, |
|
44 &client_salt, |
|
45 &server_salt, |
|
46 ) { |
|
47 io_tx.send((request_id, IoResult::Account(account))); |
|
48 } |
|
49 } |
|
50 } |
|
51 } |
|
52 }); |
|
53 |
|
54 Self { core_rx, core_tx } |
|
55 } |
|
56 |
|
57 pub fn send(&self, request_id: RequestId, task: IoTask) { |
|
58 self.core_tx.send((request_id, task)).unwrap(); |
|
59 } |
|
60 |
|
61 pub fn try_recv(&self) -> Option<(RequestId, IoResult)> { |
|
62 match self.core_rx.try_recv() { |
|
63 Ok(result) => Some(result), |
|
64 Err(mpsc::TryRecvError::Empty) => None, |
|
65 Err(mpsc::TryRecvError::Disconnected) => unreachable!(), |
|
66 } |
|
67 } |
|
68 |
|
69 pub fn register_rx(&self, poll: &mio::Poll, token: mio::Token) -> Result<()> { |
|
70 self.core_rx |
|
71 .register(poll, token, mio::Ready::readable(), PollOpt::edge()) |
16 } |
72 } |
17 } |
73 } |
18 |
|
19 impl HWServerIO for EmptyServerIO { |
|
20 fn write_file(&mut self, _name: &str, _content: &str) -> Result<()> { |
|
21 Ok(()) |
|
22 } |
|
23 |
|
24 fn read_file(&mut self, _name: &str) -> Result<String> { |
|
25 Ok("".to_string()) |
|
26 } |
|
27 } |
|
28 |
|
29 pub struct FileServerIO {} |
|
30 |
|
31 impl FileServerIO { |
|
32 pub fn new() -> Self { |
|
33 Self {} |
|
34 } |
|
35 } |
|
36 |
|
37 impl HWServerIO for FileServerIO { |
|
38 fn write_file(&mut self, name: &str, content: &str) -> Result<()> { |
|
39 let mut writer = OpenOptions::new().create(true).write(true).open(name)?; |
|
40 writer.write_all(content.as_bytes()) |
|
41 } |
|
42 |
|
43 fn read_file(&mut self, name: &str) -> Result<String> { |
|
44 let mut reader = File::open(name)?; |
|
45 let mut result = String::new(); |
|
46 reader.read_to_string(&mut result)?; |
|
47 Ok(result) |
|
48 } |
|
49 } |
|