manager_employees_rust — Backend (Rust)
Assignment 4: Implementing Control Structures — Rust Backend API University of the Cumberlands — Master’s Program, Semester 4 / Week 4
Author: Carlos Gutierrez — cgutierrez44833@ucumberlands.edu
Repository: https://git.cargdev.io/CarGDev/manager_employees_rust — this repo is the Rust backend
Related Repositories (Assignment 4 — 3 implementations):
| Implementation | Language / Role | Repository |
|---|---|---|
| This repo | Rust — Backend API (Axum/Postgres) | manager_employees_rust |
| Companion | Python — Backend/CLI | manager_employees_python |
| Companion | GUI — Graphical Interface | manager_employees_gui |
📌 This Repository — Rust Backend Only
This repo contains ONLY the Rust backend for Assignment 4. The assignment requires implementing the same scheduling problem in two contrasting languages (e.g., Rust + Python) to demonstrate control flow across paradigms — with an optional GUI.
- Scope of this repo: REST API built with
Axum(src/router.rs:159),Tokioasync runtime,SQLx+ Postgres persistence (src/database/connection.rs:5), and a preference-aware weekly scheduling engine (src/router.rs:561,src/manager/). - Companion repos are not tracked here — see table above: Python implementation and GUI implementation live at
git.cargdev.io/CarGDev. - API docs are served via
utoipa+ Swagger UI at/swagger-ui(src/router.rs:187).
📖 Story: Assignment 4 — Implementing Control Structures
1. Overview
You will implement, without logical errors, various control structures such as conditionals, loops, and branching, in multiple programming languages. This assignment will demonstrate your mastery of syntax and control flow in different paradigms. — Assignment 4 Prompt
For me, Carlos Gutierrez, this assignment was about proving that the same business rules can be expressed cleanly in two very different paradigms. I chose Rust for this backend because its match, if let, ownership model, and Result error handling force explicit, safe control flow — a sharp contrast to a dynamic language like Python or JavaScript. Every scheduling rule below is therefore not just business logic, but a deliberate exercise in conditionals, loops, and branching done idiomatically in Rust.
2. Application Prompt — Employee Schedule Manager
The company operates 7 days/week with 3 shifts/day (morning, afternoon, evening — src/database/types.rs:18). The app must:
-
Input and Storage: Collect employee names and their preferred shift for each day, storing in appropriate structures. Here:
users+employee_weekly_preferences+company_userstables (src/database/schema.rs:36,src/database/entities/), with requests likeCreateEmployeeRequestandWeeklyPreferenceRequest(src/router.rs:32,src/router.rs:46). -
Scheduling Logic: Auto-assign shifts ensuring:
- No employee works more than one shift per day (
src/manager/validator.rs:5,src/router.rs:585) - Max 5 days per week per employee (
src/manager/validator.rs:11,src/router.rs:586) - At least 2 employees per shift per day; if fewer are available, randomly/round-robin assign additional valid employees (
src/main.rs:37,src/manager/scheduler.rs:25,src/router.rs:597)
- No employee works more than one shift per day (
-
Shift Conflicts: Detect when a preferred shift is full and resolve by assigning to another available shift on the same or next day (
src/manager/conflict.rs:4,src/manager/conflict.rs:10,src/manager/conflict.rs:16,src/router.rs:240). -
Output: Final weekly schedule in readable format indicating employee → day → shift. Here:
GET /schedules/weeklyandprint_final_schedule()grouping by day/shift (src/manager/scheduler.rs:44,src/router.rs:542). -
Bonus — Priority Ranking: Employees rank shifts
first > second > third(src/database/types.rs:18,src/database/schema.rs:70). The engine ranks candidates withpreference_rank()(src/router.rs:240) and accommodates preferences while still meeting coverage.
3. Programming Language Choice
Suggested: Python, Java, C++, JavaScript, Go, Rust — must be contrasting paradigms.
This repo = Rust (systems, compiled, ownership + exhaustive match) at manager_employees_rust.
My contrasting implementations are:
- Python:
manager_employees_python— dynamic, interpreted, idiomatic loops/comprehensions - GUI:
manager_employees_gui— graphical input/output for employee names, preferences, and final schedule (bonus requirement)
The Rust side emphasizes match over if-else chains, iterator loops (for day in all_days() src/router.rs:581), and Result-based branching for DB errors (src/app.rs:29) — a direct contrast to Python’s approach in the companion repo.
✨ Features
- 7-day × 3-shift auto-generation via
POST /schedules/weekly/generate(src/router.rs:561) - Preference-aware ranking (
first=0, second=1, third=2, fallback=3) (src/router.rs:240) - Validation: one-shift/day, ≤5 days/week, ≥2/shift (
src/manager/validator.rs) - Conflict resolution: same-day fallback → next-day (
src/manager/conflict.rs) - Clock-in/out (
POST /employees/{id}/clock-insrc/router.rs:627,PUT /employees/{id}/clock-outsrc/router.rs:652) - Company & employee CRUD, weekly preferences (
PUT /employees/{id}/weekly-preferencessrc/router.rs:465) - Health check
GET /health(src/router.rs:262), CORS permissive (src/router.rs:188), OpenAPI docs
🛠 Tech Stack
| Layer | Choice | Version / File |
|---|---|---|
| Language | Rust | edition = "2024" (Cargo.toml:4) |
| Web | Axum | 0.8.4 (Cargo.toml:7) |
| Async | Tokio | 1.53.1 full (Cargo.toml:13) |
| DB | Postgres + SQLx | 0.9.0 chrono/postgres/runtime-tokio (Cargo.toml:12) |
| Validation/Types | Chrono, Serde | chrono 0.4.42, serde 1.0.228 (Cargo.toml:8, Cargo.toml:10) |
| Docs | utoipa + utoipa-swagger-ui | 5 / 9 (Cargo.toml:15, Cargo.toml:16) |
| Middleware | tower-http CORS | 0.6.6 (Cargo.toml:14) |
| Env | dotenvy | 0.15.7 (Cargo.toml:9) |
📁 Project Structure
src/
main.rs # entry, env loading, pool init, serve (src/main.rs:10)
app.rs # AppState { pool }, ApiError → 404/500 (src/app.rs:10)
router.rs # 16 routes, OpenAPI, scheduling core (src/router.rs:159)
database/
connection.rs # connect() + init_database() (src/database/connection.rs:5)
schema.rs # 9 DDL queries: enums + 5 tables + alters (src/database/schema.rs:94)
types.rs # WorkTime, DayOfWeek enums (src/database/types.rs:18)
entities/ # Company, User, CompanyUser, Schedule, WeeklyPreference
queries/ # company, employee, preference, schedule, user
manager/ # business-rule stubs extracted from main.rs assignment_rules()
scheduler.rs # generate_weekly_schedule, fill_missing, clock-in/out
validator.rs # same-day, 5-day, 2-employee validations
conflict.rs # detect + resolve same/next day
models/
company/ # CreateCompanyRequest + service
🗄 Database Schema
Enums: work_time('morning','afternoon','evening') (src/database/schema.rs:1), day_of_week('sunday'..'saturday') (src/database/schema.rs:10)
| Table | Key Columns |
|---|---|
companies |
id SERIAL PK, name TEXT UNIQUE (src/database/schema.rs:27) |
users |
id, name, last_name, preference work_time (src/database/schema.rs:36) |
company_users |
user_id FK→users, company_id FK→companies, UNIQUE(user_id,company_id) (src/database/schema.rs:47) |
schedules |
user_id FK, enter_time, day_of_week, out_time, shift work_time (src/database/schema.rs:58) |
employee_weekly_preferences |
user_id, day_of_week, first/second/third work_time, UNIQUE(user_id,day_of_week) (src/database/schema.rs:70) |
Init via CREATE_SCHEMA_QUERIES loop (src/database/connection.rs:13).
📐 Business Rules in Code
assignment_rules()summary (src/main.rs:29-39)all_days()/all_shifts()helpers (src/router.rs:224,src/router.rs:236)- Candidate filtering +
sort_by_key(preference_rank)(src/router.rs:589-595) assigned_days: HashMap<(user_id, DayOfWeek), bool>+day_count_by_user: HashMap<user_id, i32>(src/router.rs:576)
🔌 API Reference
Base: http://127.0.0.1:5005 (configurable via APP_ADDRESS)
| Method | Path | Tag | Description |
|---|---|---|---|
GET |
/health |
health | {"status":"ok"} (src/router.rs:254) |
POST |
/companies |
companies | create (src/router.rs:276) |
GET |
/companies |
companies | list (src/router.rs:284) |
GET |
/companies/{id} |
companies | get (src/router.rs:310) |
DELETE |
/companies/{id} |
companies | delete (src/router.rs:319) |
POST |
/employees |
employees | create + assign to company (src/router.rs:350) |
GET |
/employees |
employees | list (src/router.rs:375) |
POST |
/companies/{company_id}/employees/{employee_id} |
employees | assign (src/router.rs:394) |
DELETE |
/employees/{id} |
employees | delete (src/router.rs:418) |
PUT |
/employees/{id}/preference |
employees | single pref (src/router.rs:441) |
PUT |
/employees/{id}/weekly-preferences |
employees | 7-day prefs (src/router.rs:465) |
GET |
/companies/{company_name}/employees/names |
employees | names by company (src/router.rs:499) |
POST |
/schedules |
schedules | create (src/router.rs:518) |
GET |
/schedules/weekly |
schedules | list all (src/router.rs:542) |
POST |
/schedules/weekly/generate |
schedules | auto-generate (src/router.rs:561) |
POST |
/employees/{id}/clock-in |
schedules | clock-in now (src/router.rs:627) |
PUT |
/employees/{id}/clock-out |
schedules | clock-out (src/router.rs:652) |
Swagger: GET /swagger-ui + GET /api-docs/openapi.json (src/router.rs:187).
🚀 Getting Started
Prerequisites
- Rust
stable(withcargo) - Postgres ≥14 running locally
sqlx-clioptional (schema is auto-created on boot)
1. Clone & Configure
git clone https://git.cargdev.io/CarGDev/manager_employees_rust
cd manager_employees_rust
cp .env.example .env # or create .env
See also companions:
manager_employees_pythonandmanager_employees_gui.
.env (src/main.rs:11 loads via dotenvy):
DATABASE_URL=postgres://carlos:password@localhost/rust_manager_employees
APP_ADDRESS=127.0.0.1:5005
.envis gitignored (.gitignore:7). Example URL from.env:1.
2. Create Database
createdb rust_manager_employees
# or: psql -c "CREATE DATABASE rust_manager_employees;"
Tables/enums are created automatically on first run via init_database() (src/database/connection.rs:12).
3. Run
cargo run
# → listening on 127.0.0.1:5005
curl http://127.0.0.1:5005/health
# {"status":"ok"}
4. Try the Flow
# 1. Create company
curl -X POST http://127.0.0.1:5005/companies \
-H "Content-Type: application/json" \
-d '{"name":"Acme"}'
# 2. Create employees (company_id from above)
curl -X POST http://127.0.0.1:5005/employees \
-H "Content-Type: application/json" \
-d '{"company_id":1,"name":"Ana","last_name":"Lopez","preference":"morning"}'
# 3. Set weekly preferences
curl -X PUT http://127.0.0.1:5005/employees/1/weekly-preferences \
-H "Content-Type: application/json" \
-d '{"preferences":[{"day_of_week":"monday","first":"morning","second":"afternoon","third":"evening"}]}'
# 4. Generate weekly schedule
curl -X POST http://127.0.0.1:5005/schedules/weekly/generate \
-H "Content-Type: application/json" \
-d '{"company_id":1}'
# 5. View schedule
curl http://127.0.0.1:5005/schedules/weekly
# Swagger UI: http://127.0.0.1:5005/swagger-ui
⚙️ Configuration
| Var | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
yes | — | Postgres URL (src/main.rs:13) |
APP_ADDRESS |
no | 127.0.0.1:5005 |
Bind addr (src/main.rs:19) |
👨💻 Development
cargo fmt
cargo clippy
cargo check
cargo test
Error handling: ApiError(sqlx::Error) → RowNotFound→404, else 500 with JSON {"error": "..."} (src/app.rs:29).
📄 License
MIT — Copyright (c) 2026 Carlos Gutierrez. See LICENSE.
📬 Contact
Carlos Gutierrez — University of the Cumberlands
Email: cgutierrez44833@ucumberlands.edu
Project: manager_employees_rust — Rust backend for Assignment 4: Implementing Control Structures
Repositories:
- Rust Backend (this repo): https://git.cargdev.io/CarGDev/manager_employees_rust
- Python Backend: https://git.cargdev.io/CarGDev/manager_employees_python
- GUI: https://git.cargdev.io/CarGDev/manager_employees_gui