diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml
new file mode 100644
index 0000000..7c7cb7d
--- /dev/null
+++ b/.github/workflows/audit.yml
@@ -0,0 +1,16 @@
+name: Security audit
+on:
+ schedule:
+ - cron: '0 0 * * *'
+ push:
+ paths:
+ - '**/Cargo.toml'
+ - '**/Cargo.lock'
+jobs:
+ security_audit:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: taiki-e/install-action@cargo-deny
+ - name: Scan for vulnerabilities
+ run: cargo deny check advisories
\ No newline at end of file
diff --git a/.github/workflows/general.yml b/.github/workflows/general.yml
new file mode 100644
index 0000000..eb5fe83
--- /dev/null
+++ b/.github/workflows/general.yml
@@ -0,0 +1,142 @@
+name: Rust
+
+on:
+ # NB: this differs from the book's project!
+ # These settings allow us to run this specific CI pipeline for PRs against
+ # this specific branch (a.k.a. book chapter).
+ push:
+ branches:
+ - main
+ pull_request:
+ types: [ opened, synchronize, reopened ]
+ branches:
+ - main
+
+env:
+ CARGO_TERM_COLOR: always
+ SQLX_VERSION: 0.7.1
+ SQLX_FEATURES: "rustls,postgres"
+
+jobs:
+ test:
+ name: Test
+ runs-on: ubuntu-latest
+ services:
+ postgres:
+ image: postgres:14
+ env:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: postgres
+ ports:
+ - 5432:5432
+ redis:
+ image: redis:7
+ ports:
+ - 6379:6379
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@stable
+ - uses: Swatinem/rust-cache@v2
+ with:
+ key: sqlx-${{ env.SQLX_VERSION }}
+ - name: Install sqlx-cli
+ run:
+ cargo install sqlx-cli
+ --version=${{ env.SQLX_VERSION }}
+ --features ${{ env.SQLX_FEATURES }}
+ --no-default-features
+ --locked
+ - name: Migrate database
+ run: |
+ sudo apt-get install libpq-dev -y
+ SKIP_DOCKER=true ./scripts/init_db.sh
+ - name: Check sqlx-data.json is up-to-date
+ run: |
+ cargo sqlx prepare --workspace --check
+ - name: Run tests
+ run: cargo test
+
+ fmt:
+ name: Rustfmt
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ components: rustfmt
+ - name: Enforce formatting
+ run: cargo fmt --check
+
+ clippy:
+ name: Clippy
+ runs-on: ubuntu-latest
+ services:
+ postgres:
+ image: postgres:14
+ env:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: postgres
+ ports:
+ - 5432:5432
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ components: clippy
+ - uses: Swatinem/rust-cache@v2
+ with:
+ key: sqlx-${{ env.SQLX_VERSION }}
+ - name: Install sqlx-cli
+ run:
+ cargo install sqlx-cli
+ --version=${{ env.SQLX_VERSION }}
+ --features ${{ env.SQLX_FEATURES }}
+ --no-default-features
+ --locked
+ - name: Migrate database
+ run: |
+ sudo apt-get install libpq-dev -y
+ SKIP_DOCKER=true ./scripts/init_db.sh
+ - name: Linting
+ run: cargo clippy -- -D warnings
+
+ coverage:
+ name: Code coverage
+ runs-on: ubuntu-latest
+ services:
+ postgres:
+ image: postgres:14
+ env:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: postgres
+ ports:
+ - 5432:5432
+ redis:
+ image: redis:7
+ ports:
+ - 6379:6379
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@stable
+ - name: Install libpq
+ run: sudo apt-get update && sudo apt-get install postgresql-client -y
+ - uses: Swatinem/rust-cache@v2
+ with:
+ key: sqlx-${{ env.SQLX_VERSION }}
+ - name: Install tarpaulin
+ run: cargo install cargo-tarpaulin
+ - name: Install sqlx-cli
+ run:
+ cargo install sqlx-cli
+ --version=${{ env.SQLX_VERSION }}
+ --features ${{ env.SQLX_FEATURES }}
+ --no-default-features
+ --locked
+ - name: Migrate database
+ run: SKIP_DOCKER=true ./scripts/init_db.sh
+ - name: Generate code coverage
+ run: cargo tarpaulin --verbose --workspace
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..c4b7049
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/newsletter-service.iml b/.idea/newsletter-service.iml
new file mode 100644
index 0000000..cf84ae4
--- /dev/null
+++ b/.idea/newsletter-service.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 47d6300..ad894d6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,6 +3,5 @@ name = "newsletter-service"
version = "0.1.0"
edition = "2021"
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
[dependencies]
+actix-web = "4.0.0"
diff --git a/src/main.rs b/src/main.rs
index e7a11a9..5c7b505 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,23 @@
-fn main() {
- println!("Hello, world!");
+use actix_web::{
+ web,
+ App,
+ HttpRequest,
+ HttpServer,
+ Responder
+};
+
+async fn greet(req: HttpRequest) -> impl Responder {
+ let name = req.match_info().get("name").unwrap_or("world");
+
+ format!("Hello, {}!", &name)
}
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+ HttpServer::new(|| {
+ App::new()
+ .route("/", web::get().to(greet))
+ .route("/{name}", web::get().to(greet))
+ })
+ .bind("127.0.0.1:8080")?.run().await
+}
\ No newline at end of file