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
use crate::identifiers::{ClientIdentifier, GroupIdentifier, ReplicaIdentifier, RequestIdentifier};
use crate::mailbox::Address;
use crate::model::{Message, Request};
use crate::stamps::View;

pub struct Client {
    identifier: ClientIdentifier,
    view: View,
    request: RequestIdentifier,
    group: GroupIdentifier,
}

impl Client {
    pub fn new(group: GroupIdentifier) -> Self {
        Self {
            identifier: Default::default(),
            view: Default::default(),
            request: Default::default(),
            group,
        }
    }

    pub fn address(&self) -> Address {
        self.identifier.into()
    }

    pub fn identifier(&self) -> ClientIdentifier {
        self.identifier
    }

    pub fn primary(&self) -> ReplicaIdentifier {
        self.group.primary(self.view)
    }

    pub fn group(&self) -> GroupIdentifier {
        self.group
    }

    pub fn view(&self) -> View {
        self.view
    }

    pub fn last_request(&self) -> RequestIdentifier {
        self.request
    }

    pub fn new_message(&mut self, payload: &[u8]) -> Message {
        self.request.increment();
        self.message(payload, None)
    }

    pub fn new_request(&mut self, payload: &[u8]) -> Request {
        self.request.increment();
        self.request(payload, None)
    }

    pub fn message(&self, payload: &[u8], request: Option<RequestIdentifier>) -> Message {
        Message {
            from: self.identifier.into(),
            to: self.primary().into(),
            view: self.view,
            payload: self.request(payload, request).into(),
        }
    }

    pub fn broadcast(&self, payload: &[u8]) -> Message {
        Message {
            from: self.identifier.into(),
            to: self.group.into(),
            view: self.view,
            payload: self.request(payload, None).into(),
        }
    }

    pub fn request(&self, payload: &[u8], request: Option<RequestIdentifier>) -> Request {
        Request {
            op: Vec::from(payload),
            c: self.identifier,
            s: request.unwrap_or(self.request),
        }
    }

    pub fn set_view(&mut self, view: View) {
        self.view = view;
    }
}