Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/main.yml

This file was deleted.

58 changes: 58 additions & 0 deletions .github/workflows/testmain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Build and Deploy

on:
push:
branches: ["main", "hotfix", "release"]

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set environment variables
run: |
REPO_OWNER=$(echo "${GITHUB_REPOSITORY}" | cut -d '/' -f 1 | tr '[:upper:]' '[:lower:]')
REPO_NAME=$(echo "${GITHUB_REPOSITORY}" | cut -d '/' -f 2 | tr '[:upper:]' '[:lower:]')
echo "REPO_OWNER=${REPO_OWNER}" >> $GITHUB_ENV
echo "REPO_NAME=${REPO_NAME}" >> $GITHUB_ENV

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and Push Docker Image
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64, linux/arm64
push: true
tags: |
ghcr.io/${{ env.REPO_OWNER }}/${{ env.REPO_NAME }}:latest
ghcr.io/${{ env.REPO_OWNER }}/${{ env.REPO_NAME }}:${{ github.sha }}

- name: Slim Docker Image
uses: kitabisa/docker-slim-action@v1
env:
DSLIM_HTTP_PROBE: "false"
with:
target: ghcr.io/${{ env.REPO_OWNER }}/${{ env.REPO_NAME }}:latest
tag: slim
args: --http-probe=false

- name: Push Slim Image
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64, linux/arm64
push: true
tags: |
ghcr.io/${{ env.REPO_OWNER }}/${{ env.REPO_NAME }}:latest-slim
ghcr.io/${{ env.REPO_OWNER }}/${{ env.REPO_NAME }}:${{ github.sha }}-slim
119 changes: 119 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# **Rust Project Contribution Guide**

## **1. Forking & Cloning the Repository**

### **Forking the Repository**
1. Go to the **GitHub repository** you want to contribute to.
2. Click the **Fork** button (top-right corner).
3. GitHub will create a copy of the repo under your account.

### **Cloning the Forked Repository**
After forking, clone the repo locally:

```sh
git clone https://github.com/Dericko681/ChatMe.git
```
Replace `<your-username>` with your GitHub username and `<repo-name>` with the actual repository name.

### **Navigate into the Project**

```sh
cd chatme
```

### **Set the Upstream Remote (Original Repo) to Fetch Future Updates**

```sh
git remote add upstream https://github.com/Dericko681/ChatMe.git
git remote -v
```

Fetch and merge the latest changes from upstream:

```sh
git fetch upstream
git checkout main
git merge upstream/main
```

---

## **2. Rust Coding Standards & Naming Conventions**

### **Coding Standards**
Follow Rust’s official style guide using `cargo fmt` and `clippy`:

```sh
cargo fmt --all
cargo clippy -- -D warnings
```

- Use idiomatic Rust patterns (e.g., prefer `Result` over panics).
- Document public APIs using `///` Rust doc comments.
- Follow proper error handling with `thiserror` or `anyhow` crates.
- Write modular code by splitting logic into separate modules (`mod`).
- Use strong typing instead of `String` where possible (`struct`, `enum`).

### **Naming Conventions**

| Element | Naming Convention | Example |
|------------------|------------------|---------------------|
| Variables & Functions | `snake_case` | `process_data()` |
| Constants | `UPPER_CASE_SNAKE` | `MAX_RETRIES` |
| Structs & Enums | `PascalCase` | `struct UserProfile` |
| Traits | `PascalCase` | `trait Displayable` |
| Files & Modules | `snake_case.rs` | `auth_service.rs` |

---

## **3. Submitting a Pull Request (PR) with atleast one reviewer**

### **Step 1: Create a Feature Branch**
Before making changes, create a new branch:

```sh
git checkout -b feature-branch-name
```

### **Step 2: Make Changes & Run Tests**
Modify the code, then format and lint:

```sh
cargo fmt --all
cargo clippy -- -D warnings
```
Run tests before pushing:

```sh
cargo test
```

### **Step 3: Commit & Push the Changes**

```sh
git add .
git commit -m "<commit message>"
git push origin feature-branch-name
```

### **Step 4: Create a Pull Request (PR)**
1. Go to your forked repo on GitHub.
2. Click **Compare & pull request**.
3. Set the base branch (e.g., `main` or `develop`).
4. Add a clear title and detailed description.
5. Assign at least **one reviewer** in the *Reviewers* section.
6. Click **Create Pull Request**.

---

## **4. Syncing Your Fork with Upstream**
Before working on new features, keep your fork updated:

```sh
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
```

This avoids merge conflicts when submitting PRs.
22 changes: 22 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM rust:1.73-alpine as builder

RUN apk add --no-cache musl-dev

WORKDIR /app

COPY . .
COPY Cargo.lock Cargo.toml /app/

RUN cargo build --release
RUN cargo build --release --bin server
RUN cargo build --release --bin client

FROM alpine:3.19

RUN apk add --no-cache ca-certificates

COPY --from=builder /app/target/release/ /usr/local/bin
COPY --from=builder /app/target/release/server /usr/local/bin/
COPY --from=builder /app/target/release/client /usr/local/bin/

CMD ["server"]
30 changes: 11 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

ChatMe is a simple chat application written in Rust that demonstrates how to use threads and channels for communication between senders and receivers. The application consists of two parts:

Local Chat (Threading version): A multi-threaded, single-process implementation where messages are sent between sender and receiver threads within the same machine.
Distributed Chat (Networking version): A TCP-based version where a client sends messages to a server, and the server receives and displays the messages. This version allows communication between different machines over a network.
Local Chat (Threading version): A multi-threaded, single-process implementation where messages are sent between sender and receiver threads within the same machine.
Distributed Chat (Networking version): A TCP-based version where a client sends messages to a server, and the server receives and displays the messages. This version allows communication between different machines over a network.

## Table of Contents

Expand All @@ -44,37 +44,39 @@ ChatMe is a simple chat application written in Rust that demonstrates how to use

The ChatMe project is designed to demonstrate basic concepts around multi-threading and communication protocols in Rust. It consists of two main versions:

Local Chat (Threading version): Both the sender and receiver are running in separate threads on the same machine and communicate through Rust's mpsc (multi-producer, single-consumer) channels.
Distributed Chat (Networking version): Uses TCP sockets for communication between a client (sender) and a server (receiver), where the client can send messages to the server over a network connection.
Local Chat (Threading version): Both the sender and receiver are running in separate threads on the same machine and communicate through Rust's mpsc (multi-producer, single-consumer) channels.
Distributed Chat (Networking version): Uses TCP sockets for communication between a client (sender) and a server (receiver), where the client can send messages to the server over a network connection.

This project is intended for learning and experimentation with Rust's concurrency and networking capabilities.
Technologies Used

Rust: The programming language used to implement the entire chat application.
Standard Library: Utilized features from Rust's standard library including std::thread, std::sync::mpsc, and std::net for threading, channels, and networking respectively.
Rust: The programming language used to implement the entire chat application.
Standard Library: Utilized features from Rust's standard library including std::thread, std::sync::mpsc, and std::net for threading, channels, and networking respectively.

## Local Chat (Threading)

In this version, both the sender and receiver are running as separate threads within the same process. They communicate through an in-memory channel (mpsc::channel), simulating a real-time message exchange.
Features
Multi-threaded design with sender and receiver running on separate threads.
Communication between threads is achieved using Rust channels (mpsc).
Simple message passing using a Message struct that contains a sender's name and message cont
Communication between threads is achieved using Rust channels (mpsc).
Simple message passing using a Message struct that contains a sender's name and message cont

## Setup Instructions

Clone the Repository:

```
git clone https://github.com/your-username/chatme.git
git clone https://github.com/Dericko681/ChatMe.git
cd chatme
```

Install Rust (if not already installed): Follow the official instructions: https://www.rust-lang.org/learn/get-started

Build the Project: Inside the project directory, run the following command to build the project:

```
cargo build
```

Run the Application: To run the local chat version, simply run the following command:

Expand Down Expand Up @@ -108,16 +110,6 @@ Features

## Setup Instructions

Clone the Repository (if not done already):

```
git clone https://github.com/your-username/chatme.git
cd chatme
```

Build the Project:

cargo build

Run the Server: In one terminal window, run the server (this will listen for incoming connections on port 7878):

Expand Down
52 changes: 51 additions & 1 deletion src/distributed_chat/client.rs
Original file line number Diff line number Diff line change
@@ -1 +1,51 @@
// Contains the client logic to send messages to the server over a TCP connection
use std::io::{self, BufRead, BufReader, Write};
use std::net::TcpStream;
use std::thread;

pub fn start_client() {
let mut stream = TcpStream::connect("127.0.0.1:7878").expect("Failed to connect to server");

println!("Enter your username: ");
let mut username = String::new();
io::stdin()
.read_line(&mut username)
.expect("Failed to read username");
username = username.trim().to_string();

// Send username to server
writeln!(stream, "{}", username).expect("Failed to send username");
stream.flush().expect("Failed to flush username");

let mut stream_clone = stream.try_clone().expect("Failed to clone stream");

// Spawn thread to listen for messages from the server
thread::spawn(move || {
let reader = BufReader::new(&mut stream_clone);
for line in reader.lines() {
match line {
Ok(msg) => println!("{}", msg),
Err(_) => {
println!("Disconnected from server.");
break;
}
}
}
});

// Read input from user and send messages
loop {
let mut message = String::new();
io::stdin()
.read_line(&mut message)
.expect("Failed to read input");
let message = message.trim().to_string();

if message == "/exit" {
println!("Disconnecting...");
break;
}

writeln!(stream, "{}", message).expect("Failed to send message");
stream.flush().expect("Failed to flush message");
}
}
2 changes: 1 addition & 1 deletion src/distributed_chat/connection.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
// Utility file that may contain helpers for managing the connection between client and server (e.g., handling connection retries, parsing connection strings, etc.).
// Utility file that may contain helpers for managing the connection between client and server (e.g., handling connection retries, parsing connection strings, etc.).
2 changes: 1 addition & 1 deletion src/distributed_chat/message.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
// Defines the message structure for network communication, similar to local_chat/message.rs but potentially extended to include network-specific fields
// Defines the message structure for network communication, similar to local_chat/message.rs but potentially extended to include network-specific fields
5 changes: 4 additions & 1 deletion src/distributed_chat/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
// Contains a declaration for the module and organizes the submodules inside the
pub mod client;
pub mod connection;
pub mod message;
pub mod server;
Loading
Loading