DEV Community

Cover image for Chat app: Struct vs HashMap
Antonov Mike
Antonov Mike

Posted on

Chat app: Struct vs HashMap

Quick look at Struct and HashMap using сhat app as an example

First of all, I want to thank these people: Aleksandr Petrosyan, Victor Gridnevsky and Nikita Pusankov.

Sometimes a comparison of different methods can be useful for studying. In this case I mean Structures and Hash Map. Structure is a data type. Hash Map is a collection. Both are suitable for transmitting a user name and message.
Example of struct and Hash Map:

use std::collections::HashMap;

struct Some_Struct { dictionary: HashMap<char, String> }

fn main() {
    // variable of type HashMap<char, String>
    let a: HashMap<char, String> = HashMap::new();
    // variable of type Some_Struct { dictionary: HashMap<char, String> }
    let b: Some_Struct = Some_Struct { dictionary: a };
}
Enter fullscreen mode Exit fullscreen mode

Here is an example of a terminal chat application made with Structures and Hash Map. Here I will show you just a couple of things. All the code is in the repository.

Cargo.toml dependencies:

serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.67"
colored = "2.0.0"
Enter fullscreen mode Exit fullscreen mode

transmitter.rs
In the first case, you need to create a data type "structure" and create a variable of type "structure" for storing user’s name and message.
In the second case, we create a variable of the Hash Map type and also insert some data. The key will be the user name, the value will be the message.

receiver.rs
The same, but we add id as a field of a new structure and an old structure to the new structure.

chat_server/src/structures.rs

use std::iter::Map;
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, Debug)]
pub struct UserData {
    pub name: String,
    pub message: String,
}

#[derive(Debug)]
pub struct UserID {
    pub id: String,
    pub data: UserData,
}

Enter fullscreen mode Exit fullscreen mode

chat_server/src/receiver.rs Structure

let deserialized: UserData = serde_json::from_str(&serde_message).expect("Could not read");
Enter fullscreen mode Exit fullscreen mode

We don’t have to add user ID addr to Hash Map, we can use it like this:

addr.to_string()
Enter fullscreen mode Exit fullscreen mode

chat_server/src/receiver.rs Hash Map

let deserialized: HashMap<String, String> = serde_json::from_str(&serde_message).expect("Could not read");
Enter fullscreen mode Exit fullscreen mode

I made two versions of the same program for the sole purpose of getting to know better the work of Hash Map, which for some reason I have never used before. I hope this text was helpful to someone.

A little bit about DATA_SIZE

All data are transmitted as a vector of u8 using serde and serde_json. For a correct deserialization we need a limit. I don't understand exactly how it works yet. Just applying it for now. I think I'll figure it out later. For now, just an example of how to use it:
chat_server and user

const DATA_SIZE: usize = 96;
Enter fullscreen mode Exit fullscreen mode

chat_user/src/transmitter.rs

buff_serde.resize(DATA_SIZE, 0);
Enter fullscreen mode Exit fullscreen mode

chat_server/src/receiver.rs

let mut buff_serde = vec![0; DATA_SIZE];
Enter fullscreen mode Exit fullscreen mode

Extra crate

Crate colored = “2.0.0” used as a decoration tool. For example:

.bold().yellow()
.italic().on_green()
Enter fullscreen mode Exit fullscreen mode

Useful methods

resize() resizes the Vec in-place so that len is equal to new_len.

into_iter() iterates over T.

take_whale() takes a closure as an argument. It will call this closure on each element of the iterator, and yield elements while it returns true.

read_exact() reads the exact number of bytes required to fill buf.

read_line() reads bytes from the underlying stream until the newline delimiter is found.

Top comments (0)