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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use std::collections::BTreeMap;

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub enum VisibilityV1 {
    Public,
    /// require to login to see the user.
    OnlyToFriends,
    NotAllow,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UserInfoFieldV1<T> {
    visibility: VisibilityV1,
    field: T,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UserHeaderV1 {
    /// the user id.
    pub user_id: String,
    /// the user server.
    pub user_server: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UserInfoV1 {
    /// the user header
    #[serde(flatten)]
    pub header: UserHeaderV1,
    /// the user name.
    pub user_name: UserInfoFieldV1<String>,
    /// the user avatar.
    pub avatar: UserInfoFieldV1<String>,
    /// the user bio.
    pub bio: UserInfoFieldV1<String>,
    /// the user visibility.
    pub visibility: VisibilityV1,
    /// if the user is letting others add them to group.
    /// ROOM V1
    pub add_to_group: VisibilityV1,
    /// last login time
    pub last_login_time: UserInfoFieldV1<u64>,
    /// last update time
    pub last_update_time: UserInfoFieldV1<u64>,
    /// externsion
    #[serde(flatten)]
    pub extension: BTreeMap<String, UserInfoFieldV1<serde_json::Value>>,
}

#[test]
fn test_userv1_extention() {
    let user: serde_json::Value = serde_json::from_str(
        r#"
    {
        "user_id": "test",
        "user_server": "test",
        "user_name": {
            "visibility": "Public",
            "field": "test"
        },
        "avatar": {
            "visibility": "Public",
            "field": "test"
        },
        "bio": {
            "visibility": "Public",
            "field": "test"
        },
        "visibility": "Public",
        "add_to_group": "Public",
        "test": {
            "visibility": "Public",
            "field": "test"
        }
    }
    "#,
    )
    .unwrap();
    let user: UserInfoV1 = serde_json::from_value(user).unwrap();
    println!("{:#?}", user)
}

#[derive(Debug, Serialize, Deserialize)]
struct LastReadV1 {
    room_id: String,
    event_id: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Friend {
    alias: String,
    user: UserInfoV1,
    friend_since: u64,
    tags: Vec<String>,
}

// TODO: reform this to a more general way.
#[derive(Debug, Serialize, Deserialize)]
pub struct UserRecordV1 {
    pinged_rooms: Vec<String>,
    last_reads: Vec<LastReadV1>,
    user_info: UserInfoV1,
    blocked_users: Vec<UserHeaderV1>,
    friends: Vec<Friend>,
}

#[derive(Debug, Serialize, Deserialize)]
pub enum UserStatusNotifyEventV1 {
    Online,
    Offline,
}