Skip to content

Commit 869adbd

Browse files
committed
Update for 2nd edition.
1 parent 1379c1e commit 869adbd

File tree

9 files changed

+696
-64
lines changed

9 files changed

+696
-64
lines changed

Cargo.lock

Lines changed: 647 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ edition = "2018"
66

77
[dependencies]
88
async-std = { version = "1.7", features = ["unstable"] }
9-
tokio = { version = "0.3", features = ["sync"] }
9+
tokio = { version = "1.0", features = ["sync"] }
1010
serde = { version = "1.0", features = ["derive", "rc"] }
1111
serde_json = "1.0"

src/bin/client.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//# send-commands
21
use async_std::prelude::*;
32
use async_chat::utils::{self, ChatResult};
43
use async_std::io;
@@ -12,8 +11,9 @@ async fn send_commands(mut to_server: net::TcpStream) -> ChatResult<()> {
1211
to close the connection.");
1312

1413
let mut command_lines = io::BufReader::new(io::stdin()).lines();
15-
while let Some(command) = command_lines.next().await {
16-
let command = command?;
14+
while let Some(command_result) = command_lines.next().await {
15+
let command = command_result?;
16+
// See the GitHub repo for the definition of `parse_command`.
1717
let request = match parse_command(&command) {
1818
Some(request) => request,
1919
None => continue,
@@ -25,9 +25,7 @@ async fn send_commands(mut to_server: net::TcpStream) -> ChatResult<()> {
2525

2626
Ok(())
2727
}
28-
//#end
2928

30-
//# client-handle-replies
3129
use async_chat::FromServer;
3230

3331
async fn handle_replies(from_server: net::TcpStream) -> ChatResult<()> {
@@ -47,9 +45,7 @@ async fn handle_replies(from_server: net::TcpStream) -> ChatResult<()> {
4745

4846
Ok(())
4947
}
50-
//# end
5148

52-
//# client-main
5349
use async_std::task;
5450

5551
fn main() -> ChatResult<()> {
@@ -68,7 +64,6 @@ fn main() -> ChatResult<()> {
6864
Ok(())
6965
})
7066
}
71-
//# end
7267

7368
use async_chat::FromClient;
7469
use std::sync::Arc;

src/bin/server/connection.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/// Handle a single client's connection.
22
3-
//# chat-serve
43
use async_chat::{FromClient, FromServer};
54
use async_chat::utils::{self, ChatResult};
65
use async_std::prelude::*;
@@ -17,8 +16,8 @@ pub async fn serve(socket: TcpStream, groups: Arc<GroupTable>)
1716

1817
let buffered = BufReader::new(socket);
1918
let mut from_client = utils::receive_as_json(buffered);
20-
while let Some(request) = from_client.next().await {
21-
let request = request?;
19+
while let Some(request_result) = from_client.next().await {
20+
let request = request_result?;
2221

2322
let result = match request {
2423
FromClient::Join { group_name } => {
@@ -48,9 +47,7 @@ pub async fn serve(socket: TcpStream, groups: Arc<GroupTable>)
4847

4948
Ok(())
5049
}
51-
//# end
5250

53-
//# chat-Outbound
5451
use async_std::sync::Mutex;
5552

5653
pub struct Outbound(Mutex<TcpStream>);
@@ -67,4 +64,3 @@ impl Outbound {
6764
Ok(())
6865
}
6966
}
70-
//# end

src/bin/server/group.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! A chat group.
22
3-
//# group-type
43
use async_std::task;
54
use crate::connection::Outbound;
65
use std::sync::Arc;
@@ -33,9 +32,7 @@ impl Group {
3332
let _ignored = self.sender.send(message);
3433
}
3534
}
36-
//# end
3735

38-
//# handle_subscriber
3936
use async_chat::FromServer;
4037
use tokio::sync::broadcast::error::RecvError;
4138

@@ -62,4 +59,3 @@ async fn handle_subscriber(group_name: Arc<String>,
6259
}
6360
}
6461
}
65-
//# end

src/bin/server/group_table.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//# group-table
21
use crate::group::Group;
32
use std::collections::HashMap;
43
use std::sync::{Arc, Mutex};
@@ -25,5 +24,4 @@ impl GroupTable {
2524
.clone()
2625
}
2726
}
28-
//# end
2927

src/bin/server/main.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,43 @@
11
//! Asynchronous chat server.
2+
#![warn(rust_2018_idioms)]
3+
#![allow(elided_lifetimes_in_paths)]
24

3-
//# server-main
45
use async_std::prelude::*;
5-
use async_std::{net, task};
66
use async_chat::utils::ChatResult;
77
use std::sync::Arc;
88

99
mod connection;
1010
mod group;
1111
mod group_table;
1212

13+
use connection::serve;
14+
1315
fn main() -> ChatResult<()> {
1416
let address = std::env::args().nth(1).expect("Usage: server ADDRESS");
1517

16-
let groups = Arc::new(group_table::GroupTable::new());
18+
let chat_group_table = Arc::new(group_table::GroupTable::new());
19+
20+
async_std::task::block_on(async {
21+
// This code was shown in the chapter introduction.
22+
use async_std::{net, task};
1723

18-
task::block_on(async {
1924
let listener = net::TcpListener::bind(address).await?;
2025

2126
let mut new_connections = listener.incoming();
22-
loop {
23-
let socket = new_connections.next().await.unwrap()?;
24-
let groups = groups.clone();
27+
while let Some(socket_result) = new_connections.next().await {
28+
let socket = socket_result?;
29+
let groups = chat_group_table.clone();
2530
task::spawn(async {
26-
if let Err(error) = connection::serve(socket, groups).await {
27-
eprintln!("Error: {}", error);
28-
}
31+
log_error(serve(socket, groups).await);
2932
});
3033
}
34+
35+
Ok(())
3136
})
3237
}
33-
//# end
38+
39+
fn log_error(result: ChatResult<()>) {
40+
if let Err(error) = result {
41+
eprintln!("Error: {}", error);
42+
}
43+
}

src/lib.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
pub mod utils;
2-
3-
//# request-and-reply
1+
#![warn(rust_2018_idioms)]
2+
#![allow(elided_lifetimes_in_paths)]
43
use serde::{Deserialize, Serialize};
54
use std::sync::Arc;
65

6+
pub mod utils;
7+
78
#[derive(Debug, Deserialize, Serialize, PartialEq)]
89
pub enum FromClient {
910
Join { group_name: Arc<String> },
@@ -21,4 +22,21 @@ pub enum FromServer {
2122
},
2223
Error(String),
2324
}
24-
//# end
25+
26+
27+
#[test]
28+
fn test_fromclient_json() {
29+
use std::sync::Arc;
30+
31+
let from_client = FromClient::Post {
32+
group_name: Arc::new("Dogs".to_string()),
33+
message: Arc::new("Samoyeds rock!".to_string()),
34+
};
35+
36+
let json = serde_json::to_string(&from_client).unwrap();
37+
assert_eq!(json,
38+
r#"{"Post":{"group_name":"Dogs","message":"Samoyeds rock!"}}"#);
39+
40+
assert_eq!(serde_json::from_str::<FromClient>(&json).unwrap(),
41+
from_client);
42+
}

src/utils.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
//! Utilities for both clients and servers.
22
3-
//# ChatResult
43
use std::error::Error;
54

65
pub type ChatError = Box<dyn Error + Send + Sync + 'static>;
76
pub type ChatResult<T> = Result<T, ChatError>;
8-
//# end
97

10-
//# send-as-json
118
use async_std::prelude::*;
129
use serde::Serialize;
1310
use std::marker::Unpin;
@@ -22,9 +19,7 @@ where
2219
outbound.write_all(json.as_bytes()).await?;
2320
Ok(())
2421
}
25-
//# end
2622

27-
//# receive_as_json
2823
use serde::de::DeserializeOwned;
2924

3025
pub fn receive_as_json<S, P>(inbound: S) -> impl Stream<Item = ChatResult<P>>
@@ -38,26 +33,3 @@ pub fn receive_as_json<S, P>(inbound: S) -> impl Stream<Item = ChatResult<P>>
3833
Ok(parsed)
3934
})
4035
}
41-
//# end
42-
43-
#[test]
44-
fn test_fromclient_json() -> ChatResult<()> {
45-
use std::sync::Arc;
46-
use super::FromClient;
47-
48-
//# serialization
49-
let from_client = FromClient::Post {
50-
group_name: Arc::new("Dogs".to_string()),
51-
message: Arc::new("Samoyeds rock!".to_string()),
52-
};
53-
54-
let json = serde_json::to_string(&from_client)?;
55-
assert_eq!(json,
56-
r#"{"Post":{"group_name":"Dogs","message":"Samoyeds rock!"}}"#);
57-
58-
assert_eq!(serde_json::from_str::<FromClient>(&json)?,
59-
from_client);
60-
//# end
61-
62-
Ok(())
63-
}

0 commit comments

Comments
 (0)