summaryrefslogtreecommitdiff
path: root/include/erebos/contact.h
blob: 963e22a47690a7c562f1721850d273ef405ee824 (plain)
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
#pragma once

#include <erebos/identity.h>
#include <erebos/list.h>
#include <erebos/pairing.h>
#include <erebos/set.h>
#include <erebos/state.h>
#include <erebos/storage.h>

#include <memory>
#include <optional>
#include <string>
#include <vector>

namespace erebos {

using std::optional;
using std::shared_ptr;
using std::string;
using std::vector;

struct ContactData;

class Contact
{
public:
	Contact(vector<Stored<ContactData>> data);
	Contact(const Contact &) = default;
	Contact(Contact &&) = default;
	Contact & operator=(const Contact &) = default;
	Contact & operator=(Contact &&) = default;

	optional<Identity> identity() const;
	optional<string> customName() const;
	Contact customName(const Storage & st, const string & name) const;
	string name() const;

	bool operator==(const Contact &) const;
	bool operator!=(const Contact &) const;

	vector<Stored<ContactData>> data() const;
	Digest leastRoot() const;

private:
	struct Priv;
	shared_ptr<Priv> p;
	Contact(shared_ptr<Priv> p): p(p) {}

	friend class ContactService;
};

DECLARE_SHARED_TYPE(Set<Contact>)

struct ContactData
{
	static ContactData load(const Ref &);
	Ref store(const Storage &) const;

	vector<Stored<ContactData>> prev;
	vector<Stored<Signed<IdentityData>>> identity;
	optional<string> name;
};

template<> struct Mergeable<Contact>
{
	using Component = ContactData;
	static vector<Stored<ContactData>> components(const Contact & c) { return c.data(); }
	static Contact merge(vector<Stored<ContactData>> x) { return Contact(move(x)); }
};

struct ContactAccepted;

class ContactService : public PairingService<ContactAccepted>
{
public:
	ContactService(Config &&, const Server &);
	virtual ~ContactService();

	UUID uuid() const override;

	void request(const Peer &);

protected:
	virtual Stored<ContactAccepted> handlePairingComplete(const Peer &) override;
	virtual void handlePairingResult(Context &, Stored<ContactAccepted>) override;

	const Server & server;
};

template<class T> class Signed;

struct ContactAccepted
{
	static ContactAccepted load(const Ref &);
	Ref store(const Storage &) const;
};

}