1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use crate::{FromString, GetVariants};

/// Represents a [User] of the cock analyzer.
/// `name` field is the name of the user.
/// `discord_name` field is the discord name of the user.
#[derive(Debug, PartialEq, Clone)]
pub struct User {
    pub name: String,
    pub discord_name: String,
}

/// Represents a unique identifier for a user, their [ID].
/// Variants include an anonymous identifier or a specific user.
#[derive(Debug, PartialEq, Clone)]
pub enum ID {
    Anonymous,
    User(User),
}

/// Implementing [GetVariants] for [ID] enum to provide the different variant options for [ID].
impl GetVariants for ID {
    fn get_variants() -> Vec<String> {
        vec![String::from("Anonymous"), String::from("User")]
    }
}

/// Implementing [FromString] for [ID] enum to create an [ID] instance from a string.
impl FromString for ID {
    fn from_string(id: &str) -> ID {
        match id {
            "Anonymous" => ID::Anonymous,
            "User" => ID::User(User {
                name: String::from(""),
                discord_name: String::from(""),
            }),
            _ => panic!("Invalid ID"),
        }
    }
}

/// Implementing [std::fmt::Display] trait for [ID] for formatted print.
impl std::fmt::Display for ID {
    /// Returnis a string representation of the [ID] variant.
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ID::Anonymous => write!(f, "Anonymous User"),
            ID::User(user) => write!(
                f,
                "Username: {}\nDiscord name: {}",
                user.name, user.discord_name
            ),
        }
    }
}

/// Tests for the [User] and [ID] structs
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_user() {
        let user = User {
            name: String::from("S"),
            discord_name: String::from("test"),
        };

        assert_eq!(user.name, "S");
        assert_eq!(user.discord_name, String::from("test"));
    }

    #[test]
    fn test_id() {
        let user = User {
            name: String::from("S"),
            discord_name: String::from("test"),
        };

        let id = ID::User(user);

        match id {
            ID::User(user) => {
                assert_eq!(user.name, "S");
                assert_eq!(user.discord_name, String::from("test"));
            }
            _ => panic!("Expected ID::User"),
        }
    }
}