├── 27-bevy_snake
├── .gitignore
├── .cargo
│ └── config.toml
├── snake01_beginning
│ ├── src
│ │ └── main.rs
│ └── Cargo.toml
├── README.md
├── snake02_window
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake04_snakemove
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake06_grid
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake09_foodspawning
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake03_snakehead
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake05_snakecontrol
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake07_moveongrid
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake08_configwindow
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake10_foodtimer
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake11_headadvance
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake12_segments
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake13_attachtail
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── snake14_eatandgrow
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
└── snake15_hitting
│ └── Cargo.toml
├── 30-ffi
├── bigint-pyo3
│ ├── .gitignore
│ ├── fib_rust.py
│ ├── Cargo.toml
│ ├── fib.py
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ └── Cargo.lock
├── c_call_rust
│ ├── run_c.sh
│ ├── compile_c.sh
│ ├── call_rust
│ ├── src
│ │ └── lib.rs
│ ├── call_rust.c
│ ├── Cargo.lock
│ └── Cargo.toml
├── word-count
│ ├── MANIFEST.in
│ ├── cargo-generate.toml
│ ├── __pycache__
│ │ └── noxfile.cpython-310.pyc
│ ├── tests
│ │ ├── __pycache__
│ │ │ └── test_word_count.cpython-310-pytest-7.4.3.pyc
│ │ └── test_word_count.py
│ ├── .template
│ │ ├── pre-script.rhai
│ │ ├── pyproject.toml
│ │ └── Cargo.toml
│ ├── Cargo.toml
│ ├── noxfile.py
│ ├── word_count
│ │ └── __init__.py
│ ├── pyproject.toml
│ ├── README.md
│ ├── src
│ │ └── lib.rs
│ └── Cargo.lock
└── rust_call_c
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── .gitignore
├── 2122-axumapp_stepbystep
├── axumapp03_addlog
│ ├── .gitignore
│ ├── assets
│ │ ├── index.html
│ │ ├── script.js
│ │ └── ferris.png
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp04_query
│ ├── .gitignore
│ ├── start.sh
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp05_form
│ ├── .gitignore
│ ├── start.sh
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp10_db
│ ├── .gitignore
│ ├── start.sh
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp11_todo
│ ├── .gitignore
│ ├── start.sh
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp01_helloworld
│ ├── .gitignore
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp02_staticfile
│ ├── .gitignore
│ ├── assets
│ │ ├── index.html
│ │ ├── script.js
│ │ └── ferris.png
│ ├── assets2
│ │ ├── index.html
│ │ ├── script.js
│ │ └── ferris2.png
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp06_jsoninput
│ ├── .gitignore
│ ├── assets
│ │ ├── index.html
│ │ ├── script.js
│ │ └── ferris.png
│ ├── start.sh
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp07_jsonres
│ ├── .gitignore
│ ├── start.sh
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp08_global404
│ ├── .gitignore
│ ├── start.sh
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── axumapp09_template
│ ├── .gitignore
│ ├── templates
│ │ └── hello.html
│ ├── start.sh
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── .cargo
│ └── config.toml
└── .rustc_info.json
├── 28-nom
├── .cargo
│ └── config.toml
├── color
│ ├── Cargo.toml
│ ├── Cargo.lock
│ └── src
│ │ └── main.rs
├── coordination
│ ├── Cargo.toml
│ ├── Cargo.lock
│ └── src
│ │ └── main.rs
├── num0_parser
│ ├── Cargo.toml
│ ├── src
│ │ └── main.rs
│ └── Cargo.lock
└── num1_parser
│ ├── Cargo.toml
│ ├── src
│ └── main.rs
│ └── Cargo.lock
├── 25-slint-chatbot-demo
├── build.rs
├── assets
│ └── screenshot.png
├── .gitignore
├── Cargo.toml
├── LICENSE
├── ui
│ └── appwindow.slint
├── README.md
└── src
│ ├── main.rs
│ ├── token_output_stream.rs
│ └── llmengin.rs
├── 26-slint-yolov8-demo
├── build.rs
├── football.jpg
├── .vscode
│ ├── settings.json
│ ├── extensions.json
│ └── launch.json
├── assets
│ ├── poses.png
│ └── objects.png
├── src
│ ├── yolov8engine
│ │ ├── roboto-mono-stripped.ttf
│ │ └── coco_classes.rs
│ └── main.rs
├── Cargo.toml
├── LICENSE
├── README.md
└── ui
│ └── appwindow.slint
├── 24-candle_yolov8
├── assets
│ ├── bike.jpg
│ ├── cats.jpg
│ └── football.jpg
├── src
│ ├── roboto-mono-stripped.ttf
│ └── coco_classes.rs
├── Cargo.toml
└── README.md
├── 23-candle_chat
├── Cargo.toml
├── README.md
└── src
│ ├── token_output_stream.rs
│ ├── simple.rs
│ └── cli.rs
├── 16-channel
├── Cargo.toml
└── src
│ ├── main_e.rs
│ ├── main_f.rs
│ ├── main_c.rs
│ ├── main_a.rs
│ ├── main_b.rs
│ └── main_d.rs
└── 14-getinfo
├── Cargo.toml
└── src
├── client_framed.rs
├── client.rs
├── server_framed.rs
└── server.rs
/27-bevy_snake/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/30-ffi/bigint-pyo3/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/target
2 | **/debug
3 | **/.env/
4 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp03_addlog/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp04_query/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp05_form/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp10_db/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp11_todo/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp01_helloworld/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp06_jsoninput/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp07_jsonres/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp08_global404/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp09_template/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/27-bevy_snake/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | target-dir="target"
3 |
--------------------------------------------------------------------------------
/28-nom/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | target-dir="target"
3 |
4 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | target-dir="target"
3 |
--------------------------------------------------------------------------------
/30-ffi/c_call_rust/run_c.sh:
--------------------------------------------------------------------------------
1 | LD_LIBRARY_PATH=./target/debug ./call_rust
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp03_addlog/assets/index.html:
--------------------------------------------------------------------------------
1 | Hi from index.html
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/assets/index.html:
--------------------------------------------------------------------------------
1 | Hi from index.html
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp06_jsoninput/assets/index.html:
--------------------------------------------------------------------------------
1 | Hi from index.html
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp03_addlog/assets/script.js:
--------------------------------------------------------------------------------
1 | console.log("Hello, World!");
2 |
--------------------------------------------------------------------------------
/30-ffi/bigint-pyo3/fib_rust.py:
--------------------------------------------------------------------------------
1 | import rust_fib
2 |
3 | rust_fib.calc_fib(2000000)
4 |
5 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/assets/script.js:
--------------------------------------------------------------------------------
1 | console.log("Hello, World!");
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/assets2/index.html:
--------------------------------------------------------------------------------
1 | Hi from assets2/index.html
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/assets2/script.js:
--------------------------------------------------------------------------------
1 | console.log("Hello, World2!");
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp06_jsoninput/assets/script.js:
--------------------------------------------------------------------------------
1 | console.log("Hello, World!");
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp09_template/templates/hello.html:
--------------------------------------------------------------------------------
1 |
Hello, {{ name }}!
2 |
--------------------------------------------------------------------------------
/30-ffi/c_call_rust/compile_c.sh:
--------------------------------------------------------------------------------
1 | gcc call_rust.c -o call_rust -lc_call_rust -L./target/debug
2 |
--------------------------------------------------------------------------------
/30-ffi/word-count/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include pyproject.toml Cargo.toml
2 | recursive-include src *
3 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp05_form/start.sh:
--------------------------------------------------------------------------------
1 | RUST_LOG=tower_http=debug,axumapp05=debug cargo run
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp10_db/start.sh:
--------------------------------------------------------------------------------
1 | RUST_LOG=tower_http=debug,axumapp10=debug cargo run
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp11_todo/start.sh:
--------------------------------------------------------------------------------
1 | RUST_LOG=tower_http=debug,axumapp11=debug cargo run
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp04_query/start.sh:
--------------------------------------------------------------------------------
1 | RUST_LOG=tower_http=debug,axumapp04=debug cargo run
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp06_jsoninput/start.sh:
--------------------------------------------------------------------------------
1 | RUST_LOG=tower_http=debug,axumapp06=debug cargo run
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp07_jsonres/start.sh:
--------------------------------------------------------------------------------
1 | RUST_LOG=tower_http=debug,axumapp07=debug cargo run
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp08_global404/start.sh:
--------------------------------------------------------------------------------
1 | RUST_LOG=tower_http=debug,axumapp08=debug cargo run
2 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp09_template/start.sh:
--------------------------------------------------------------------------------
1 | RUST_LOG=tower_http=debug,axumapp09=debug cargo run
2 |
--------------------------------------------------------------------------------
/25-slint-chatbot-demo/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | slint_build::compile("ui/appwindow.slint").unwrap();
3 | }
4 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | slint_build::compile("ui/appwindow.slint").unwrap();
3 | }
4 |
--------------------------------------------------------------------------------
/30-ffi/c_call_rust/call_rust:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/30-ffi/c_call_rust/call_rust
--------------------------------------------------------------------------------
/24-candle_yolov8/assets/bike.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/24-candle_yolov8/assets/bike.jpg
--------------------------------------------------------------------------------
/24-candle_yolov8/assets/cats.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/24-candle_yolov8/assets/cats.jpg
--------------------------------------------------------------------------------
/27-bevy_snake/snake01_beginning/src/main.rs:
--------------------------------------------------------------------------------
1 | use bevy::prelude::*;
2 |
3 | fn main() {
4 | App::new().run();
5 | }
6 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/football.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/26-slint-yolov8-demo/football.jpg
--------------------------------------------------------------------------------
/24-candle_yolov8/assets/football.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/24-candle_yolov8/assets/football.jpg
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "rust-analyzer.linkedProjects": [
3 | ".\\Cargo.toml"
4 | ]
5 | }
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/assets/poses.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/26-slint-yolov8-demo/assets/poses.png
--------------------------------------------------------------------------------
/30-ffi/c_call_rust/src/lib.rs:
--------------------------------------------------------------------------------
1 | #[no_mangle]
2 | pub extern "C" fn hello_from_rust() {
3 | println!("Hello from Rust!");
4 | }
5 |
--------------------------------------------------------------------------------
/30-ffi/word-count/cargo-generate.toml:
--------------------------------------------------------------------------------
1 | [template]
2 | ignore = [".nox"]
3 |
4 | [hooks]
5 | pre = [".template/pre-script.rhai"]
6 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/assets/objects.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/26-slint-yolov8-demo/assets/objects.png
--------------------------------------------------------------------------------
/24-candle_yolov8/src/roboto-mono-stripped.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/24-candle_yolov8/src/roboto-mono-stripped.ttf
--------------------------------------------------------------------------------
/25-slint-chatbot-demo/assets/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/25-slint-chatbot-demo/assets/screenshot.png
--------------------------------------------------------------------------------
/30-ffi/c_call_rust/call_rust.c:
--------------------------------------------------------------------------------
1 | extern void hello_from_rust();
2 |
3 | int main(void) {
4 | hello_from_rust();
5 | return 0;
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/30-ffi/word-count/__pycache__/noxfile.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/30-ffi/word-count/__pycache__/noxfile.cpython-310.pyc
--------------------------------------------------------------------------------
/27-bevy_snake/README.md:
--------------------------------------------------------------------------------
1 | # bevy_snake
2 |
3 |
4 | Clone of the snake game, with Bevy. Updated to Bevy v0.12.
5 |
6 | https://mbuffett.com/posts/bevy-snake-tutorial/
7 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp03_addlog/assets/ferris.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/2122-axumapp_stepbystep/axumapp03_addlog/assets/ferris.png
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/assets/ferris.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/2122-axumapp_stepbystep/axumapp02_staticfile/assets/ferris.png
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp06_jsoninput/assets/ferris.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/2122-axumapp_stepbystep/axumapp06_jsoninput/assets/ferris.png
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "rust-lang.rust-analyzer",
4 | "vadimcn.vscode-lldb",
5 | "Slint.slint"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/src/yolov8engine/roboto-mono-stripped.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/26-slint-yolov8-demo/src/yolov8engine/roboto-mono-stripped.ttf
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/assets2/ferris2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/2122-axumapp_stepbystep/axumapp02_staticfile/assets2/ferris2.png
--------------------------------------------------------------------------------
/30-ffi/c_call_rust/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "c_call_rust"
7 | version = "0.1.0"
8 |
--------------------------------------------------------------------------------
/30-ffi/rust_call_c/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "rust_call_c"
7 | version = "0.1.0"
8 |
--------------------------------------------------------------------------------
/30-ffi/word-count/tests/__pycache__/test_word_count.cpython-310-pytest-7.4.3.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketang84/jikeshijian/HEAD/30-ffi/word-count/tests/__pycache__/test_word_count.cpython-310-pytest-7.4.3.pyc
--------------------------------------------------------------------------------
/25-slint-chatbot-demo/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | /target/
4 |
5 | # These are backup files generated by rustfmt
6 | **/*.rs.bk
7 |
8 | *.gguf
9 | *.json
10 |
--------------------------------------------------------------------------------
/30-ffi/rust_call_c/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_call_c"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 |
--------------------------------------------------------------------------------
/30-ffi/word-count/.template/pre-script.rhai:
--------------------------------------------------------------------------------
1 | variable::set("PYO3_VERSION", "0.20.0");
2 | file::rename(".template/Cargo.toml", "Cargo.toml");
3 | file::rename(".template/pyproject.toml", "pyproject.toml");
4 | file::delete(".template");
5 |
--------------------------------------------------------------------------------
/28-nom/color/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "color"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | nom = "7.1.3"
10 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp01_helloworld/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp01"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 |
--------------------------------------------------------------------------------
/28-nom/coordination/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "coordination"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | nom = "7.1.3"
10 |
--------------------------------------------------------------------------------
/28-nom/num0_parser/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "num0_parser"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | nom = "7.1.3"
10 |
--------------------------------------------------------------------------------
/28-nom/num1_parser/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "num1_parser"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | nom = "7.1.3"
10 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake02_window/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake02"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake04_snakemove/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake04"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
--------------------------------------------------------------------------------
/27-bevy_snake/snake06_grid/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake06"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake09_foodspawning/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake09"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
--------------------------------------------------------------------------------
/27-bevy_snake/snake01_beginning/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake01"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake03_snakehead/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake03"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake05_snakecontrol/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake05"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake07_moveongrid/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake07"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake08_configwindow/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake08"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake10_foodtimer/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake10"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
12 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake11_headadvance/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake11"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
12 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake12_segments/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake12"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
12 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake13_attachtail/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake13"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
12 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake14_eatandgrow/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake14"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
12 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake15_hitting/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "snake15"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = "0.12.1"
10 | rand = "0.8.5"
11 |
12 |
--------------------------------------------------------------------------------
/30-ffi/c_call_rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "c_call_rust"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 |
9 | [lib]
10 | crate-type = ["cdylib"]
11 |
12 |
13 | [dependencies]
14 |
--------------------------------------------------------------------------------
/30-ffi/word-count/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "word-count"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [lib]
7 | name = "word_count"
8 | crate-type = ["cdylib"]
9 |
10 | [dependencies]
11 | pyo3 = { version = "0.20", features = ["extension-module"] }
12 | rayon = "1.0.2"
13 |
14 | [workspace]
15 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp02"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7.2"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5.0", features = ["fs", "trace"] }
11 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake02_window/src/main.rs:
--------------------------------------------------------------------------------
1 | use bevy::prelude::*;
2 |
3 | fn main() {
4 | App::new()
5 | .add_plugins(DefaultPlugins)
6 | .add_systems(Startup, setup_camera)
7 | .run();
8 | }
9 |
10 | fn setup_camera(mut commands: Commands) {
11 | commands.spawn(Camera2dBundle::default());
12 | }
13 |
--------------------------------------------------------------------------------
/30-ffi/word-count/.template/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["maturin>=1,<2"]
3 | build-backend = "maturin"
4 |
5 | [project]
6 | name = "{{project-name}}"
7 | version = "0.1.0"
8 |
9 | [project.optional-dependencies]
10 | dev = ["pytest"]
11 |
12 | [tool.pytest.ini_options]
13 | addopts = "--benchmark-disable"
14 |
--------------------------------------------------------------------------------
/30-ffi/word-count/.template/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | authors = ["{{authors}}"]
3 | name = "{{project-name}}"
4 | version = "0.1.0"
5 | edition = "2021"
6 |
7 | [lib]
8 | name = "word_count"
9 | crate-type = ["cdylib"]
10 |
11 | [dependencies]
12 | pyo3 = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
13 | rayon = "1.0.2"
14 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp03_addlog/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp03"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5.0", features = ["fs", "trace"] }
11 | tracing = "0.1.40"
12 | tracing-subscriber = "0.3.18"
13 |
--------------------------------------------------------------------------------
/30-ffi/bigint-pyo3/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "bigint"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [lib]
9 | name = "rust_fib"
10 | crate-type = ["cdylib"]
11 |
12 | [dependencies]
13 | num-bigint = "0.4.4"
14 | num-traits = "0.2.17"
15 | pyo3 = "0.20"
16 |
17 |
--------------------------------------------------------------------------------
/30-ffi/bigint-pyo3/fib.py:
--------------------------------------------------------------------------------
1 | def fibonacci(n):
2 | if n <= 0:
3 | return "输入的数字必须大于0"
4 | elif n == 1:
5 | return 0
6 | elif n == 2:
7 | return 1
8 | else:
9 | a, b = 0, 1
10 | for _ in range(n - 2):
11 | a, b = b, a + b
12 | return b
13 |
14 | # 测试函数
15 | # print(fibonacci(100000))
16 | fibonacci(2000000)
17 |
18 |
--------------------------------------------------------------------------------
/28-nom/num0_parser/src/main.rs:
--------------------------------------------------------------------------------
1 | use nom::IResult;
2 | use std::error::Error;
3 |
4 | pub fn do_nothing_parser(input: &str) -> IResult<&str, &str> {
5 | Ok((input, ""))
6 | }
7 | fn main() -> Result<(), Box> {
8 | let (remaining_input, output) = do_nothing_parser("abcdefg")?;
9 | assert_eq!(remaining_input, "abcdefg");
10 | assert_eq!(output, "");
11 | Ok(())
12 | }
13 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp05_form/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp05"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5", features = ["fs", "trace"] }
11 | tracing = "0.1"
12 | tracing-subscriber = "0.3"
13 | serde = { version = "1.0", features = ["derive"] }
14 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp04_query/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp04"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5", features = ["fs", "trace"] }
11 | tracing = "0.1"
12 | tracing-subscriber = "0.3"
13 | serde = { version = "1.0", features = ["derive"] }
14 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp06_jsoninput/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp06"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5", features = ["fs", "trace"] }
11 | tracing = "0.1"
12 | tracing-subscriber = "0.3"
13 | serde = { version = "1.0", features = ["derive"] }
14 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp07_jsonres/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp07"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5", features = ["fs", "trace"] }
11 | tracing = "0.1"
12 | tracing-subscriber = "0.3"
13 | serde = { version = "1.0", features = ["derive"] }
14 | serde_json = "1.0"
15 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp08_global404/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp08"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5", features = ["fs", "trace"] }
11 | tracing = "0.1"
12 | tracing-subscriber = "0.3"
13 | serde = { version = "1.0", features = ["derive"] }
14 | serde_json = "1.0"
15 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp09_template/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp09"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5", features = ["fs", "trace"] }
11 | tracing = "0.1"
12 | tracing-subscriber = "0.3"
13 | serde = { version = "1.0", features = ["derive"] }
14 | serde_json = "1.0"
15 | askama = "0.12"
16 |
--------------------------------------------------------------------------------
/30-ffi/word-count/noxfile.py:
--------------------------------------------------------------------------------
1 | import nox
2 |
3 | nox.options.sessions = ["test"]
4 |
5 |
6 | @nox.session
7 | def test(session: nox.Session):
8 | session.env["MATURIN_PEP517_ARGS"] = "--profile=dev"
9 | session.install(".[dev]")
10 | session.run("pytest")
11 |
12 |
13 | @nox.session
14 | def bench(session: nox.Session):
15 | session.env["MATURIN_PEP517_ARGS"] = "--profile=dev"
16 | session.install(".[dev]")
17 | session.run("pytest", "--benchmark-enable")
18 |
--------------------------------------------------------------------------------
/28-nom/num1_parser/src/main.rs:
--------------------------------------------------------------------------------
1 | pub use nom::bytes::complete::tag;
2 | pub use nom::IResult;
3 | use std::error::Error;
4 |
5 | fn parse_input(input: &str) -> IResult<&str, &str> {
6 | tag("abc")(input)
7 | }
8 |
9 | fn main() -> Result<(), Box> {
10 | let (leftover_input, output) = parse_input("abcWorld")?;
11 | assert_eq!(leftover_input, "World");
12 | assert_eq!(output, "abc");
13 |
14 | assert!(parse_input("defWorld").is_err());
15 | Ok(())
16 | }
17 |
--------------------------------------------------------------------------------
/30-ffi/bigint-pyo3/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["maturin>=1.4,<2.0"]
3 | build-backend = "maturin"
4 |
5 | [project]
6 | name = "bigint-pyo3"
7 | requires-python = ">=3.8"
8 | classifiers = [
9 | "Programming Language :: Rust",
10 | "Programming Language :: Python :: Implementation :: CPython",
11 | "Programming Language :: Python :: Implementation :: PyPy",
12 | ]
13 | dynamic = ["version"]
14 |
15 | [tool.maturin]
16 | features = ["pyo3/extension-module"]
17 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp10_db/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp10"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5", features = ["fs", "trace"] }
11 | tracing = "0.1"
12 | tracing-subscriber = "0.3"
13 | serde = { version = "1.0", features = ["derive"] }
14 | serde_json = "1.0"
15 | bb8 = "0.7"
16 | bb8-postgres = "0.7"
17 | tokio-postgres = "0.7"
18 |
--------------------------------------------------------------------------------
/30-ffi/word-count/word_count/__init__.py:
--------------------------------------------------------------------------------
1 | from .word_count import search, search_sequential, search_sequential_allow_threads
2 |
3 | __all__ = [
4 | "search_py",
5 | "search",
6 | "search_sequential",
7 | "search_sequential_allow_threads",
8 | ]
9 |
10 |
11 | def search_py(contents: str, needle: str) -> int:
12 | total = 0
13 | for line in contents.splitlines():
14 | for word in line.split(" "):
15 | if word == needle:
16 | total += 1
17 | return total
18 |
--------------------------------------------------------------------------------
/25-slint-chatbot-demo/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "slint-chatbot-demo"
3 | version = "0.1.0"
4 | authors = ["daoga"]
5 | edition = "2021"
6 | build = "build.rs"
7 |
8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
9 |
10 | [dependencies]
11 | slint = "1.3"
12 | anyhow = "1.0.75"
13 | candle-core = { version = "0.3.1" }
14 | candle-transformers = { version = "0.3.1" }
15 | clap = "4.4.10"
16 | hf-hub = "0.3.2"
17 | tokenizers = "0.15.0"
18 |
19 | [build-dependencies]
20 | slint-build = "1.3"
21 |
--------------------------------------------------------------------------------
/23-candle_chat/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "candle_demo_openchat_35"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | anyhow = "1.0.75"
10 | candle-core = { version = "0.3.1" }
11 | candle-transformers = "0.3.1"
12 | clap = "4.4.10"
13 | hf-hub = "0.3.2"
14 | tokenizers = "0.15.0"
15 |
16 | [[bin]]
17 | name = "simple"
18 | path = "src/simple.rs"
19 |
20 |
21 | [[bin]]
22 | name = "cli"
23 | path = "src/cli.rs"
24 |
25 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp11_todo/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axumapp11"
3 | version = "0.1.0"
4 | edition = "2021"
5 | publish = false
6 |
7 | [dependencies]
8 | axum = "0.7"
9 | tokio = { version = "1.0", features = ["full"] }
10 | tower-http = { version = "0.5", features = ["fs", "trace"] }
11 | tracing = "0.1"
12 | tracing-subscriber = "0.3"
13 | serde = { version = "1.0", features = ["derive"] }
14 | serde_json = "1.0"
15 | bb8 = "0.7"
16 | bb8-postgres = "0.7"
17 | tokio-postgres = "0.7"
18 | uuid = { version = "1.0", features = ["serde", "v4"] }
19 |
20 |
--------------------------------------------------------------------------------
/24-candle_yolov8/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "candle_demo_yolov8"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | anyhow = "1.0.75"
10 | candle-core = "0.3.1"
11 | candle-nn = "0.3.1"
12 | candle-transformers = "0.3.1"
13 | clap = "4.4.10"
14 | hf-hub = "0.3.2"
15 | image = "0.24.7"
16 | imageproc = "0.23.0"
17 | rusttype = "0.9.3"
18 | tokenizers = "0.15.0"
19 | tracing = "0.1.40"
20 | tracing-chrome = "0.7.1"
21 | tracing-subscriber = "0.3.18"
22 |
23 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp01_helloworld/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::{response::Html, routing::get, Router};
2 |
3 | #[tokio::main]
4 | async fn main() {
5 | // build our application with a route
6 | let app = Router::new().route("/", get(handler));
7 |
8 | // run it
9 | let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
10 | .await
11 | .unwrap();
12 | println!("listening on {}", listener.local_addr().unwrap());
13 | axum::serve(listener, app).await.unwrap();
14 | }
15 |
16 | async fn handler() -> Html<&'static str> {
17 | Html("Hello, World!
")
18 | }
19 |
--------------------------------------------------------------------------------
/30-ffi/word-count/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["maturin>=1,<2"]
3 | build-backend = "maturin"
4 |
5 | [project]
6 | name = "word-count"
7 | version = "0.1.0"
8 | classifiers = [
9 | "License :: OSI Approved :: MIT License",
10 | "Development Status :: 3 - Alpha",
11 | "Intended Audience :: Developers",
12 | "Programming Language :: Python",
13 | "Programming Language :: Rust",
14 | "Operating System :: POSIX",
15 | "Operating System :: MacOS :: MacOS X",
16 | ]
17 |
18 | [project.optional-dependencies]
19 | dev = ["pytest", "pytest-benchmark"]
20 |
21 | [tool.pytest.ini_options]
22 | addopts = "--benchmark-disable"
23 |
--------------------------------------------------------------------------------
/16-channel/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "channel"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | tokio = { version = "1.33.0", features = ["full"] }
10 |
11 | [[bin]]
12 | name = "main_a"
13 | path = "src/main_a.rs"
14 |
15 | [[bin]]
16 | name = "main_b"
17 | path = "src/main_b.rs"
18 |
19 | [[bin]]
20 | name = "main_c"
21 | path = "src/main_c.rs"
22 |
23 | [[bin]]
24 | name = "main_d"
25 | path = "src/main_d.rs"
26 |
27 | [[bin]]
28 | name = "main_e"
29 | path = "src/main_e.rs"
30 |
31 | [[bin]]
32 | name = "main_f"
33 | path = "src/main_f.rs"
34 |
--------------------------------------------------------------------------------
/16-channel/src/main_e.rs:
--------------------------------------------------------------------------------
1 | use std::time::Duration;
2 | use tokio::task;
3 | use tokio::time;
4 |
5 | #[tokio::main]
6 | async fn main() {
7 | let task_a = task::spawn(async move {
8 | println!("in task_a");
9 | time::sleep(Duration::from_secs(3)).await; // 等待3s
10 | 1
11 | });
12 | let task_b = task::spawn(async move {
13 | println!("in task_b");
14 | 2
15 | });
16 | let task_c = task::spawn(async move {
17 | println!("in task_c");
18 | 3
19 | });
20 |
21 | let (r1, r2, r3) = tokio::join!(task_a, task_b, task_c);
22 |
23 | println!("{}, {}, {}", r1.unwrap(), r2.unwrap(), r3.unwrap());
24 | }
25 |
--------------------------------------------------------------------------------
/30-ffi/bigint-pyo3/src/lib.rs:
--------------------------------------------------------------------------------
1 | use num_bigint::BigUint;
2 | use num_traits::{One, Zero};
3 | use pyo3::prelude::*;
4 |
5 | // Calculate large fibonacci numbers.
6 | fn fib(n: usize) -> BigUint {
7 | let mut f0: BigUint = Zero::zero();
8 | let mut f1: BigUint = One::one();
9 | for _ in 0..n {
10 | let f2 = f0 + &f1;
11 | f0 = f1;
12 | f1 = f2;
13 | }
14 | f0
15 | }
16 |
17 | #[pyfunction]
18 | fn calc_fib(n: usize) -> PyResult<()> {
19 | let _ = fib(n);
20 | Ok(())
21 | }
22 |
23 | #[pymodule]
24 | fn rust_fib(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
25 | m.add_function(wrap_pyfunction!(calc_fib, m)?)?;
26 | Ok(())
27 | }
28 |
--------------------------------------------------------------------------------
/14-getinfo/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "getinfo"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bytes = "1.5.0"
10 | futures = "0.3.29"
11 | tokio = { version = "1.33.0", features = ["full"] }
12 | tokio-util = { version = "0.7.10", features = ["full"] }
13 |
14 |
15 | [[bin]]
16 | name = "server"
17 | path = "src/server.rs"
18 |
19 | [[bin]]
20 | name = "client"
21 | path = "src/client.rs"
22 |
23 | [[bin]]
24 | name = "server_framed"
25 | path = "src/server_framed.rs"
26 |
27 | [[bin]]
28 | name = "client_framed"
29 | path = "src/client_framed.rs"
30 |
31 |
--------------------------------------------------------------------------------
/16-channel/src/main_f.rs:
--------------------------------------------------------------------------------
1 | use std::time::Duration;
2 | use tokio::task;
3 | use tokio::time;
4 |
5 | #[tokio::main]
6 | async fn main() {
7 | let task_a = task::spawn(async move {
8 | println!("in task_a");
9 | time::sleep(Duration::from_secs(3)).await; // 等待3s
10 | 1
11 | });
12 | let task_b = task::spawn(async move {
13 | println!("in task_b");
14 | 2
15 | });
16 | let task_c = task::spawn(async move {
17 | println!("in task_c");
18 | 3
19 | });
20 |
21 | let ret = tokio::select! {
22 | r = task_a => r.unwrap(),
23 | r = task_b => r.unwrap(),
24 | r = task_c => r.unwrap(),
25 | };
26 |
27 | println!("{}", ret);
28 | }
29 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "slint-yolov8-demo"
3 | version = "0.1.0"
4 | authors = ["Daogang Tang "]
5 | edition = "2021"
6 | build = "build.rs"
7 |
8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
9 |
10 | [dependencies]
11 | native-dialog = "0.7.0"
12 | slint = "1.3"
13 |
14 | anyhow = "1.0.75"
15 | candle-core = "0.3.1"
16 | candle-nn = "0.3.1"
17 | candle-transformers = "0.3.1"
18 | #clap = "4.4.10"
19 | hf-hub = "0.3.2"
20 | image = "0.24.7"
21 | imageproc = "0.23.0"
22 | rusttype = "0.9.3"
23 | tokenizers = "0.15.0"
24 | tracing = "0.1.40"
25 | tracing-chrome = "0.7.1"
26 | tracing-subscriber = "0.3.18"
27 |
28 |
29 | [build-dependencies]
30 | slint-build = "1.3"
31 |
--------------------------------------------------------------------------------
/16-channel/src/main_c.rs:
--------------------------------------------------------------------------------
1 | use std::time::Duration;
2 | use tokio::task;
3 | use tokio::time;
4 |
5 | #[tokio::main]
6 | async fn main() {
7 | let task_a = task::spawn(async move {
8 | println!("in task_a");
9 | time::sleep(Duration::from_secs(3)).await; // 等待3s
10 | 1
11 | });
12 | let task_b = task::spawn(async move {
13 | println!("in task_b");
14 | 2
15 | });
16 | let task_c = task::spawn(async move {
17 | println!("in task_c");
18 | 3
19 | });
20 |
21 | let mut tasks = Vec::with_capacity(3);
22 | tasks.push(task_a);
23 | tasks.push(task_b);
24 | tasks.push(task_c);
25 |
26 | let mut outputs = Vec::with_capacity(tasks.len());
27 | for task in tasks {
28 | println!("iterate task result..");
29 | // 在这里依次等待任务完成
30 | outputs.push(task.await.unwrap());
31 | }
32 | println!("{:?}", outputs);
33 | }
34 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake03_snakehead/src/main.rs:
--------------------------------------------------------------------------------
1 | use bevy::prelude::*;
2 |
3 | const SNAKE_HEAD_COLOR: Color = Color::rgb(0.7, 0.7, 0.7);
4 |
5 | #[derive(Component)]
6 | struct SnakeHead;
7 |
8 | fn main() {
9 | App::new()
10 | .add_plugins(DefaultPlugins)
11 | .add_systems(Startup, (setup_camera, spawn_snake))
12 | .run();
13 |
14 | }
15 |
16 | fn setup_camera(mut commands: Commands) {
17 | commands.spawn(Camera2dBundle::default());
18 | }
19 |
20 | fn spawn_snake(mut commands: Commands) {
21 | commands
22 | .spawn(SpriteBundle {
23 | sprite: Sprite {
24 | color: SNAKE_HEAD_COLOR,
25 | ..default()
26 | },
27 | transform: Transform {
28 | scale: Vec3::new(10.0, 10.0, 10.0),
29 | ..default()
30 | },
31 | ..default()
32 | })
33 | .insert(SnakeHead);
34 | }
35 |
--------------------------------------------------------------------------------
/28-nom/color/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "color"
7 | version = "0.1.0"
8 | dependencies = [
9 | "nom",
10 | ]
11 |
12 | [[package]]
13 | name = "memchr"
14 | version = "2.6.4"
15 | source = "registry+https://github.com/rust-lang/crates.io-index"
16 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
17 |
18 | [[package]]
19 | name = "minimal-lexical"
20 | version = "0.2.1"
21 | source = "registry+https://github.com/rust-lang/crates.io-index"
22 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
23 |
24 | [[package]]
25 | name = "nom"
26 | version = "7.1.3"
27 | source = "registry+https://github.com/rust-lang/crates.io-index"
28 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
29 | dependencies = [
30 | "memchr",
31 | "minimal-lexical",
32 | ]
33 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp02_staticfile/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::{response::Html, routing::get, Router};
2 | use tower_http::services::{ServeDir, ServeFile};
3 |
4 | #[tokio::main]
5 | async fn main() {
6 | let serve_dir =
7 | ServeDir::new("assets2").not_found_service(ServeFile::new("assets2/index.html"));
8 | // build our application with a route
9 | let app = Router::new()
10 | .route("/foo", get(handler))
11 | .nest_service("/assets", ServeDir::new("assets"))
12 | .nest_service("/assets2", serve_dir.clone())
13 | .fallback_service(serve_dir);
14 |
15 | // run it
16 | let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
17 | .await
18 | .unwrap();
19 | println!("listening on {}", listener.local_addr().unwrap());
20 | axum::serve(listener, app).await.unwrap();
21 | }
22 |
23 | async fn handler() -> Html<&'static str> {
24 | Html("Hello, World!
")
25 | }
26 |
--------------------------------------------------------------------------------
/28-nom/num0_parser/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "memchr"
7 | version = "2.6.4"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
10 |
11 | [[package]]
12 | name = "minimal-lexical"
13 | version = "0.2.1"
14 | source = "registry+https://github.com/rust-lang/crates.io-index"
15 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
16 |
17 | [[package]]
18 | name = "nom"
19 | version = "7.1.3"
20 | source = "registry+https://github.com/rust-lang/crates.io-index"
21 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
22 | dependencies = [
23 | "memchr",
24 | "minimal-lexical",
25 | ]
26 |
27 | [[package]]
28 | name = "num0_parser"
29 | version = "0.1.0"
30 | dependencies = [
31 | "nom",
32 | ]
33 |
--------------------------------------------------------------------------------
/28-nom/num1_parser/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "memchr"
7 | version = "2.6.4"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
10 |
11 | [[package]]
12 | name = "minimal-lexical"
13 | version = "0.2.1"
14 | source = "registry+https://github.com/rust-lang/crates.io-index"
15 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
16 |
17 | [[package]]
18 | name = "nom"
19 | version = "7.1.3"
20 | source = "registry+https://github.com/rust-lang/crates.io-index"
21 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
22 | dependencies = [
23 | "memchr",
24 | "minimal-lexical",
25 | ]
26 |
27 | [[package]]
28 | name = "num1_parser"
29 | version = "0.1.0"
30 | dependencies = [
31 | "nom",
32 | ]
33 |
--------------------------------------------------------------------------------
/28-nom/coordination/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "coordination"
7 | version = "0.1.0"
8 | dependencies = [
9 | "nom",
10 | ]
11 |
12 | [[package]]
13 | name = "memchr"
14 | version = "2.6.4"
15 | source = "registry+https://github.com/rust-lang/crates.io-index"
16 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
17 |
18 | [[package]]
19 | name = "minimal-lexical"
20 | version = "0.2.1"
21 | source = "registry+https://github.com/rust-lang/crates.io-index"
22 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
23 |
24 | [[package]]
25 | name = "nom"
26 | version = "7.1.3"
27 | source = "registry+https://github.com/rust-lang/crates.io-index"
28 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
29 | dependencies = [
30 | "memchr",
31 | "minimal-lexical",
32 | ]
33 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/.rustc_info.json:
--------------------------------------------------------------------------------
1 | {"rustc_fingerprint":729461393880023121,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.73.0 (cc66ad468 2023-10-03)\nbinary: rustc\ncommit-hash: cc66ad468955717ab92600c770da8c1601a4ff33\ncommit-date: 2023-10-03\nhost: x86_64-unknown-linux-gnu\nrelease: 1.73.0\nLLVM version: 17.0.2\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/mike/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp03_addlog/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::{response::Html, routing::get, Router};
2 | use tower_http::{
3 | services::{ServeDir, ServeFile},
4 | trace::TraceLayer,
5 | };
6 |
7 | #[tokio::main]
8 | async fn main() {
9 | tracing_subscriber::fmt::init();
10 |
11 | let serve_dir = ServeDir::new("assets").not_found_service(ServeFile::new("assets/index.html"));
12 | // build our application with a route
13 | let app = Router::new()
14 | .route("/foo", get(handler))
15 | .nest_service("/assets", serve_dir.clone())
16 | .fallback_service(serve_dir)
17 | .layer(TraceLayer::new_for_http());
18 |
19 | // run it
20 | let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
21 | .await
22 | .unwrap();
23 | tracing::debug!("listening on {}", listener.local_addr().unwrap());
24 | axum::serve(listener, app).await.unwrap();
25 | }
26 |
27 | async fn handler() -> Html<&'static str> {
28 | Html("Hello, World!
")
29 | }
30 |
--------------------------------------------------------------------------------
/14-getinfo/src/client_framed.rs:
--------------------------------------------------------------------------------
1 | use bytes::Bytes;
2 | use futures::{SinkExt, StreamExt};
3 | use std::env;
4 | use tokio::net::TcpStream;
5 | use tokio_util::codec::{Framed, LengthDelimitedCodec};
6 |
7 | #[tokio::main]
8 | async fn main() -> Result<(), Box> {
9 | let addr = env::args()
10 | .nth(1)
11 | .unwrap_or_else(|| "127.0.0.1:8888".to_string());
12 | // 连接到服务端
13 | let stream = TcpStream::connect(&addr).await?;
14 | // 包裹成 Frame stream
15 | let mut framed_stream = Framed::new(stream, LengthDelimitedCodec::new());
16 |
17 | // 发送指令
18 | framed_stream.send(Bytes::from("gettime")).await?;
19 |
20 | // 读取返回数据,这里只读一次
21 | if let Some(msg) = framed_stream.next().await {
22 | match msg {
23 | Ok(msg) => {
24 | let timeinfo = String::from_utf8(msg.to_vec())?;
25 | println!("{}", timeinfo);
26 | }
27 | Err(e) => return Err(e.into()),
28 | }
29 | }
30 |
31 | Ok(())
32 | }
33 |
--------------------------------------------------------------------------------
/30-ffi/word-count/README.md:
--------------------------------------------------------------------------------
1 | # word-count
2 |
3 | Demonstrates searching for a file in plain python, with rust singlethreaded and with rust multithreaded.
4 |
5 | ## Build
6 |
7 | ```shell
8 | pip install .
9 | ```
10 |
11 | ## Usage
12 |
13 | ```python
14 | from word_count import search_py, search, search_sequential
15 |
16 | search_py("foo bar", "foo")
17 | search("foo bar", "foo")
18 | search_sequential("foo bar", "foo")
19 | ```
20 |
21 | ## Testing
22 |
23 | To test install nox globally and run
24 |
25 | ```shell
26 | nox
27 | ```
28 |
29 | ## Benchmark
30 |
31 | To test install nox globally and run
32 |
33 | ```shell
34 | nox -s bench
35 | ```
36 |
37 | ## Copying this example
38 |
39 | Use [`cargo-generate`](https://crates.io/crates/cargo-generate):
40 |
41 | ```bash
42 | $ cargo install cargo-generate
43 | $ cargo generate --git https://github.com/PyO3/pyo3 examples/word-count
44 | ```
45 |
46 | (`cargo generate` will take a little while to clone the PyO3 repo first; be patient when waiting for the command to run.)
47 |
--------------------------------------------------------------------------------
/16-channel/src/main_a.rs:
--------------------------------------------------------------------------------
1 | use tokio::sync::mpsc;
2 |
3 | #[tokio::main]
4 | async fn main() {
5 | let mut db: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
6 | let (tx, mut rx) = mpsc::channel::(100);
7 |
8 | let tx1 = tx.clone();
9 | let tx2 = tx.clone();
10 |
11 | let task_a = tokio::task::spawn(async move {
12 | if let Err(_) = tx1.send(50).await {
13 | println!("receiver dropped");
14 | return;
15 | }
16 | });
17 | let task_b = tokio::task::spawn(async move {
18 | if let Err(_) = tx2.send(100).await {
19 | println!("receiver dropped");
20 | return;
21 | }
22 | });
23 |
24 | let task_c = tokio::task::spawn(async move {
25 | while let Some(i) = rx.recv().await {
26 | println!("got = {}", i);
27 | db[4] = i;
28 | println!("{:?}", db);
29 | }
30 | });
31 | _ = task_a.await.unwrap();
32 | _ = task_b.await.unwrap();
33 | _ = task_c.await.unwrap();
34 | }
35 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp09_template/src/main.rs:
--------------------------------------------------------------------------------
1 | use askama::Template;
2 | use axum::{
3 | extract::Path,
4 | http::StatusCode,
5 | response::IntoResponse,
6 | routing::get,
7 | Router,
8 | };
9 | use tower_http::trace::TraceLayer;
10 |
11 | #[tokio::main]
12 | async fn main() {
13 | tracing_subscriber::fmt::init();
14 |
15 | let app = Router::new()
16 | .route("/greet/:name", get(greet))
17 | .layer(TraceLayer::new_for_http())
18 | .fallback(handler_404);
19 |
20 | // run it
21 | let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
22 | .await
23 | .unwrap();
24 | tracing::debug!("listening on {}", listener.local_addr().unwrap());
25 | axum::serve(listener, app).await.unwrap();
26 | }
27 |
28 | #[derive(Template)]
29 | #[template(path = "hello.html")]
30 | struct HelloTemplate {
31 | name: String,
32 | }
33 |
34 | async fn greet(Path(name): Path) -> impl IntoResponse {
35 | HelloTemplate { name } .to_string()
36 | }
37 |
38 | async fn handler_404() -> impl IntoResponse {
39 | (StatusCode::NOT_FOUND, "nothing to see here")
40 | }
41 |
--------------------------------------------------------------------------------
/25-slint-chatbot-demo/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/27-bevy_snake/snake04_snakemove/src/main.rs:
--------------------------------------------------------------------------------
1 | use bevy::prelude::*;
2 |
3 | const SNAKE_HEAD_COLOR: Color = Color::rgb(0.7, 0.7, 0.7);
4 |
5 | #[derive(Component)]
6 | struct SnakeHead;
7 |
8 | fn main() {
9 | App::new()
10 | .add_plugins(DefaultPlugins)
11 | .add_systems(Startup, (setup_camera, spawn_snake))
12 | .add_systems(Update, snake_movement)
13 | .run();
14 | }
15 |
16 | fn setup_camera(mut commands: Commands) {
17 | commands.spawn(Camera2dBundle::default());
18 | }
19 |
20 | fn spawn_snake(mut commands: Commands) {
21 | commands
22 | .spawn(SpriteBundle {
23 | sprite: Sprite {
24 | color: SNAKE_HEAD_COLOR,
25 | ..default()
26 | },
27 | transform: Transform {
28 | scale: Vec3::new(10.0, 10.0, 10.0),
29 | ..default()
30 | },
31 | ..default()
32 | })
33 | .insert(SnakeHead);
34 | }
35 |
36 | fn snake_movement(mut head_positions: Query<(&SnakeHead, &mut Transform)>) {
37 | for (_head, mut transform) in head_positions.iter_mut() {
38 | transform.translation.y += 2.;
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/28-nom/color/src/main.rs:
--------------------------------------------------------------------------------
1 | use nom::{
2 | bytes::complete::{tag, take_while_m_n},
3 | combinator::map_res,
4 | sequence::Tuple,
5 | IResult,
6 | };
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct Color {
10 | pub red: u8,
11 | pub green: u8,
12 | pub blue: u8,
13 | }
14 |
15 | fn from_hex(input: &str) -> Result {
16 | u8::from_str_radix(input, 16)
17 | }
18 |
19 | fn is_hex_digit(c: char) -> bool {
20 | c.is_digit(16)
21 | }
22 |
23 | fn hex_primary(input: &str) -> IResult<&str, u8> {
24 | map_res(take_while_m_n(2, 2, is_hex_digit), from_hex)(input)
25 | }
26 |
27 | fn hex_color(input: &str) -> IResult<&str, Color> {
28 | let (input, _) = tag("#")(input)?;
29 | let (input, (red, green, blue)) = (hex_primary, hex_primary, hex_primary).parse(input)?;
30 | Ok((input, Color { red, green, blue }))
31 | }
32 |
33 | #[test]
34 | fn parse_color() {
35 | assert_eq!(
36 | hex_color("#2F14DF"),
37 | Ok((
38 | "",
39 | Color {
40 | red: 47,
41 | green: 20,
42 | blue: 223,
43 | }
44 | ))
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp04_query/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::{extract::Query, response::{Html, IntoResponse}, routing::get, Router};
2 | use serde::Deserialize;
3 | use tower_http::trace::TraceLayer;
4 |
5 | #[derive(Debug, Deserialize)]
6 | #[allow(dead_code)]
7 | struct Params {
8 | foo: i32,
9 | bar: String,
10 | aa: Option,
11 | }
12 |
13 | #[tokio::main]
14 | async fn main() {
15 | tracing_subscriber::fmt::init();
16 |
17 | // build our application with a route
18 | let app = Router::new()
19 | .route("/", get(handler))
20 | .route("/query", get(query))
21 | .layer(TraceLayer::new_for_http());
22 |
23 | // run it
24 | let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
25 | .await
26 | .unwrap();
27 | println!("listening on {}", listener.local_addr().unwrap());
28 | axum::serve(listener, app).await.unwrap();
29 | }
30 |
31 | async fn handler() -> Html<&'static str> {
32 | Html("Hello, World!
")
33 | }
34 |
35 | async fn query(Query(params): Query) -> impl IntoResponse {
36 | tracing::debug!("query params {:?}", params);
37 | Html("Test query
")
38 | }
39 |
--------------------------------------------------------------------------------
/16-channel/src/main_b.rs:
--------------------------------------------------------------------------------
1 | use std::time::Duration;
2 | use tokio::sync::mpsc;
3 | use tokio::task;
4 | use tokio::time;
5 |
6 | #[tokio::main]
7 | async fn main() {
8 | let mut db: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
9 | let (tx, mut rx) = mpsc::channel::(100);
10 |
11 | let tx1 = tx.clone();
12 | let tx2 = tx.clone();
13 |
14 | let task_a = task::spawn(async move {
15 | println!("in task_a 1");
16 | time::sleep(Duration::from_secs(3)).await;
17 | println!("in task_a 2");
18 | if let Err(_) = tx1.send(50).await {
19 | println!("receiver dropped");
20 | return;
21 | }
22 | });
23 | let task_b = task::spawn(async move {
24 | println!("in task_b");
25 | if let Err(_) = tx2.send(100).await {
26 | println!("receiver dropped");
27 | return;
28 | }
29 | });
30 |
31 | let task_c = task::spawn(async move {
32 | while let Some(i) = rx.recv().await {
33 | println!("got = {}", i);
34 | db[4] = i;
35 | println!("{:?}", db);
36 | }
37 | });
38 |
39 | _ = task_c.await.unwrap();
40 | _ = task_a.await.unwrap();
41 | _ = task_b.await.unwrap();
42 | }
43 |
--------------------------------------------------------------------------------
/28-nom/coordination/src/main.rs:
--------------------------------------------------------------------------------
1 | use nom::bytes::complete::tag;
2 | use nom::sequence::{delimited, separated_pair};
3 | use nom::IResult;
4 | use std::error::Error;
5 |
6 | #[derive(Debug, PartialEq)]
7 | pub struct Coordinate {
8 | pub x: i32,
9 | pub y: i32,
10 | }
11 |
12 | use nom::character::complete::i32;
13 |
14 | fn parse_integer_pair(input: &str) -> IResult<&str, (i32, i32)> {
15 | separated_pair(i32, tag(", "), i32)(input)
16 | }
17 |
18 | fn parse_coordinate(input: &str) -> IResult<&str, Coordinate> {
19 | let (remaining, (x, y)) = delimited(tag("("), parse_integer_pair, tag(")"))(input)?;
20 |
21 | Ok((remaining, Coordinate { x, y }))
22 | }
23 |
24 | fn main() -> Result<(), Box> {
25 | let (_, parsed) = parse_coordinate("(3, 5)")?;
26 | assert_eq!(parsed, Coordinate { x: 3, y: 5 });
27 |
28 | let (_, parsed) = parse_coordinate("(2, -4)")?;
29 | assert_eq!(parsed, Coordinate { x: 2, y: -4 });
30 |
31 | let parsing_error = parse_coordinate("(3,)");
32 | assert!(parsing_error.is_err());
33 |
34 | let parsing_error = parse_coordinate("(,3)");
35 | assert!(parsing_error.is_err());
36 |
37 | let parsing_error = parse_coordinate("Ferris");
38 | assert!(parsing_error.is_err());
39 |
40 | Ok(())
41 | }
42 |
--------------------------------------------------------------------------------
/14-getinfo/src/client.rs:
--------------------------------------------------------------------------------
1 | use std::env;
2 | use tokio::io::{AsyncReadExt, AsyncWriteExt};
3 | use tokio::net::TcpStream;
4 |
5 | #[tokio::main]
6 | async fn main() -> Result<(), Box> {
7 | let addr = env::args()
8 | .nth(1)
9 | .unwrap_or_else(|| "127.0.0.1:8888".to_string());
10 | // 连接到服务端
11 | let mut stream = TcpStream::connect(&addr).await?;
12 |
13 | // 写入指令数据,这是一种最简单的协议.
14 | stream.write_all(b"gettime").await?;
15 |
16 | // 等待tcp server的回复,读取内容
17 | // 这里用动态数组来存储从服务端返回的内容
18 | let mut buf: Vec = Vec::with_capacity(8128);
19 | // 读取的缓冲区
20 | let mut resp = [0u8; 2048];
21 | loop {
22 | // 尝试一次读,返回读到的字节数
23 | let n = stream.read(&mut resp).await?;
24 | // 将读到的字节合并到buf中去
25 | buf.extend_from_slice(&resp[0..n]);
26 | if n == 0 {
27 | // 流断掉了
28 | panic!("Unexpected EOF");
29 | } else if buf.len() >= 28 {
30 | // like: "Tue Oct 31 14:56:27 CST 2023"
31 | // buf 已经填充了足够的内容
32 | break;
33 | } else {
34 | // buf 中还没有足够多的内容,继续填充...
35 | continue;
36 | }
37 | }
38 |
39 | // 转换并打印返回的信息
40 | let timeinfo = String::from_utf8(buf)?;
41 | println!("{}", timeinfo);
42 |
43 | Ok(())
44 | }
45 |
--------------------------------------------------------------------------------
/30-ffi/word-count/src/lib.rs:
--------------------------------------------------------------------------------
1 | use pyo3::prelude::*;
2 | use rayon::prelude::*;
3 |
4 | /// Searches for the word, parallelized by rayon
5 | #[pyfunction]
6 | fn search(contents: &str, needle: &str) -> usize {
7 | contents
8 | .par_lines()
9 | .map(|line| count_line(line, needle))
10 | .sum()
11 | }
12 |
13 | /// Searches for a word in a classic sequential fashion
14 | #[pyfunction]
15 | fn search_sequential(contents: &str, needle: &str) -> usize {
16 | contents.lines().map(|line| count_line(line, needle)).sum()
17 | }
18 |
19 | #[pyfunction]
20 | fn search_sequential_allow_threads(py: Python<'_>, contents: &str, needle: &str) -> usize {
21 | py.allow_threads(|| search_sequential(contents, needle))
22 | }
23 |
24 | /// Count the occurrences of needle in line, case insensitive
25 | fn count_line(line: &str, needle: &str) -> usize {
26 | let mut total = 0;
27 | for word in line.split(' ') {
28 | if word == needle {
29 | total += 1;
30 | }
31 | }
32 | total
33 | }
34 |
35 | #[pymodule]
36 | fn word_count(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
37 | m.add_function(wrap_pyfunction!(search, m)?)?;
38 | m.add_function(wrap_pyfunction!(search_sequential, m)?)?;
39 | m.add_function(wrap_pyfunction!(search_sequential_allow_threads, m)?)?;
40 |
41 | Ok(())
42 | }
43 |
--------------------------------------------------------------------------------
/30-ffi/rust_call_c/src/main.rs:
--------------------------------------------------------------------------------
1 | use std::fmt;
2 |
3 | // this extern block links to the libm library
4 | #[link(name = "m")]
5 | extern "C" {
6 | // this is a foreign function
7 | // that computes the square root of a single precision complex number
8 | fn csqrtf(z: Complex) -> Complex;
9 |
10 | fn ccosf(z: Complex) -> Complex;
11 | }
12 |
13 | // Since calling foreign functions is considered unsafe,
14 | // it's common to write safe wrappers around them.
15 | fn cos(z: Complex) -> Complex {
16 | unsafe { ccosf(z) }
17 | }
18 |
19 | fn main() {
20 | // z = -1 + 0i
21 | let z = Complex { re: -1., im: 0. };
22 |
23 | // calling a foreign function is an unsafe operation
24 | let z_sqrt = unsafe { csqrtf(z) };
25 |
26 | println!("the square root of {:?} is {:?}", z, z_sqrt);
27 |
28 | // calling safe API wrapped around unsafe operation
29 | println!("cos({:?}) = {:?}", z, cos(z));
30 | }
31 |
32 | // Minimal implementation of single precision complex numbers
33 | #[repr(C)]
34 | #[derive(Clone, Copy)]
35 | struct Complex {
36 | re: f32,
37 | im: f32,
38 | }
39 |
40 | impl fmt::Debug for Complex {
41 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 | if self.im < 0. {
43 | write!(f, "{}-{}i", self.re, -self.im)
44 | } else {
45 | write!(f, "{}+{}i", self.re, self.im)
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/25-slint-chatbot-demo/ui/appwindow.slint:
--------------------------------------------------------------------------------
1 | import { Button, VerticalBox, TextEdit } from "std-widgets.slint";
2 |
3 | export component AppWindow inherits Window {
4 | title: "OpenChat Bot";
5 | width: 500px;
6 | height: 550px;
7 | forward-focus: ed2;
8 | // in-out property counter: 42;
9 | in-out property dialog;
10 | in-out property input-ask;
11 |
12 | // callback request-increase-value();
13 | callback send-ask-content(string);
14 |
15 | VerticalBox {
16 | Text {
17 | // text: "Model: openchat_3.5.Q8_0.gguf";
18 | text: "Model: openchat_3.5.Q4_K_M.gguf";
19 | }
20 | ed1 := TextEdit {
21 | font-size: 15px;
22 | width: parent.width - 20px;
23 | // height: parent.height - 200px;
24 | vertical-stretch: 1;
25 | read-only: true;
26 | text: root.dialog;
27 | }
28 | ed2 := TextEdit {
29 | font-size: 15px;
30 | width: parent.width - 20px;
31 | height: 100px;
32 | text <=> root.input-ask;
33 | }
34 | Button {
35 | text: "Send";
36 | clicked => {
37 | // root.request-increase-value();
38 | root.send-ask-content(root.input-ask);
39 | ed2.text = "";
40 | // root.update-dialog-content("test ");
41 | // root.dialog = root.dialog + "test ";
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/25-slint-chatbot-demo/README.md:
--------------------------------------------------------------------------------
1 | # Slint Chatbot Demo
2 |
3 | This is a demo of Rust + Slint + Candle + OpenChat LLM, it looks like this:
4 |
5 | 
6 |
7 | ## Do it by yourself
8 |
9 | Make sure you have downloaded `openchat_3.5.Q4_K_M.gguf` and `tokenizer.json` by:
10 |
11 | ```
12 | HF_HUB_ENABLE_HF_TRANSFER=1 HF_ENDPOINT=https://hf-mirror.com huggingface-cli download TheBloke/openchat_3.5-GGUF openchat_3.5.Q4_K_M.gguf
13 | HF_HUB_ENABLE_HF_TRANSFER=1 HF_ENDPOINT=https://hf-mirror.com huggingface-cli download openchat/openchat_3.5 tokenizer.json
14 | ```
15 | The downloads locate at `~/.cache/huggingface/hub/`.
16 |
17 | Copy them to the root of the current project directory, like the following:
18 |
19 | ```
20 | $ ls -lh
21 | total 12G
22 | -rw-r--r-- 1 daoga 197609 71 12月 6 12:34 build.rs
23 | -rw-r--r-- 1 daoga 197609 141K 12月 7 17:37 Cargo.lock
24 | -rw-r--r-- 1 daoga 197609 436 12月 7 17:36 Cargo.toml
25 | -rw-r--r-- 1 daoga 197609 1.1K 12月 6 12:34 LICENSE
26 | -rw-r--r-- 1 daoga 197609 4.1G 12月 7 15:31 openchat_3.5.Q4_K_M.gguf
27 | -rw-r--r-- 1 daoga 197609 7.2G 12月 7 15:53 openchat_3.5.Q8_0.gguf
28 | -rw-r--r-- 1 daoga 197609 468 12月 7 17:39 README.md
29 | drwxr-xr-x 1 daoga 197609 0 12月 7 15:07 src/
30 | drwxr-xr-x 1 daoga 197609 0 12月 6 16:49 target/
31 | -rw-r--r-- 1 daoga 197609 1.8M 12月 7 15:30 tokenizer.json
32 | drwxr-xr-x 1 daoga 197609 0 12月 6 12:34 ui/
33 | ```
34 |
35 | and then
36 |
37 | ```
38 | cargo run --release
39 | ```
40 |
41 | You will look at a GUI app poped up, good luck!
42 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/README.md:
--------------------------------------------------------------------------------
1 | # Slint Chatbot Demo
2 |
3 | This is a demo of Rust + Slint + Candle + Yolov8, it looks like this:
4 |
5 | 
6 | 
7 |
8 | ## Do it by yourself
9 |
10 | Make sure you have downloaded `yolov8m.safetensors` and `yolov8m-pose.safetensors` by:
11 |
12 | ```
13 | HF_HUB_ENABLE_HF_TRANSFER=1 HF_ENDPOINT=https://hf-mirror.com huggingface-cli download lmz/candle-yolo-v8 yolov8m.safetensors
14 | HF_HUB_ENABLE_HF_TRANSFER=1 HF_ENDPOINT=https://hf-mirror.com huggingface-cli download lmz/candle-yolo-v8 yolov8m-pose.safetensors
15 | ```
16 | The downloads locate at `~/.cache/huggingface/hub/`.
17 |
18 | Copy them to the root of the current project directory, like follows:
19 |
20 | ```
21 | $ ls -lh
22 | total 101M
23 | -rwxr-xr-x 1 mike mike 150K Dec 9 14:58 Cargo.lock
24 | -rwxr-xr-x 1 mike mike 615 Dec 9 14:58 Cargo.toml
25 | -rwxr-xr-x 1 mike mike 1.1K Dec 9 14:58 LICENSE
26 | -rwxr-xr-x 1 mike mike 747 Dec 9 18:29 README.md
27 | drwxr-xr-x 2 mike mike 4.0K Dec 9 18:27 assets
28 | -rwxr-xr-x 1 mike mike 71 Dec 9 14:58 build.rs
29 | -rwxr-xr-x 1 mike mike 168K Dec 9 14:58 football.jpg
30 | drwxr-xr-x 3 mike mike 4.0K Dec 9 14:58 src
31 | drwxr-xr-x 4 mike mike 4.0K Dec 9 15:03 target
32 | drwxr-xr-x 2 mike mike 4.0K Dec 9 14:58 ui
33 | -rw-r--r-- 1 mike mike 51M Dec 9 17:45 yolov8m-pose.safetensors
34 | -rw-r--r-- 1 mike mike 50M Dec 9 17:45 yolov8m.safetensors
35 | ```
36 |
37 | and then
38 |
39 | ```
40 | cargo run --release
41 | ```
42 |
43 | You will look at a GUI app popped up, good luck!
44 |
--------------------------------------------------------------------------------
/24-candle_yolov8/src/coco_classes.rs:
--------------------------------------------------------------------------------
1 | pub const NAMES: [&str; 80] = [
2 | "person",
3 | "bicycle",
4 | "car",
5 | "motorbike",
6 | "aeroplane",
7 | "bus",
8 | "train",
9 | "truck",
10 | "boat",
11 | "traffic light",
12 | "fire hydrant",
13 | "stop sign",
14 | "parking meter",
15 | "bench",
16 | "bird",
17 | "cat",
18 | "dog",
19 | "horse",
20 | "sheep",
21 | "cow",
22 | "elephant",
23 | "bear",
24 | "zebra",
25 | "giraffe",
26 | "backpack",
27 | "umbrella",
28 | "handbag",
29 | "tie",
30 | "suitcase",
31 | "frisbee",
32 | "skis",
33 | "snowboard",
34 | "sports ball",
35 | "kite",
36 | "baseball bat",
37 | "baseball glove",
38 | "skateboard",
39 | "surfboard",
40 | "tennis racket",
41 | "bottle",
42 | "wine glass",
43 | "cup",
44 | "fork",
45 | "knife",
46 | "spoon",
47 | "bowl",
48 | "banana",
49 | "apple",
50 | "sandwich",
51 | "orange",
52 | "broccoli",
53 | "carrot",
54 | "hot dog",
55 | "pizza",
56 | "donut",
57 | "cake",
58 | "chair",
59 | "sofa",
60 | "pottedplant",
61 | "bed",
62 | "diningtable",
63 | "toilet",
64 | "tvmonitor",
65 | "laptop",
66 | "mouse",
67 | "remote",
68 | "keyboard",
69 | "cell phone",
70 | "microwave",
71 | "oven",
72 | "toaster",
73 | "sink",
74 | "refrigerator",
75 | "book",
76 | "clock",
77 | "vase",
78 | "scissors",
79 | "teddy bear",
80 | "hair drier",
81 | "toothbrush",
82 | ];
83 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/src/yolov8engine/coco_classes.rs:
--------------------------------------------------------------------------------
1 | pub const NAMES: [&str; 80] = [
2 | "person",
3 | "bicycle",
4 | "car",
5 | "motorbike",
6 | "aeroplane",
7 | "bus",
8 | "train",
9 | "truck",
10 | "boat",
11 | "traffic light",
12 | "fire hydrant",
13 | "stop sign",
14 | "parking meter",
15 | "bench",
16 | "bird",
17 | "cat",
18 | "dog",
19 | "horse",
20 | "sheep",
21 | "cow",
22 | "elephant",
23 | "bear",
24 | "zebra",
25 | "giraffe",
26 | "backpack",
27 | "umbrella",
28 | "handbag",
29 | "tie",
30 | "suitcase",
31 | "frisbee",
32 | "skis",
33 | "snowboard",
34 | "sports ball",
35 | "kite",
36 | "baseball bat",
37 | "baseball glove",
38 | "skateboard",
39 | "surfboard",
40 | "tennis racket",
41 | "bottle",
42 | "wine glass",
43 | "cup",
44 | "fork",
45 | "knife",
46 | "spoon",
47 | "bowl",
48 | "banana",
49 | "apple",
50 | "sandwich",
51 | "orange",
52 | "broccoli",
53 | "carrot",
54 | "hot dog",
55 | "pizza",
56 | "donut",
57 | "cake",
58 | "chair",
59 | "sofa",
60 | "pottedplant",
61 | "bed",
62 | "diningtable",
63 | "toilet",
64 | "tvmonitor",
65 | "laptop",
66 | "mouse",
67 | "remote",
68 | "keyboard",
69 | "cell phone",
70 | "microwave",
71 | "oven",
72 | "toaster",
73 | "sink",
74 | "refrigerator",
75 | "book",
76 | "clock",
77 | "vase",
78 | "scissors",
79 | "teddy bear",
80 | "hair drier",
81 | "toothbrush",
82 | ];
83 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "lldb",
9 | "request": "launch",
10 | "name": "Debug executable 'slint-yolov8-demo'",
11 | "cargo": {
12 | "args": [
13 | "build",
14 | "--bin=slint-yolov8-demo",
15 | "--package=slint-yolov8-demo"
16 | ],
17 | "filter": {
18 | "name": "slint-yolov8-demo",
19 | "kind": "bin"
20 | }
21 | },
22 | "args": [],
23 | "cwd": "${workspaceFolder}"
24 | },
25 | {
26 | "type": "lldb",
27 | "request": "launch",
28 | "name": "Debug unit tests in executable 'slint-yolov8-demo'",
29 | "cargo": {
30 | "args": [
31 | "test",
32 | "--no-run",
33 | "--bin=slint-yolov8-demo",
34 | "--package=slint-yolov8-demo"
35 | ],
36 | "filter": {
37 | "name": "slint-yolov8-demo",
38 | "kind": "bin"
39 | }
40 | },
41 | "args": [],
42 | "cwd": "${workspaceFolder}"
43 | }
44 | ]
45 | }
--------------------------------------------------------------------------------
/25-slint-chatbot-demo/src/main.rs:
--------------------------------------------------------------------------------
1 | #![allow(unused)]
2 |
3 | use std::sync::mpsc::channel;
4 |
5 | mod token_output_stream;
6 | mod llmengin;
7 |
8 | slint::include_modules!();
9 |
10 | fn main() -> Result<(), slint::PlatformError> {
11 | let ui = AppWindow::new()?;
12 |
13 | let ui_handle = ui.as_weak();
14 | let (sender, receiver) = channel::();
15 | let sender1 = sender.clone();
16 |
17 | let _thread = std::thread::spawn(move || {
18 |
19 | if let Err(_) = llmengin::start_engine(ui_handle, receiver) {
20 | // process before exit.
21 | }
22 | });
23 |
24 | let ui_handle = ui.as_weak();
25 | ui.on_send_ask_content(move |content| {
26 | update_dialog(ui_handle.clone(), content.to_string());
27 | sender.send(content.to_string()).unwrap();
28 | });
29 |
30 | ui.window().on_close_requested(move || {
31 | sender1.send("_exit_".to_string()).unwrap();
32 | slint::CloseRequestResponse::HideWindow
33 | });
34 |
35 | ui.run()
36 | }
37 |
38 | fn update_dialog(ui_handle: slint::Weak, msg: String) {
39 | _ = slint::invoke_from_event_loop(move || {
40 | let ui_handle = ui_handle.unwrap();
41 | let old_content = ui_handle.get_dialog();
42 | ui_handle.set_dialog(old_content + &msg + "\n");
43 | });
44 | }
45 |
46 | fn update_dialog_without_ln(ui_handle: slint::Weak, msg: String) {
47 | _ = slint::invoke_from_event_loop(move || {
48 | let ui_handle = ui_handle.unwrap();
49 | let old_content = ui_handle.get_dialog();
50 | ui_handle.set_dialog(old_content + &msg);
51 | });
52 | }
--------------------------------------------------------------------------------
/27-bevy_snake/snake05_snakecontrol/src/main.rs:
--------------------------------------------------------------------------------
1 | use bevy::prelude::*;
2 |
3 | const SNAKE_HEAD_COLOR: Color = Color::rgb(0.7, 0.7, 0.7);
4 |
5 | #[derive(Component)]
6 | struct SnakeHead;
7 |
8 | fn main() {
9 | App::new()
10 | .add_plugins(DefaultPlugins)
11 | .add_systems(Startup, (setup_camera, spawn_snake))
12 | .add_systems(Update, snake_movement)
13 | .run();
14 | }
15 |
16 | fn setup_camera(mut commands: Commands) {
17 | commands.spawn(Camera2dBundle::default());
18 | }
19 |
20 | fn spawn_snake(mut commands: Commands) {
21 | commands
22 | .spawn(SpriteBundle {
23 | sprite: Sprite {
24 | color: SNAKE_HEAD_COLOR,
25 | ..default()
26 | },
27 | transform: Transform {
28 | scale: Vec3::new(10.0, 10.0, 10.0),
29 | ..default()
30 | },
31 | ..default()
32 | })
33 | .insert(SnakeHead);
34 | }
35 |
36 | fn snake_movement(
37 | keyboard_input: Res>,
38 | mut head_positions: Query<&mut Transform, With>,
39 | ) {
40 | for mut transform in head_positions.iter_mut() {
41 | if keyboard_input.pressed(KeyCode::Left) {
42 | transform.translation.x -= 2.;
43 | }
44 | if keyboard_input.pressed(KeyCode::Right) {
45 | transform.translation.x += 2.;
46 | }
47 | if keyboard_input.pressed(KeyCode::Down) {
48 | transform.translation.y -= 2.;
49 | }
50 | if keyboard_input.pressed(KeyCode::Up) {
51 | transform.translation.y += 2.;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/26-slint-yolov8-demo/ui/appwindow.slint:
--------------------------------------------------------------------------------
1 | import { Button, VerticalBox , HorizontalBox} from "std-widgets.slint";
2 |
3 | export component AppWindow inherits Window {
4 | width: 900px;
5 | height: 480px;
6 |
7 | in-out property orig-image;
8 | in-out property orig-image-path;
9 |
10 | in-out property generated-image;
11 |
12 | callback select-orig-pic();
13 | callback probe-objects();
14 | callback probe-poses();
15 |
16 | VerticalBox {
17 | width: 100%;
18 | vertical-stretch: 1;
19 | Text {
20 | text: "Model Size: Medium";
21 | }
22 | HorizontalBox {
23 | width: 98%;
24 | vertical-stretch: 1;
25 | Image {
26 | width: 49%;
27 | source: root.orig-image;
28 |
29 | }
30 | Rectangle {
31 | width: 1px;
32 | background: gray;
33 | }
34 | Image {
35 | width: 49%;
36 | source: root.generated-image;
37 | }
38 | }
39 | HorizontalBox {
40 | alignment: start;
41 | height: 50px;
42 | Button {
43 | text: "Select Picture..";
44 | clicked => {
45 | root.select-orig-pic();
46 | }
47 | }
48 | Button {
49 | text: "Detect Objects";
50 | clicked => {
51 | root.probe-objects();
52 | }
53 | }
54 | Button {
55 | text: "Detect Poses";
56 | clicked => {
57 | root.probe-poses();
58 | }
59 | }
60 | }
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/16-channel/src/main_d.rs:
--------------------------------------------------------------------------------
1 | use std::time::Duration;
2 | use tokio::sync::{mpsc, oneshot};
3 | use tokio::task;
4 | use tokio::time;
5 |
6 | #[tokio::main]
7 | async fn main() {
8 | let mut db: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
9 | let (tx, mut rx) = mpsc::channel::<(u32, oneshot::Sender)>(100);
10 |
11 | let tx1 = tx.clone();
12 | let tx2 = tx.clone();
13 |
14 | let task_a = task::spawn(async move {
15 | time::sleep(Duration::from_secs(3)).await;
16 | let (resp_tx, resp_rx) = oneshot::channel();
17 | if let Err(_) = tx1.send((50, resp_tx)).await {
18 | println!("receiver dropped");
19 | return;
20 | }
21 | if let Ok(ret) = resp_rx.await {
22 | if ret {
23 | println!("task_a finished with success.");
24 | } else {
25 | println!("task_a finished with failure.");
26 | }
27 | } else {
28 | println!("oneshot sender dropped");
29 | return;
30 | }
31 | });
32 | let task_b = task::spawn(async move {
33 | let (resp_tx, resp_rx) = oneshot::channel();
34 | if let Err(_) = tx2.send((100, resp_tx)).await {
35 | println!("receiver dropped");
36 | return;
37 | }
38 | if let Ok(ret) = resp_rx.await {
39 | if ret {
40 | println!("task_b finished with success.");
41 | } else {
42 | println!("task_b finished with failure.");
43 | }
44 | } else {
45 | println!("oneshot sender dropped");
46 | return;
47 | }
48 | });
49 |
50 | let task_c = task::spawn(async move {
51 | while let Some((i, resp_tx)) = rx.recv().await {
52 | println!("got = {}", i);
53 | db[4] = i;
54 | println!("{:?}", db);
55 | resp_tx.send(true).unwrap();
56 | }
57 | });
58 |
59 | _ = task_a.await.unwrap();
60 | _ = task_b.await.unwrap();
61 | _ = task_c.await.unwrap();
62 | }
63 |
--------------------------------------------------------------------------------
/24-candle_yolov8/README.md:
--------------------------------------------------------------------------------
1 |
2 | # candle-yolo-v8
3 |
4 | ```bash
5 | cargo run --release -- assets/football.jpg
6 | # or
7 | cargo run --release -- assets/football.jpg --task pose
8 | ```
9 |
10 |
11 |
12 | ## candle-yolo-v8: Object Detection and Pose Estimation
13 |
14 | This is a port of [Ultralytics
15 | YOLOv8](https://github.com/ultralytics/ultralytics). The implementation is based
16 | on the [tinygrad
17 | version](https://github.com/tinygrad/tinygrad/blob/master/examples/yolov8.py)
18 | and on the model architecture described in this
19 | [issue](https://github.com/ultralytics/ultralytics/issues/189). The supported
20 | tasks are object detection and pose estimation.
21 |
22 | You can try this model online on the [Candle YOLOv8
23 | Space](https://huggingface.co/spaces/lmz/candle-yolo). The model then fully runs
24 | in your browser using WebAssembly - if you use a custom image it will never
25 | leave your phone/computer!
26 |
27 | ## Running some example
28 |
29 | ### Object Detection
30 | ```bash
31 | cargo run --example yolo-v8 --release -- candle-examples/examples/yolo-v8/assets/bike.jpg
32 | ```
33 |
34 | This prints details about the detected objects and generates a `bike.pp.jpg` file.
35 |
36 | 
37 |
38 | Image source:
39 | [wikimedia](https://commons.wikimedia.org/wiki/File:Leading_group,_Giro_d%27Italia_2021,_Stage_15.jpg).
40 |
41 | 
42 |
43 | ### Pose Estimation
44 | ```bash
45 | cargo run --example yolo-v8 --release -- \
46 | candle-examples/examples/yolo-v8/assets/bike.jpg --task pose
47 | ```
48 |
49 | 
50 |
51 | ### Command-line flags
52 |
53 | - `--which`: select the model variant to be used, `n`, `s` , `m`, `l`, or `x` by
54 | increasing size and quality.
55 | - `--task`: `detect` for object detection and `pose` for pose estimation.
56 | - `--legend-size`: the size of the characters to print.
57 | - `--model`: use a local model file rather than downloading it from the hub.
58 |
59 |
--------------------------------------------------------------------------------
/14-getinfo/src/server_framed.rs:
--------------------------------------------------------------------------------
1 | use bytes::Bytes;
2 | use futures::{SinkExt, StreamExt};
3 | use std::env;
4 | use tokio::net::TcpListener;
5 | use tokio::process::Command;
6 | use tokio_util::codec::{Framed, LengthDelimitedCodec};
7 |
8 | #[tokio::main]
9 | async fn main() -> Result<(), Box> {
10 | let addr = env::args()
11 | .nth(1)
12 | .unwrap_or_else(|| "127.0.0.1:8888".to_string());
13 | println!("Listening on: {}", addr);
14 | let listener = TcpListener::bind(&addr).await?;
15 |
16 | // 注意这里是一个无条件循环,表明始终处于服务状态
17 | loop {
18 | // 等待客户端请求连上来
19 | let (stream, _) = listener.accept().await?;
20 | // 包裹成一个Frame stream
21 | let mut framed_stream = Framed::new(stream, LengthDelimitedCodec::new());
22 |
23 | // 创建子task执行任务
24 | tokio::spawn(async move {
25 | // 等待读取一个一个msg,如果返回None,会退出这个循环
26 | while let Some(msg) = framed_stream.next().await {
27 | match msg {
28 | Ok(msg) => {
29 | // 解析指令,执行任务
30 | let directive = String::from_utf8(msg.to_vec())
31 | .expect("error when converting to string directive.");
32 | println!("{directive}");
33 | let output = process(&directive).await;
34 | println!("{output}");
35 |
36 | // 返回执行结果
37 | _ = framed_stream.send(Bytes::from(output)).await;
38 | }
39 | Err(e) => {
40 | println!("{e:?}");
41 | }
42 | }
43 | }
44 | });
45 | }
46 | }
47 |
48 | async fn process(directive: &str) -> String {
49 | if directive == "gettime" {
50 | // 这里我们用了unwrap()是因为我们一般确信执行date命令不会失败
51 | // 更可靠的作法是对返回的Result作处理
52 | let output = Command::new("date").output().await.unwrap();
53 | String::from_utf8(output.stdout).unwrap()
54 | } else {
55 | // 如果是其它指令,我们目前返回 无效指令
56 | "invalid command".to_owned()
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp10_db/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::{
2 | extract::State,
3 | http::StatusCode,
4 | response::{Html, IntoResponse},
5 | routing::get,
6 | Router,
7 | };
8 | use bb8::Pool;
9 | use bb8_postgres::PostgresConnectionManager;
10 | use tokio_postgres::NoTls;
11 | use tower_http::trace::TraceLayer;
12 |
13 | type ConnectionPool = Pool>;
14 |
15 |
16 | #[tokio::main]
17 | async fn main() {
18 | tracing_subscriber::fmt::init();
19 |
20 | let manager = PostgresConnectionManager::new_from_stringlike(
21 | "host=localhost user=postgres dbname=postgres password=123456",
22 | NoTls,
23 | )
24 | .unwrap();
25 |
26 | let pool = Pool::builder().build(manager).await.unwrap();
27 |
28 | let app = Router::new()
29 | .route("/", get(handler))
30 | .route("/query_from_db", get(query_from_db))
31 | .layer(TraceLayer::new_for_http())
32 | .fallback(handler_404)
33 | .with_state(pool);
34 |
35 | // run it
36 | let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
37 | .await
38 | .unwrap();
39 | tracing::debug!("listening on {}", listener.local_addr().unwrap());
40 | axum::serve(listener, app).await.unwrap();
41 | }
42 |
43 | async fn handler() -> Html<&'static str> {
44 | Html("Hello, World!
")
45 | }
46 |
47 | async fn handler_404() -> impl IntoResponse {
48 | (StatusCode::NOT_FOUND, "nothing to see here")
49 | }
50 |
51 | async fn query_from_db(State(pool): State) -> Result {
52 | tracing::debug!("get db conn {:?}", pool);
53 | let conn = pool.get().await.map_err(internal_error)?;
54 |
55 | tracing::debug!("query_from_db: 1");
56 | let row = conn
57 | .query_one("select 1 + 1", &[])
58 | .await
59 | .map_err(internal_error)?;
60 | tracing::debug!("query_from_db: 2");
61 |
62 | let two: i32 = row.try_get(0).map_err(internal_error)?;
63 | tracing::debug!("query_from_db: 3");
64 | tracing::debug!("calc_result {:?}", two);
65 |
66 | Ok(two.to_string())
67 | }
68 |
69 | fn internal_error(err: E) -> (StatusCode, String)
70 | where
71 | E: std::error::Error,
72 | {
73 | (StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
74 | }
75 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp05_form/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::{
2 | extract::{Form, Query},
3 | response::Html,
4 | routing::get,
5 | Router,
6 | };
7 | use serde::Deserialize;
8 | use tower_http::trace::TraceLayer;
9 |
10 | #[allow(dead_code)]
11 | #[derive(Debug, Deserialize)]
12 | struct Params {
13 | foo: Option,
14 | bar: Option,
15 | }
16 |
17 | #[tokio::main]
18 | async fn main() {
19 | tracing_subscriber::fmt::init();
20 |
21 | let app = Router::new()
22 | .route("/", get(handler))
23 | .route("/query", get(query))
24 | .route("/form", get(show_form).post(accept_form))
25 | .layer(TraceLayer::new_for_http());
26 |
27 | // run it
28 | let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
29 | .await
30 | .unwrap();
31 | tracing::debug!("listening on {}", listener.local_addr().unwrap());
32 | axum::serve(listener, app).await.unwrap();
33 | }
34 |
35 | async fn handler() -> Html<&'static str> {
36 | Html("Hello, World!
")
37 | }
38 |
39 | async fn query(Query(params): Query) -> Html<&'static str> {
40 | tracing::debug!("query params {:?}", params);
41 | Html("Test query
")
42 | }
43 |
44 | async fn show_form() -> Html<&'static str> {
45 | Html(
46 | r#"
47 |
48 |
49 |
50 |
51 |
64 |
65 |
66 | "#,
67 | )
68 | }
69 |
70 | #[allow(dead_code)]
71 | #[derive(Deserialize, Debug)]
72 | struct Input {
73 | name: String,
74 | email: String,
75 | }
76 |
77 | async fn accept_form(Form(input): Form) -> Html<&'static str> {
78 | tracing::debug!("form params {:?}", input);
79 |
80 | Html("Form posted
")
81 | }
82 |
83 |
--------------------------------------------------------------------------------
/30-ffi/word-count/tests/test_word_count.py:
--------------------------------------------------------------------------------
1 | from concurrent.futures import ThreadPoolExecutor
2 |
3 | import pytest
4 | import word_count
5 |
6 | NT = 10
7 |
8 | @pytest.fixture(scope="session")
9 | def contents() -> str:
10 | text = """
11 | The Zen of Python, by Tim Peters
12 |
13 | Beautiful is better than ugly.
14 | Explicit is better than implicit.
15 | Simple is better than complex.
16 | Complex is better than complicated.
17 | Flat is better than nested.
18 | Sparse is better than dense.
19 | Readability counts.
20 | Special cases aren't special enough to break the rules.
21 | Although practicality beats purity.
22 | Errors should never pass silently.
23 | Unless explicitly silenced.
24 | In the face of ambiguity, refuse the temptation to guess.
25 | There should be one-- and preferably only one --obvious way to do it.
26 | Although that way may not be obvious at first unless you're Dutch.
27 | Now is better than never.
28 | Although never is often better than *right* now.
29 | If the implementation is hard to explain, it's a bad idea.
30 | If the implementation is easy to explain, it may be a good idea.
31 | Namespaces are one honking great idea -- let's do more of those!
32 | """
33 | return text * 1000 * NT
34 |
35 |
36 | def test_word_count_rust_parallel(benchmark, contents):
37 | count = benchmark(word_count.search, contents, "is")
38 | assert count == 10000 * NT
39 |
40 |
41 | def test_word_count_rust_sequential(benchmark, contents):
42 | count = benchmark(word_count.search_sequential, contents, "is")
43 | assert count == 10000 * NT
44 |
45 |
46 | def test_word_count_python_sequential(benchmark, contents):
47 | count = benchmark(word_count.search_py, contents, "is")
48 | assert count == 10000 * NT
49 |
50 |
51 | def run_rust_sequential_twice(
52 | executor: ThreadPoolExecutor, contents: str, needle: str
53 | ) -> int:
54 | future_1 = executor.submit(
55 | word_count.search_sequential_allow_threads, contents, needle
56 | )
57 | future_2 = executor.submit(
58 | word_count.search_sequential_allow_threads, contents, needle
59 | )
60 | result_1 = future_1.result()
61 | result_2 = future_2.result()
62 | return result_1 + result_2
63 |
64 |
65 | def test_word_count_rust_sequential_twice_with_threads(benchmark, contents):
66 | executor = ThreadPoolExecutor(max_workers=2)
67 | count = benchmark(run_rust_sequential_twice, executor, contents, "is")
68 | assert count == 20000 * NT
69 |
--------------------------------------------------------------------------------
/23-candle_chat/README.md:
--------------------------------------------------------------------------------
1 | ## Rust Candle Demo
2 |
3 | An interactive command line tool to demonstrate how to use HuggingFace's rust [Candle ML framework](https://github.com/huggingface/candle) to execute LLM.
4 |
5 | This demo uses the quantized version of LLM openchat: https://huggingface.co/TheBloke/openchat_3.5-GGUF by default.
6 |
7 |
8 | ### Prepare
9 |
10 | Make sure you have installed the huggingface cli, if not, do it:
11 |
12 | ```
13 | pip install -U "huggingface_hub[cli]"
14 | ```
15 |
16 | And then you should download this model file associated with the original openchat `tokenizer.json` file:
17 |
18 |
19 | ```
20 | mkdir hf_hub
21 | HF_HUB_ENABLE_HF_TRANSFER=1 HF_ENDPOINT=https://hf-mirror.com huggingface-cli download TheBloke/openchat_3.5-GGUF openchat_3.5.Q8_0.gguf --local-dir hf_hub
22 | HF_HUB_ENABLE_HF_TRANSFER=1 HF_ENDPOINT=https://hf-mirror.com huggingface-cli download openchat/openchat_3.5 tokenizer.json --local-dir hf_hub
23 | ```
24 |
25 | ### Run
26 |
27 | There are two examples here:
28 |
29 | - **simple**: all parameters are hardcoded into code to make everything simplest, but you need to modify the model and tokenizer.json file by yourself, and run by:
30 |
31 | ```
32 | cargo run --release --bin simple
33 | ```
34 |
35 | - **cli**: you can use this cli program to pass parameters from command line.
36 |
37 | ```
38 | cargo run --release --bin cli -- --model=xxxxxxx --tokenizer=xxxx
39 | ```
40 |
41 | You can use `--help` to show what parameters could be configured.
42 |
43 | ```
44 | $ cargo run --release --bin cli -- --help
45 | Finished release [optimized] target(s) in 0.04s
46 | Running `target/release/cli --help`
47 | avx: false, neon: false, simd128: false, f16c: false
48 | Usage: cli [OPTIONS]
49 |
50 | Options:
51 | --tokenizer [default: ../hf_hub/openchat_3.5_tokenizer.json]
52 | --model [default: ../hf_hub/openchat_3.5.Q8_0.gguf]
53 | -n, --sample-len [default: 1000]
54 | --temperature [default: 0.8]
55 | --seed [default: 299792458]
56 | --repeat-penalty [default: 1.1]
57 | --repeat-last-n [default: 64]
58 | --gqa [default: 8]
59 | -h, --help Print help
60 | -V, --version Print version
61 | ```
62 |
63 | ### License
64 |
65 | None.
66 |
67 | ### Feedback
68 |
69 | Feel free to submit issues to this repository.
70 |
--------------------------------------------------------------------------------
/2122-axumapp_stepbystep/axumapp06_jsoninput/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::{
2 | extract::{Form, Json, Query},
3 | response::Html,
4 | routing::{get, post},
5 | Router,
6 | };
7 | use serde::Deserialize;
8 | use tower_http::trace::TraceLayer;
9 |
10 | #[allow(dead_code)]
11 | #[derive(Debug, Deserialize)]
12 | struct Params {
13 | foo: Option,
14 | bar: Option,
15 | }
16 |
17 | #[tokio::main]
18 | async fn main() {
19 | tracing_subscriber::fmt::init();
20 |
21 | let app = Router::new()
22 | .route("/", get(handler))
23 | .route("/query", get(query))
24 | .route("/form", get(show_form).post(accept_form))
25 | .route("/json", post(accept_json))
26 | .layer(TraceLayer::new_for_http());
27 |
28 | // run it
29 | let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
30 | .await
31 | .unwrap();
32 | tracing::debug!("listening on {}", listener.local_addr().unwrap());
33 | axum::serve(listener, app).await.unwrap();
34 | }
35 |
36 | async fn handler() -> Html<&'static str> {
37 | Html("Hello, World!
")
38 | }
39 |
40 | async fn query(Query(params): Query) -> Html<&'static str> {
41 | tracing::debug!("query params {:?}", params);
42 | Html("Test query
")
43 | }
44 |
45 | async fn show_form() -> Html<&'static str> {
46 | Html(
47 | r#"
48 |
49 |
50 |
51 |
52 |
65 |
66 |
67 | "#,
68 | )
69 | }
70 |
71 | #[allow(dead_code)]
72 | #[derive(Deserialize, Debug)]
73 | struct Input {
74 | name: String,
75 | email: String,
76 | }
77 |
78 | async fn accept_form(Form(input): Form) -> Html<&'static str> {
79 | tracing::debug!("form params {:?}", input);
80 |
81 | Html("Form posted
")
82 | }
83 |
84 | async fn accept_json(Json(input): Json) -> Html<&'static str> {
85 | tracing::debug!("json params {:?}", input);
86 | Html("Json posted
")
87 | }
88 |
--------------------------------------------------------------------------------
/14-getinfo/src/server.rs:
--------------------------------------------------------------------------------
1 | use std::env;
2 | use tokio::io::{AsyncReadExt, AsyncWriteExt};
3 | use tokio::net::TcpListener;
4 | use tokio::process::Command;
5 |
6 | #[tokio::main]
7 | async fn main() -> Result<(), Box> {
8 | let addr = env::args()
9 | .nth(1)
10 | .unwrap_or_else(|| "127.0.0.1:8888".to_string());
11 | println!("Listening on: {}", addr);
12 | let listener = TcpListener::bind(&addr).await?;
13 |
14 | // 注意这里是一个无条件循环,表明始终处于服务状态
15 | loop {
16 | // 等待客户端请求连上来
17 | let (mut socket, _) = listener.accept().await?;
18 |
19 | // 来一个客户端连接,创建一个对应的新任务
20 | tokio::spawn(async move {
21 | // 分配一个缓冲存
22 | let mut buf = [0; 1024];
23 | let mut offset = 0;
24 | // 循环读,因为不能确保一次能从网络线路上读完数据
25 | loop {
26 | // 读操作,返回的n表示读了多少个字节
27 | // 正常情况下,读到数据才会返回,如果没有读到,就会等待
28 | let n = socket
29 | .read(&mut buf[offset..])
30 | .await
31 | .expect("failed to read data from socket");
32 |
33 | // n返回0的情况,是碰到了EOF,表明远端的写操作已断开,这个一定要判断
34 | if n == 0 {
35 | // 碰到了EOF就直接返回结束此任务,因为后面的操作没了意义
36 | return;
37 | }
38 |
39 | println!("offset: {offset}, n: {n}");
40 | let end = offset + n;
41 | // 转换指令为字符串
42 | if let Ok(directive) = std::str::from_utf8(&buf[..end]) {
43 | println!("{directive}");
44 | // 执行指令对应的工作
45 | let output = process(directive).await;
46 | println!("{output}");
47 | // 向客户端返回处理结果
48 | socket
49 | .write_all(&output.as_bytes())
50 | .await
51 | .expect("failed to write data to socket");
52 | } else {
53 | // 判断是否转换失败,如果失败,就有可能是网络上的数据还没读完
54 | // 要继续loop读下一波数据
55 | offset = end;
56 | }
57 | }
58 | });
59 | }
60 | }
61 |
62 | async fn process(directive: &str) -> String {
63 | if directive == "gettime" {
64 | // 这里我们用了unwrap()是因为我们一般确信执行date命令不会失败
65 | // 更可靠的作法是对返回的Result作处理
66 | let output = Command::new("date").output().await.unwrap();
67 | String::from_utf8(output.stdout).unwrap()
68 | } else {
69 | // 如果是其它指令,我们目前返回 无效指令
70 | "invalid command".to_owned()
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/23-candle_chat/src/token_output_stream.rs:
--------------------------------------------------------------------------------
1 | use candle_core::Result;
2 |
3 | /// This is a wrapper around a tokenizer to ensure that tokens can be returned to the user in a
4 | /// streaming way rather than having to wait for the full decoding.
5 | pub struct TokenOutputStream {
6 | tokenizer: tokenizers::Tokenizer,
7 | tokens: Vec,
8 | prev_index: usize,
9 | current_index: usize,
10 | }
11 |
12 | impl TokenOutputStream {
13 | pub fn new(tokenizer: tokenizers::Tokenizer) -> Self {
14 | Self {
15 | tokenizer,
16 | tokens: Vec::new(),
17 | prev_index: 0,
18 | current_index: 0,
19 | }
20 | }
21 |
22 | pub fn into_inner(self) -> tokenizers::Tokenizer {
23 | self.tokenizer
24 | }
25 |
26 | fn decode(&self, tokens: &[u32]) -> Result {
27 | match self.tokenizer.decode(tokens, true) {
28 | Ok(str) => Ok(str),
29 | Err(err) => candle_core::bail!("cannot decode: {err}"),
30 | }
31 | }
32 |
33 | // https://github.com/huggingface/text-generation-inference/blob/5ba53d44a18983a4de32d122f4cb46f4a17d9ef6/server/text_generation_server/models/model.py#L68
34 | pub fn next_token(&mut self, token: u32) -> Result