├── Ch06
├── hello-wasm
│ ├── .cargo-ok
│ ├── client
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── .travis.yml
│ │ ├── bootstrap.js
│ │ ├── index.html
│ │ ├── webpack.config.js
│ │ ├── .bin
│ │ │ └── create-wasm-app.js
│ │ ├── package.json
│ │ ├── LICENSE-MIT
│ │ ├── README.md
│ │ └── LICENSE-APACHE
│ ├── .gitignore
│ ├── tests
│ │ └── web.rs
│ ├── .appveyor.yml
│ ├── src
│ │ ├── lib.rs
│ │ └── utils.rs
│ ├── Cargo.toml
│ ├── LICENSE_MIT
│ ├── README.md
│ ├── .travis.yml
│ └── LICENSE_APACHE
├── wasm-image-processing
│ ├── .cargo-ok
│ ├── client
│ │ ├── .gitignore
│ │ ├── .travis.yml
│ │ ├── bootstrap.js
│ │ ├── webpack.config.js
│ │ ├── index.html
│ │ ├── .bin
│ │ │ └── create-wasm-app.js
│ │ ├── package.json
│ │ ├── LICENSE-MIT
│ │ ├── index.js
│ │ ├── README.md
│ │ └── LICENSE-APACHE
│ ├── .gitignore
│ ├── tests
│ │ └── web.rs
│ ├── .appveyor.yml
│ ├── src
│ │ ├── utils.rs
│ │ └── lib.rs
│ ├── LICENSE_MIT
│ ├── Cargo.toml
│ ├── README.md
│ ├── .travis.yml
│ └── LICENSE_APACHE
└── yew-image-processing
│ ├── .cargo-ok
│ ├── static
│ ├── style.scss
│ └── index.html
│ ├── .gitignore
│ ├── bootstrap.js
│ ├── netlify
│ ├── todomvc.wasm
│ ├── index.html
│ └── todomvc.js
│ ├── tests
│ └── web.rs
│ ├── .github
│ └── workflows
│ │ ├── check.yml
│ │ └── deploy.yml
│ ├── src
│ ├── lib.rs
│ └── app.rs
│ ├── package.json
│ ├── README.md
│ ├── Cargo.toml
│ ├── LICENSE_MIT
│ ├── webpack.config.js
│ └── LICENSE_APACHE
├── Ch02
├── catdex
│ ├── 3
│ ├── migrations
│ │ ├── .gitkeep
│ │ ├── 2020-05-26-192813_create_cats
│ │ │ ├── down.sql
│ │ │ └── up.sql
│ │ └── 00000000000000_diesel_initial_setup
│ │ │ ├── down.sql
│ │ │ └── up.sql
│ ├── .gitignore
│ ├── static
│ │ ├── image
│ │ │ ├── persian.jpg
│ │ │ ├── ragdoll.jpg
│ │ │ ├── Selection_224.png
│ │ │ ├── extreme_origami.pdf
│ │ │ └── british-short-hair.jpg
│ │ ├── css
│ │ │ └── index.css
│ │ ├── cat.html
│ │ ├── add.html
│ │ └── index.html
│ ├── src
│ │ ├── schema.rs
│ │ ├── models.rs
│ │ └── main.rs
│ ├── diesel.toml
│ ├── start_database.sh
│ └── Cargo.toml
└── hello-world
│ ├── .gitignore
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── Ch03
└── rest_api
│ └── catdex
│ ├── .gitignore
│ ├── migrations
│ ├── .gitkeep
│ ├── 2020-05-26-192813_create_cats
│ │ ├── down.sql
│ │ └── up.sql
│ └── 00000000000000_diesel_initial_setup
│ │ ├── down.sql
│ │ └── up.sql
│ ├── static
│ ├── css
│ │ ├── cat.css
│ │ └── index.css
│ ├── image
│ │ ├── persian.jpg
│ │ ├── ragdoll.jpg
│ │ ├── Selection_224.png
│ │ └── british-short-hair.jpg
│ ├── add.html
│ ├── cat.html
│ └── index.html
│ ├── src
│ ├── schema.rs
│ ├── models.rs
│ ├── errors.rs
│ └── main.rs
│ ├── diesel.toml
│ ├── create_cert.sh
│ ├── start_database.sh
│ └── Cargo.toml
├── Ch05
├── serverless-catdex
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── package.json
│ ├── client
│ │ └── dist
│ │ │ ├── css
│ │ │ └── index.css
│ │ │ ├── index.html
│ │ │ └── add.html
│ ├── cats
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── main.rs
│ ├── cat_post
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── main.rs
│ ├── .github
│ │ └── workflows
│ │ │ └── main.yml
│ ├── serverless.yml
│ └── README.md
└── serverless-hello-world
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── .gitattributes
├── 9781484265888.jpg
├── Ch04
└── websocket
│ ├── pre-commit
│ ├── client
│ ├── index.html
│ ├── index.js
│ ├── chat.js
│ ├── chat.html
│ └── json_chat.html
│ ├── examples
│ ├── echo_server.rs
│ ├── chat_server.rs
│ ├── push_notification.rs
│ ├── unresponsive_client.rs
│ ├── broadcast_client.rs
│ ├── json_chat_server.rs
│ ├── 5_sec_ping_timer.rs
│ ├── unresponsive_timer.rs
│ └── broadcast.rs
│ └── Cargo.toml
├── errata.md
├── README.md
├── Contributing.md
└── LICENSE.txt
/Ch06/hello-wasm/.cargo-ok:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Ch02/catdex/migrations/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Ch02/catdex/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/.cargo-ok:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/.cargo-ok:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Ch02/hello-world/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/migrations/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/client/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 |
--------------------------------------------------------------------------------
/Ch05/serverless-catdex/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | target
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/client/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/Ch05/serverless-catdex/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = ["cats", "cat_post"]
3 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/client/index.js:
--------------------------------------------------------------------------------
1 | import * as wasm from "hello-wasm";
2 |
3 | wasm.greet();
4 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/static/css/cat.css:
--------------------------------------------------------------------------------
1 | img {
2 | max-width: 90vw;
3 | max-height: 80vh;
4 | }
5 |
--------------------------------------------------------------------------------
/9781484265888.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/9781484265888.jpg
--------------------------------------------------------------------------------
/Ch06/hello-wasm/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | **/*.rs.bk
3 | Cargo.lock
4 | bin/
5 | pkg/
6 | wasm-pack.log
7 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | **/*.rs.bk
3 | Cargo.lock
4 | bin/
5 | pkg/
6 | wasm-pack.log
7 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/static/style.scss:
--------------------------------------------------------------------------------
1 | $background: #f5f5f5;
2 |
3 | body {
4 | background: $background;
5 | }
6 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/client/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: "10"
3 |
4 | script:
5 | - ./node_modules/.bin/webpack
6 |
--------------------------------------------------------------------------------
/Ch02/catdex/migrations/2020-05-26-192813_create_cats/down.sql:
--------------------------------------------------------------------------------
1 | -- This file should undo anything in `up.sql`
2 | DROP TABLE cats
3 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/client/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: "10"
3 |
4 | script:
5 | - ./node_modules/.bin/webpack
6 |
--------------------------------------------------------------------------------
/Ch02/catdex/static/image/persian.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch02/catdex/static/image/persian.jpg
--------------------------------------------------------------------------------
/Ch02/catdex/static/image/ragdoll.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch02/catdex/static/image/ragdoll.jpg
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/migrations/2020-05-26-192813_create_cats/down.sql:
--------------------------------------------------------------------------------
1 | -- This file should undo anything in `up.sql`
2 | DROP TABLE cats
3 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | **/*.rs.bk
3 | Cargo.lock
4 | bin/
5 | pkg/
6 | dist/
7 | wasm-pack.log
8 | node_modules
9 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/bootstrap.js:
--------------------------------------------------------------------------------
1 | import './static/style.scss';
2 |
3 | import("./pkg").then(module => {
4 | module.run_app();
5 | });
6 |
--------------------------------------------------------------------------------
/Ch02/catdex/static/image/Selection_224.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch02/catdex/static/image/Selection_224.png
--------------------------------------------------------------------------------
/Ch02/catdex/static/image/extreme_origami.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch02/catdex/static/image/extreme_origami.pdf
--------------------------------------------------------------------------------
/Ch04/websocket/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | echo "Running pre-commit checks..."
3 | cargo fmt
4 | # find . -name main.rs | xargs rustfmt --check
5 |
--------------------------------------------------------------------------------
/Ch02/catdex/src/schema.rs:
--------------------------------------------------------------------------------
1 | table! {
2 | cats (id) {
3 | id -> Int4,
4 | name -> Varchar,
5 | image_path -> Varchar,
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/static/image/persian.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch03/rest_api/catdex/static/image/persian.jpg
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/static/image/ragdoll.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch03/rest_api/catdex/static/image/ragdoll.jpg
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/netlify/todomvc.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch06/yew-image-processing/netlify/todomvc.wasm
--------------------------------------------------------------------------------
/Ch02/catdex/static/image/british-short-hair.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch02/catdex/static/image/british-short-hair.jpg
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/src/schema.rs:
--------------------------------------------------------------------------------
1 | table! {
2 | cats (id) {
3 | id -> Int4,
4 | name -> Varchar,
5 | image_path -> Varchar,
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/static/image/Selection_224.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch03/rest_api/catdex/static/image/Selection_224.png
--------------------------------------------------------------------------------
/Ch02/catdex/diesel.toml:
--------------------------------------------------------------------------------
1 | # For documentation on how to configure this file,
2 | # see diesel.rs/guides/configuring-diesel-cli
3 |
4 | [print_schema]
5 | file = "src/schema.rs"
6 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/static/image/british-short-hair.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/practical-rust-web-projects/HEAD/Ch03/rest_api/catdex/static/image/british-short-hair.jpg
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/diesel.toml:
--------------------------------------------------------------------------------
1 | # For documentation on how to configure this file,
2 | # see diesel.rs/guides/configuring-diesel-cli
3 |
4 | [print_schema]
5 | file = "src/schema.rs"
6 |
--------------------------------------------------------------------------------
/Ch02/catdex/migrations/2020-05-26-192813_create_cats/up.sql:
--------------------------------------------------------------------------------
1 | -- Your SQL goes here
2 | CREATE TABLE cats (
3 | id SERIAL PRIMARY KEY,
4 | name VARCHAR NOT NULL,
5 | image_path VARCHAR NOT NULL
6 | )
7 |
--------------------------------------------------------------------------------
/Ch04/websocket/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/migrations/2020-05-26-192813_create_cats/up.sql:
--------------------------------------------------------------------------------
1 | -- Your SQL goes here
2 | CREATE TABLE cats (
3 | id SERIAL PRIMARY KEY,
4 | name VARCHAR NOT NULL,
5 | image_path VARCHAR NOT NULL
6 | )
7 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/create_cert.sh:
--------------------------------------------------------------------------------
1 | openssl req -x509 -newkey rsa:4096 \
2 | -keyout key.pem \
3 | -out cert.pem \
4 | -days 365 \
5 | -sha256 \
6 | -subj "/CN=localhost"
7 |
8 | openssl rsa -in key.pem -out key-no-password.pem
9 |
--------------------------------------------------------------------------------
/Ch05/serverless-catdex/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "serverless": "^1.74.1",
4 | "serverless-rust": "^0.3.8"
5 | },
6 | "name": "serverless-catdex",
7 | "dependencies": {
8 | "serverless-finch": "^2.6.0"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Ch04/websocket/examples/echo_server.rs:
--------------------------------------------------------------------------------
1 | extern crate ws;
2 |
3 | fn main() {
4 | ws::listen("127.0.0.1:8080", |out| {
5 | move |msg| {
6 | println!("Received message: {}", msg);
7 | out.send(msg)
8 | }
9 | })
10 | .unwrap()
11 | }
12 |
--------------------------------------------------------------------------------
/Ch02/catdex/static/css/index.css:
--------------------------------------------------------------------------------
1 | .cats {
2 | display: flex;
3 | }
4 |
5 | .cat {
6 | border: 1px solid grey;
7 | min-width: 200px;
8 | min-height: 350px;
9 | margin: 5px;
10 | padding: 5px;
11 | text-align: center;
12 | }
13 |
14 | .cat > img {
15 | width: 190px;
16 | }
17 |
--------------------------------------------------------------------------------
/Ch04/websocket/examples/chat_server.rs:
--------------------------------------------------------------------------------
1 | extern crate ws;
2 |
3 | fn main() {
4 | ws::listen("127.0.0.1:8080", |out| {
5 | move |msg| {
6 | println!("Received message: {}", msg);
7 | out.broadcast(msg)
8 | }
9 | })
10 | .unwrap()
11 | }
12 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Yew • TodoMVC
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/static/css/index.css:
--------------------------------------------------------------------------------
1 | .cats {
2 | display: flex;
3 | }
4 |
5 | .cat {
6 | border: 1px solid grey;
7 | min-width: 200px;
8 | min-height: 350px;
9 | margin: 5px;
10 | padding: 5px;
11 | text-align: center;
12 | }
13 |
14 | .cat > img {
15 | width: 190px;
16 | }
17 |
--------------------------------------------------------------------------------
/errata.md:
--------------------------------------------------------------------------------
1 | # Errata for *Practical Rust Web Projects*
2 |
3 | On **page xx** [Summary of error]:
4 |
5 | Details of error here. Highlight key pieces in **bold**.
6 |
7 | ***
8 |
9 | On **page xx** [Summary of error]:
10 |
11 | Details of error here. Highlight key pieces in **bold**.
12 |
13 | ***
--------------------------------------------------------------------------------
/Ch05/serverless-catdex/client/dist/css/index.css:
--------------------------------------------------------------------------------
1 | .cats {
2 | display: flex;
3 | }
4 |
5 | .cat {
6 | border: 1px solid grey;
7 | min-width: 200px;
8 | min-height: 350px;
9 | margin: 5px;
10 | padding: 5px;
11 | text-align: center;
12 | }
13 |
14 | .cat > img {
15 | width: 190px;
16 | }
17 |
--------------------------------------------------------------------------------
/Ch02/hello-world/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "hello-world"
3 | version = "0.1.0"
4 | authors = ["Shing Lyu "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | actix-web = "3"
11 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/client/bootstrap.js:
--------------------------------------------------------------------------------
1 | // A dependency graph that contains any wasm must all be imported
2 | // asynchronously. This `bootstrap.js` file does the single async import, so
3 | // that no one else needs to worry about it again.
4 | import("./index.js")
5 | .catch(e => console.error("Error importing `index.js`:", e));
6 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/tests/web.rs:
--------------------------------------------------------------------------------
1 | //! Test suite for the Web and headless browsers.
2 |
3 | #![cfg(target_arch = "wasm32")]
4 |
5 | extern crate wasm_bindgen_test;
6 | use wasm_bindgen_test::*;
7 |
8 | wasm_bindgen_test_configure!(run_in_browser);
9 |
10 | #[wasm_bindgen_test]
11 | fn pass() {
12 | assert_eq!(1 + 1, 2);
13 | }
14 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/client/bootstrap.js:
--------------------------------------------------------------------------------
1 | // A dependency graph that contains any wasm must all be imported
2 | // asynchronously. This `bootstrap.js` file does the single async import, so
3 | // that no one else needs to worry about it again.
4 | import("./index.js")
5 | .catch(e => console.error("Error importing `index.js`:", e));
6 |
--------------------------------------------------------------------------------
/Ch04/websocket/client/index.js:
--------------------------------------------------------------------------------
1 | const ws = new WebSocket("ws://127.0.0.1:8080")
2 |
3 | ws.addEventListener("open", function (event) {
4 | console.log("Sending message to server: Meow!")
5 | ws.send("Meow!")
6 | })
7 |
8 | ws.addEventListener("message", function (event) {
9 | console.log("Message from server:", event.data)
10 | })
11 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/tests/web.rs:
--------------------------------------------------------------------------------
1 | //! Test suite for the Web and headless browsers.
2 |
3 | #![cfg(target_arch = "wasm32")]
4 |
5 | extern crate wasm_bindgen_test;
6 | use wasm_bindgen_test::*;
7 |
8 | wasm_bindgen_test_configure!(run_in_browser);
9 |
10 | #[wasm_bindgen_test]
11 | fn pass() {
12 | assert_eq!(1 + 1, 2);
13 | }
14 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/tests/web.rs:
--------------------------------------------------------------------------------
1 | //! Test suite for the Web and headless browsers.
2 |
3 | #![cfg(target_arch = "wasm32")]
4 |
5 | extern crate wasm_bindgen_test;
6 | use wasm_bindgen_test::*;
7 |
8 | wasm_bindgen_test_configure!(run_in_browser);
9 |
10 | #[wasm_bindgen_test]
11 | fn pass() {
12 | assert_eq!(1 + 1, 2);
13 | }
14 |
--------------------------------------------------------------------------------
/Ch02/catdex/start_database.sh:
--------------------------------------------------------------------------------
1 | # Run this the first time:
2 | # docker run --name catdex-db -e POSTGRES_PASSWORD=mypassword -p 5432:5432 -d postgres:12.3-alpine
3 |
4 | # From the second time, run this instead:
5 | docker start catdex-db
6 |
7 | echo "Run this to set the databse URL:"
8 | echo "export DATABASE_URL=postgres://postgres:mypassword@localhost"
9 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/start_database.sh:
--------------------------------------------------------------------------------
1 | # Run this the first time:
2 | # docker run --name catdex-db -e POSTGRES_PASSWORD=mypassword -p 5432:5432 -d postgres:12.3-alpine
3 |
4 | # From the second time, run this instead:
5 | docker start catdex-db
6 |
7 | echo "Run this to set the databse URL:"
8 | echo "export DATABASE_URL=postgres://postgres:mypassword@localhost"
9 |
--------------------------------------------------------------------------------
/Ch05/serverless-catdex/cats/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cats"
3 | version = "0.1.0"
4 | edition = "2018"
5 |
6 | [dependencies]
7 | tokio = { version = "0.2", features = ["macros"] }
8 | lambda_http = { git = "https://github.com/awslabs/aws-lambda-rust-runtime/", branch = "master"}
9 | serde_json = "1.0"
10 | rusoto_core = "0.45.0"
11 | rusoto_dynamodb = "0.45.0"
12 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello wasm-pack!
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Ch04/websocket/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "websocket"
3 | version = "0.1.0"
4 | authors = ["Shing Lyu "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | ws = "0.9.1"
11 | serde = "1.0.104"
12 | serde_json = "1.0.48"
13 | serde_derive= "1.0.104"
14 |
--------------------------------------------------------------------------------
/Ch02/catdex/migrations/00000000000000_diesel_initial_setup/down.sql:
--------------------------------------------------------------------------------
1 | -- This file was automatically created by Diesel to setup helper functions
2 | -- and other internal bookkeeping. This file is safe to edit, any future
3 | -- changes will be added to existing projects as new migrations.
4 |
5 | DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
6 | DROP FUNCTION IF EXISTS diesel_set_updated_at();
7 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/client/webpack.config.js:
--------------------------------------------------------------------------------
1 | const CopyWebpackPlugin = require("copy-webpack-plugin");
2 | const path = require('path');
3 |
4 | module.exports = {
5 | entry: "./bootstrap.js",
6 | output: {
7 | path: path.resolve(__dirname, "dist"),
8 | filename: "bootstrap.js",
9 | },
10 | mode: "development",
11 | plugins: [
12 | new CopyWebpackPlugin(['index.html'])
13 | ],
14 | };
15 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/migrations/00000000000000_diesel_initial_setup/down.sql:
--------------------------------------------------------------------------------
1 | -- This file was automatically created by Diesel to setup helper functions
2 | -- and other internal bookkeeping. This file is safe to edit, any future
3 | -- changes will be added to existing projects as new migrations.
4 |
5 | DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
6 | DROP FUNCTION IF EXISTS diesel_set_updated_at();
7 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/.appveyor.yml:
--------------------------------------------------------------------------------
1 | install:
2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
5 | - rustc -V
6 | - cargo -V
7 |
8 | build: false
9 |
10 | test_script:
11 | - cargo test --locked
12 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/client/webpack.config.js:
--------------------------------------------------------------------------------
1 | const CopyWebpackPlugin = require("copy-webpack-plugin");
2 | const path = require('path');
3 |
4 | module.exports = {
5 | entry: "./bootstrap.js",
6 | output: {
7 | path: path.resolve(__dirname, "dist"),
8 | filename: "bootstrap.js",
9 | },
10 | mode: "development",
11 | plugins: [
12 | new CopyWebpackPlugin(['index.html'])
13 | ],
14 | };
15 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/.appveyor.yml:
--------------------------------------------------------------------------------
1 | install:
2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
5 | - rustc -V
6 | - cargo -V
7 |
8 | build: false
9 |
10 | test_script:
11 | - cargo test --locked
12 |
--------------------------------------------------------------------------------
/Ch02/catdex/static/cat.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{name}}
6 |
12 |
13 |
14 | {{name}}
15 |
16 |
17 | Back
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Ch02/catdex/src/models.rs:
--------------------------------------------------------------------------------
1 | use serde::{Deserialize, Serialize};
2 | use super::schema::cats;
3 |
4 |
5 | #[derive(Queryable, Serialize)]
6 | pub struct Cat {
7 | pub id: i32,
8 | pub name: String,
9 | pub image_path: String
10 | }
11 |
12 | #[derive(Insertable, Serialize, Deserialize)]
13 | #[table_name = "cats"]
14 | pub struct NewCat {
15 | // id will be added by the database
16 | pub name: String,
17 | pub image_path: String
18 | }
19 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/src/models.rs:
--------------------------------------------------------------------------------
1 | use serde::{Deserialize, Serialize};
2 | use super::schema::cats;
3 |
4 |
5 | #[derive(Queryable, Serialize)]
6 | pub struct Cat {
7 | pub id: i32,
8 | pub name: String,
9 | pub image_path: String
10 | }
11 |
12 | #[derive(Insertable, Serialize, Deserialize)]
13 | #[table_name = "cats"]
14 | pub struct NewCat {
15 | // id will be added by the database
16 | pub name: String,
17 | pub image_path: String
18 | }
19 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/src/lib.rs:
--------------------------------------------------------------------------------
1 | mod utils;
2 |
3 | use wasm_bindgen::prelude::*;
4 |
5 | // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
6 | // allocator.
7 | #[cfg(feature = "wee_alloc")]
8 | #[global_allocator]
9 | static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
10 |
11 | #[wasm_bindgen]
12 | extern {
13 | fn alert(s: &str);
14 | }
15 |
16 | #[wasm_bindgen]
17 | pub fn greet() {
18 | alert("Hello, hello-wasm!");
19 | }
20 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/netlify/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Yew • TodoMVC
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Ch02/hello-world/src/main.rs:
--------------------------------------------------------------------------------
1 | use actix_web::{web, App, HttpResponse, HttpServer, Responder};
2 |
3 | async fn hello() -> impl Responder {
4 | HttpResponse::Ok().body("Hello world")
5 | }
6 |
7 | #[actix_web::main]
8 | async fn main() -> std::io::Result<()> {
9 | println!("Listening on port 8080");
10 | HttpServer::new(|| {
11 | App::new()
12 | .route("/hello", web::get().to(hello))
13 | })
14 | .bind("127.0.0.1:8080")?
15 | .run()
16 | .await
17 | }
18 |
--------------------------------------------------------------------------------
/Ch06/hello-wasm/src/utils.rs:
--------------------------------------------------------------------------------
1 | pub fn set_panic_hook() {
2 | // When the `console_error_panic_hook` feature is enabled, we can call the
3 | // `set_panic_hook` function at least once during initialization, and then
4 | // we will get better error messages if our code ever panics.
5 | //
6 | // For more details see
7 | // https://github.com/rustwasm/console_error_panic_hook#readme
8 | #[cfg(feature = "console_error_panic_hook")]
9 | console_error_panic_hook::set_once();
10 | }
11 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/src/utils.rs:
--------------------------------------------------------------------------------
1 | pub fn set_panic_hook() {
2 | // When the `console_error_panic_hook` feature is enabled, we can call the
3 | // `set_panic_hook` function at least once during initialization, and then
4 | // we will get better error messages if our code ever panics.
5 | //
6 | // For more details see
7 | // https://github.com/rustwasm/console_error_panic_hook#readme
8 | #[cfg(feature = "console_error_panic_hook")]
9 | console_error_panic_hook::set_once();
10 | }
11 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/.github/workflows/check.yml:
--------------------------------------------------------------------------------
1 | name: Cargo Check
2 | on: [pull_request]
3 | jobs:
4 | check:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - uses: actions/checkout@v2
8 | - name: Setup Rust
9 | uses: actions-rs/toolchain@v1
10 | with:
11 | toolchain: stable
12 | - name: Run fmt
13 | run: cargo fmt -- --check
14 | - name: Run clippy
15 | run: cargo clippy -- --deny=warnings
16 | - name: Run check
17 | run: cargo check
--------------------------------------------------------------------------------
/Ch02/catdex/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "catdex"
3 | version = "0.1.0"
4 | authors = ["Shing Lyu "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | actix-web = "3"
11 | actix-files = "0.3.0"
12 | serde_json = "1.0.53"
13 | handlebars = { version = "3.0.1", features = ["dir_source"] }
14 | diesel = { version = "1.4.4", features = ["postgres", "r2d2"] }
15 | serde = "1.0.110"
16 | r2d2 = "0.8.8"
17 | awmp = "0.6.0"
18 |
--------------------------------------------------------------------------------
/Ch04/websocket/client/chat.js:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", function(){
2 | const socket = new WebSocket("ws://127.0.0.1:8080");
3 | socket.onmessage = function (event) {
4 | const messages = document.getElementById("messages");
5 | messages.value += `${event.data}\n`;
6 | };
7 |
8 | const sendButton= document.getElementById("send");
9 | sendButton.addEventListener("click", (event) => {
10 | const message = document.getElementById("message");
11 | socket.send(message.value)
12 | message.value = "";
13 | })
14 | });
15 |
--------------------------------------------------------------------------------
/Ch05/serverless-hello-world/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "serverless-hello-world"
3 | version = "0.1.0"
4 | authors = ["Shing Lyu "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | lambda_runtime = "0.2.1"
11 | serde = "^1"
12 | serde_json = "^1"
13 | serde_derive = "^1"
14 | tokio = "0.1"
15 | log = "^0.4"
16 | simple_logger = "^1.11.0"
17 | simple-error = "^0.1"
18 |
19 | [[bin]]
20 | name = "bootstrap"
21 | path = "src/main.rs"
22 |
--------------------------------------------------------------------------------
/Ch06/yew-image-processing/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![recursion_limit = "512"]
2 |
3 | mod app;
4 |
5 | use wasm_bindgen::prelude::*;
6 |
7 | // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
8 | // allocator.
9 | #[cfg(feature = "wee_alloc")]
10 | #[global_allocator]
11 | static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
12 |
13 | // This is the entry point for the web app
14 | #[wasm_bindgen]
15 | pub fn run_app() -> Result<(), JsValue> {
16 | wasm_logger::init(wasm_logger::Config::default());
17 | yew::start_app::();
18 | Ok(())
19 | }
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Apress Source Code
2 |
3 | This repository accompanies [*Practical Rust Web Projects*](https://www.apress.com/9781484265888) by Shing Lyu (Apress, 2021).
4 |
5 | [comment]: #cover
6 | 
7 |
8 | Download the files as a zip using the green button, or clone the repository to your machine using Git.
9 |
10 | ## Releases
11 |
12 | Release v1.0 corresponds to the code in the published book, without corrections or updates.
13 |
14 | ## Contributions
15 |
16 | See the file Contributing.md for more information on how you can contribute to this repository.
--------------------------------------------------------------------------------
/Ch04/websocket/client/chat.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | WebSocket Chat
6 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Ch05/serverless-catdex/cat_post/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cat_post"
3 | version = "0.1.0"
4 | authors = ["Shing Lyu "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | tokio = { version = "0.2", features = ["macros"] }
11 | lambda_http = { git = "https://github.com/awslabs/aws-lambda-rust-runtime/", branch = "master"}
12 | serde_json = "1.0"
13 | rusoto_core = "0.45.0"
14 | rusoto_dynamodb = "0.45.0"
15 | serde = "1.0.114"
16 | rusoto_s3 = "0.45.0"
17 | rusoto_credential = "0.45.0"
18 |
--------------------------------------------------------------------------------
/Ch04/websocket/examples/push_notification.rs:
--------------------------------------------------------------------------------
1 | extern crate ws;
2 |
3 | use std::{thread, time};
4 | use ws::{Handler, Sender, WebSocket};
5 |
6 | struct Server {
7 | out: Sender,
8 | }
9 |
10 | impl Handler for Server {}
11 |
12 | fn main() {
13 | let server = WebSocket::new(|out| Server { out }).unwrap();
14 |
15 | let broadcaster = server.broadcaster();
16 |
17 | let periodic = thread::spawn(move || loop {
18 | broadcaster.send("Meow!").unwrap();
19 | thread::sleep(time::Duration::from_secs(1));
20 | });
21 | server.listen("127.0.0.1:8080").unwrap();
22 | periodic.join().unwrap();
23 | }
24 |
--------------------------------------------------------------------------------
/Ch06/wasm-image-processing/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Cat image processor
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Ch02/catdex/static/add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Catdex
6 |
7 |
8 |
9 | Add a new cat
10 |
11 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Ch02/catdex/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{project_name}}
6 |
7 |
8 |
9 | {{project_name}}
10 |
11 | Add a new cat
12 |
13 |
14 |
15 | {{#each cats}}
16 |
17 |
18 |
19 |
20 | {{/each}}
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Ch03/rest_api/catdex/static/add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Catdex
6 |
7 |
8 |
9 | Add a new cat
10 |
11 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Ch04/websocket/examples/unresponsive_client.rs:
--------------------------------------------------------------------------------
1 | extern crate ws;
2 |
3 | use ws::{connect, CloseCode, Frame, Message, OpCode, Result};
4 |
5 | struct Client {
6 | out: ws::Sender,
7 | }
8 | impl ws::Handler for Client {
9 | fn on_frame(
10 | &mut self,
11 | frame: Frame,
12 | ) -> Result