libkazv
Loading...
Searching...
No Matches
context.hpp
Go to the documentation of this file.
1/*
2 * This file is part of libkazv.
3 * SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
4 * SPDX-License-Identifier: AGPL-3.0-or-later
5 */
6
7#pragma once
8
9#include <lager/deps.hpp>
10
11#include <boost/hana.hpp>
12
13#include <jsonwrap.hpp>
14#include <promise-interface.hpp>
15
16namespace Kazv
17{
19 {
20 public:
21 inline EffectStatus() : m_succ(true) {}
22 inline EffectStatus(bool succ) : m_succ(succ) {}
23 inline EffectStatus(bool succ, JsonWrap d) : m_succ(succ), m_data(d) {}
24
30 inline bool success() const { return m_succ; }
36 inline explicit operator bool() const { return success(); }
42 inline const JsonWrap &data() const { return m_data; }
43
52 inline const json &dataJson(std::string key) const {
53 return data().get().at(key);
54 }
55
65 inline const json &dataJson(int index, std::string key) const {
66 return data().get().at(index).at(key);
67 }
68
78 inline std::string dataStr(std::string key) const {
79 return dataJson(key).template get<std::string>();
80 }
81
92 inline std::string dataStr(int index, std::string key) const {
93 return dataJson(index, key).template get<std::string>();
94 }
95 private:
96 bool m_succ;
97 JsonWrap m_data;
98 };
99
101 {
102 return EffectStatus{true, json::array()};
103 }
104
106 {
107 auto succ = a.success() && b.success();
108 auto data = a.data().get().is_array()
109 ? a.data().get()
110 : json::array({a.data().get()});
111 if (b.data().get().is_array()) {
112 for (const auto &i: b.data().get()) {
113 data.push_back(i);
114 }
115 } else {
116 data.push_back(b.data().get());
117 }
118 return {succ, data};
119 }
120
122 {
123 return EffectStatus(true);
124 }
125
127
128 template<class T, class Action, class Deps = lager::deps<>>
129 class ContextBase : public Deps
130 {
131 public:
132 using RetType = T;
135 template<class Func>
136 ContextBase(Func &&dispatcher, PromiseInterfaceT ph, Deps deps)
137 : Deps(std::move(deps))
138 , m_ph(ph)
139 , m_dispatcher(std::forward<Func>(dispatcher))
140 {
141 }
142
143 template<class AnotherAction, class AnotherDeps,
144 std::enable_if_t<std::is_convertible_v<Action, AnotherAction>
145 && std::is_convertible_v<AnotherDeps, Deps>, int> = 0>
147 : Deps(that)
148 , m_ph(that.m_ph)
149 , m_dispatcher(that.m_dispatcher)
150 {
151 }
152
153 template<class AnotherAction, class AnotherDeps, class Conv,
154 std::enable_if_t<std::is_convertible_v<std::invoke_result_t<Conv, Action>, AnotherAction>
155 && std::is_convertible_v<AnotherDeps, Deps>, int> = 0>
157 : Deps(that)
158 , m_ph(that.m_ph)
159 , m_dispatcher([=,
160 thatDispatcher=that.m_dispatcher,
161 conv=std::forward<Conv>(conv)](Action a) {
162 thatDispatcher(conv(std::move(a)));
163 })
164 {
165 }
166
167 PromiseT dispatch(Action a) const {
168 return m_dispatcher(std::move(a));
169 }
170
171 decltype(auto) deps() {
172 return static_cast<Deps &>(*this);
173 }
174
175 template<class Func>
176 PromiseT createPromise(Func func) const {
177 return m_ph.create(std::move(func));
178 }
179
180 template<class Func>
182 return m_ph.createResolveToPromise(std::move(func));
183 }
184
186 return m_ph.createResolved(v);
187 }
188
190 return m_ph;
191 }
192
193 private:
194 template<class R2, class A2, typename D2>
195 friend class ContextBase;
197 std::function<PromiseT(Action)> m_dispatcher;
198 };
199
200 template<class A, class D = lager::deps<>>
202
203 template<class T, class Action, class Deps = lager::deps<>>
205 {
206 public:
207 using RetType = T;
210
226 template<class Func>
227 EffectBase(Func func) {
228 if constexpr (std::is_same_v<std::invoke_result_t<Func, ContextT>, void>) {
229 m_d = [func=std::move(func)](const auto &ctx) {
230 return ctx.createPromise(
231 [ctx,
232 func](auto resolve) {
233 func(ctx);
234 resolve(PromiseCombination::defaultForPromiseThen(RetType()));
235 });
236 };
237 } else {
238 m_d = [func=std::move(func)](const auto &ctx) {
239 return ctx.createResolvedPromise(PromiseCombination::defaultForPromiseThen(RetType()))
240 .then([ctx,
241 func](auto) {
242 return func(ctx);
243 });
244 };
245 }
246 }
247
248 PromiseT operator()(const ContextT &ctx) const {
249 return m_d(ctx);
250 }
251
252 private:
253 std::function<PromiseT(const ContextT &)> m_d;
254 };
255
256 template<class A, class D = lager::deps<>>
258
259 template<class Reducer, class RetType, class Model, class Action, class Deps>
260 constexpr bool hasEffect = boost::hana::is_valid(
261 []() -> decltype((void)EffectBase<RetType, Action, Deps>(
262 std::get<1>(std::declval<std::invoke_result_t<Reducer, Model, Action>>()))) {}
263 )();
264
265}
Definition context.hpp:130
PromiseT createWaitingPromise(Func func) const
Definition context.hpp:181
PromiseT dispatch(Action a) const
Definition context.hpp:167
PromiseT createResolvedPromise(RetType v) const
Definition context.hpp:185
PromiseInterfaceT promiseInterface() const
Definition context.hpp:189
PromiseT createPromise(Func func) const
Definition context.hpp:176
decltype(auto) deps()
Definition context.hpp:171
SingleTypePromise< RetType > PromiseT
Definition context.hpp:134
ContextBase(const ContextBase< RetType, AnotherAction, AnotherDeps > &that, Conv &&conv)
Definition context.hpp:156
ContextBase(Func &&dispatcher, PromiseInterfaceT ph, Deps deps)
Definition context.hpp:136
ContextBase(const ContextBase< RetType, AnotherAction, AnotherDeps > &that)
Definition context.hpp:146
T RetType
Definition context.hpp:132
Definition context.hpp:205
EffectBase(Func func)
Constructor.
Definition context.hpp:227
PromiseT operator()(const ContextT &ctx) const
Definition context.hpp:248
T RetType
Definition context.hpp:207
SingleTypePromise< RetType > PromiseT
Definition context.hpp:208
ContextBase< RetType, Action, Deps > ContextT
Definition context.hpp:209
Definition context.hpp:19
EffectStatus()
Definition context.hpp:21
const JsonWrap & data() const
Get the attached data.
Definition context.hpp:42
const json & dataJson(int index, std::string key) const
Get the data at index at key.
Definition context.hpp:65
bool success() const
Get whether this is successful.
Definition context.hpp:30
const json & dataJson(std::string key) const
Get the data at key.
Definition context.hpp:52
EffectStatus(bool succ, JsonWrap d)
Definition context.hpp:23
std::string dataStr(std::string key) const
Get the data string at key.
Definition context.hpp:78
EffectStatus(bool succ)
Definition context.hpp:22
std::string dataStr(int index, std::string key) const
Get the data at index at key.
Definition context.hpp:92
Definition jsonwrap.hpp:23
const json & get() const
Definition jsonwrap.hpp:40
PromiseT createResolveToPromise(std::function< void(ResolveToPromiseT)> f) const
Definition promise-interface.hpp:280
PromiseT create(std::function< void(ResolveT)> f) const
Definition promise-interface.hpp:276
PromiseT createResolved(DataT v) const
Definition promise-interface.hpp:284
Definition promise-interface.hpp:122
Definition location.hpp:10
EffectStatus dataCombineNone(EffectStatus)
Definition context.hpp:121
EffectStatus createDefaultForPromiseThen(EffectStatus)
Definition context.hpp:100
nlohmann::json json
Definition jsonwrap.hpp:20
EffectStatus dataCombine(EffectStatus a, EffectStatus b)
Definition context.hpp:105
constexpr bool hasEffect
Definition context.hpp:260
Definition clientutil.hpp:140