summaryrefslogtreecommitdiff
path: root/lib/persistence.cpp
blob: 543f2fdb3ed54b5f2d95868787a183265c485648 (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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "persistence.h"
#include <map>
#include <sstream>

namespace Persistence {
	using Factories
			= std::pair<std::function<std::unique_ptr<Persistable>()>, std::function<std::shared_ptr<Persistable>()>>;
	using NamedTypeFactories = std::map<std::string_view, Factories>;

	inline static auto &
	namedTypeFactories()
	{
		static NamedTypeFactories namedTypeFactories;
		return namedTypeFactories;
	}

	void
	Persistable::addFactory(const std::string_view t, std::function<std::unique_ptr<Persistable>()> fu,
			std::function<std::shared_ptr<Persistable>()> fs)
	{
		namedTypeFactories().emplace(t, std::make_pair(std::move(fu), std::move(fs)));
	}

	std::unique_ptr<Persistable>
	Persistable::callFactory(const std::string_view t)
	{
		return namedTypeFactories().at(t).first();
	}

	std::shared_ptr<Persistable>
	Persistable::callSharedFactory(const std::string_view t)
	{
		return namedTypeFactories().at(t).second();
	}

	[[nodiscard]] std::string
	Persistable::getId() const
	{
		std::stringstream ss;
		ss << std::hex << this;
		return ss.str();
	}

	PersistenceSelect::PersistenceSelect(const std::string & n) : name {n} { }

	PersistenceStore::NameAction
	PersistenceSelect::setName(const std::string_view key, const Selection &)
	{
		return (key == name) ? NameAction::Push : NameAction::Ignore;
	}

	void
	PersistenceSelect::setType(const std::string_view, const Persistable *)
	{
	}

	PersistenceWrite::PersistenceWrite(const Writer & o, bool sh) : out {o}, shared {sh} { }

	PersistenceStore::NameAction
	PersistenceWrite::setName(const std::string_view key, const Selection & s)
	{
		if (s.needsWrite()) {
			if (!first) {
				out.nextValue();
			}
			else {
				first = false;
			}
			out.pushKey(key);
			return NameAction::HandleAndContinue;
		}
		return NameAction::Ignore;
	}

	void
	PersistenceWrite::selHandler()
	{
		this->sel->write(out);
	}

	void
	PersistenceWrite::setType(const std::string_view tn, const Persistable * p)
	{
		out.pushKey("p.typeid");
		out.pushValue(tn);
		first = false;
		if (shared) {
			out.nextValue();
			out.pushKey("p.id");
			out.pushValue(p->getId());
		}
	}

	void
	Selection::setValue(float)
	{
		throw std::runtime_error("Unexpected float");
	}

	void
	Selection::setValue(bool)
	{
		throw std::runtime_error("Unexpected bool");
	}

	void
	Selection::setValue(std::nullptr_t)
	{
		throw std::runtime_error("Unexpected null");
	}

	void
	Selection::setValue(std::string &&)
	{
		throw std::runtime_error("Unexpected string");
	}

	void
	Selection::beginArray(Stack &)
	{
		throw std::runtime_error("Unexpected array");
	}

	void
	Selection::beginObject(Stack &)
	{
		throw std::runtime_error("Unexpected object");
	}

	/// LCOV_EXCL_START Don't think we can trigger these from something lexer will parse
	void
	Selection::beforeValue(Stack &)
	{
		throw std::runtime_error("Unexpected value");
	}

	SelectionPtr
	Selection::select(const std::string &)
	{
		throw std::runtime_error("Unexpected select");
	}

	void
	Selection::endObject(Stack &)
	{
	}

	bool
	Selection::needsWrite() const
	{
		return true;
	}

	void
	Selection::write(const Writer &) const
	{
		throw std::logic_error("Default write op shouldn't ever get called");
	}
	/// LCOV_EXCL_STOP
}