Come up with several minimal viable solutions of the problems, written in rust code, using only libs that is explicitly used in code below, pointing in which files which update needed and which new files need to create with which code. Task: define in proper file five alternative entities, each initialized with the same set of rows, consisting of 3 cells type of a string, that can be read and updated by any function or macro in …/project/src/main.rs or …/project/src/subproject/src/lib.rs. Start with hashmap, hashset (three cells goes into hashset as \t tab-separated in one string) and two other entities of your choice, the last of which can be filled and updated with any type of data not limiting to string cells

___


Solution 1: Using HashMap and HashSet

In file ./project/src/data.rs, define five alternative entities as follows:


use std::collections::{HashMap, HashSet};

pub static mut HASHMAP: HashMap<i32, [String; 3]> = HashMap::new();
pub static mut HASHSET: HashSet<String> = HashSet::new();
pub static mut VECTOR: Vec<[String; 3]> = Vec::new();
pub static mut BINARY_TREE: BinaryTree<[String; 3]> = BinaryTree::new();
pub static mut BINARY_HEAP: BinaryHeap<[String; 3]> = BinaryHeap::new();



The HashMap is defined to store rows of data indexed by an integer key. The HashSet is defined to store rows of data as a single string separated by tabs (\t) as the unique value. The Vector is a simple array collection of rows. The BinaryTree and BinaryHeap are defined to store rows of data in a binary search tree and a binary heap respectively.

In file ./project/src/main.rs, use the data module and insert some data into these data structures as follows:


mod data;

fn main() {
    unsafe {
        // Insert data into HashMap
        HASHMAP.insert(1, [“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
        
        // Insert data into HashSet
        let row = vec![“cell1”, “cell2”, “cell3”].join(“\t”);
        HASHSET.insert(row);

        // Insert data into Vector
        VECTOR.push([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);

        // Insert data into BinaryTree
        BINARY_TREE.insert([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);

        // Insert data into BinaryHeap
        BINARY_HEAP.push([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    }
}



Solution 2: Using Tuple Structs

In file ./project/src/data.rs, define five alternative entity tuple structs as follows:


pub struct Entity1(pub i32, pub [String; 3]);
pub struct Entity2(pub String);
pub struct Entity3(pub [String; 3]);
pub struct Entity4(pub BinaryTree<[String; 3]>);
pub struct Entity5(pub BinaryHeap<[String; 3]>);



The Entity1 struct is defined to store a row of data as an integer key and an array of cells. The Entity2 struct is defined to store a row of data as a single string separated by tabs. The Entity3 struct is defined to store a row of data as an array of cells. The Entity4 and Entity5 structs are defined to store rows of data in a binary search tree and a binary heap respectively.

In file ./project/src/main.rs, use the data module and insert some data into these data structures as follows:


mod data;

fn main() {
    // Insert data into Entity1
    let entity1 = data::Entity1(1, [“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity2
    let entity2 = data::Entity2(vec![“cell1”, “cell2”, “cell3”].join(“\t”));
    
    // Insert data into Entity3
    let entity3 = data::Entity3([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity4
    let mut entity4 = data::Entity4(BinaryTree::new());
    entity4.0.insert([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity5
    let mut entity5 = data::Entity5(BinaryHeap::new());
    entity5.0.push([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
}



Solution 3: Using Structs and Generics

In file ./project/src/data.rs, define a single generic struct as follows:


pub struct Entity<T> {
    data: Vec<[T; 3]>
}

impl<T> Entity<T> {
    pub fn new() -> Self {
        Entity { data: Vec::new() }
    }
    
    pub fn insert(&mut self, row: [T; 3]) {
        self.data.push(row);
    }
}

pub type Entity1 = Entity<String>;
pub type Entity2 = Entity<String>;
pub type Entity3 = Entity<String>;
pub type Entity4 = Entity<String>;
pub type Entity5 = Entity<i32>;



The Entity struct is defined as a generic struct that stores rows of data as an array of cells. The Entity1, Entity2, Entity3, Entity4, and Entity5 types are aliases with specific data types.

In file ./project/src/main.rs, use the data module and insert some data into these data structures as follows:


mod data;

fn main() {
    // Insert data into Entity1
    let mut entity1 = data::Entity1::new();
    entity1.insert([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity2
    let mut entity2 = data::Entity2::new();
    entity2.insert(vec![“cell1”, “cell2”, “cell3”].join(“\t”));
    
    // Insert data into Entity3
    let mut entity3 = data::Entity3::new();
    entity3.insert([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity4
    let mut entity4 = data::Entity4::new();
    entity4.insert([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity5
    let mut entity5 = data::Entity5::new();
    entity5.insert(1);
}



Solution 4: Using Enums

In file ./project/src/data.rs, define a single enum with associated values as follows:


enum Entity {
    Entity1(i32, [String; 3]),
    Entity2(String),
    Entity3([String; 3]),
    Entity4(BinaryTree<[String; 3]>),
    Entity5(BinaryHeap<[String; 3]>),
}



The Entity enum is defined with five variants, each with its data type. The Entity1 variant stores a row of data as an integer key and an array of cells. The Entity2 variant stores a row of data as a single string separated by tabs. The Entity3 variant stores a row of data as an array of cells. The Entity4 and Entity5 variants are defined to store rows of data in a binary search tree and a binary heap respectively.

In file ./project/src/main.rs, use the data module and insert some data into these data structures as follows:


mod data;

fn main() {
    // Insert data into Entity1
    let entity1 = data::Entity::Entity1(1, [“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity2
    let entity2 = data::Entity::Entity2(vec![“cell1”, “cell2”, “cell3”].join(“\t”));
    
    // Insert data into Entity3
    let entity3 = data::Entity::Entity3([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity4
    let mut entity4 = data::Entity::Entity4(BinaryTree::new());
    entity4.0.insert([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    
    // Insert data into Entity5
    let mut entity5 = data::Entity::Entity5(BinaryHeap::new());
    entity5.0.push([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
}



Solution 5: Using a Global Struct

In file ./project/src/data.rs, define a global Data struct as follows:


use std::collections::{HashMap, HashSet};

pub struct Data {
    pub hashmap: HashMap<i32, [String; 3]>,
    pub hashset: HashSet<String>,
    pub vector: Vec<[String; 3]>,
    pub binary_tree: BinaryTree<[String; 3]>,
    pub binary_heap: BinaryHeap<[String; 3]>,
}

impl Data {
    pub fn new() -> Self {
        Data {
            hashmap: HashMap::new(),
            hashset: HashSet::new(),
            vector: Vec::new(),
            binary_tree: BinaryTree::new(),
            binary_heap: BinaryHeap::new(),
        }
    }
}

pub static mut DATA: Data = Data::new();



The Data struct is defined with five fields for each data structure. A new instance of the struct can be created with its new method.

In file ./project/src/main.rs, use the data module and insert some data into these data structures as follows:


mod data;

fn main() {
    unsafe {
        // Insert data into HashMap
        DATA.hashmap.insert(1, [“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
        
        // Insert data into HashSet
        let row = vec![“cell1”, “cell2”, “cell3”].join(“\t”);
        DATA.hashset.insert(row);

        // Insert data into Vector
        DATA.vector.push([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);

        // Insert data into BinaryTree
        DATA.binary_tree.insert([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);

        // Insert data into BinaryHeap
        DATA.binary_heap.push([“cell1”.to_owned(), “cell2”.to_owned(), “cell3”.to_owned()]);
    }
}  what solution will be most suitable for filling data from a bunch of dynamically changing files, processing it and updating the files, given that each file can be updated asyncronously from many threads of provided solution