aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/jinja2cpp/src/render_context.h
diff options
context:
space:
mode:
authorsnaury <snaury@yandex-team.com>2024-10-16 12:16:48 +0300
committersnaury <snaury@yandex-team.com>2024-10-16 12:32:13 +0300
commite0fb25470a47f0c243091ed28bf54a186f732f6a (patch)
treee85dfe628401f4f21749ab95b9d711242e3b49cd /contrib/libs/jinja2cpp/src/render_context.h
parentb3b4a0b9681eb0981f9958a426c95a53f79169a7 (diff)
downloadydb-e0fb25470a47f0c243091ed28bf54a186f732f6a.tar.gz
ydblib: add jinja2cpp
commit_hash:f3563041f6f6f7443e75fc99acd2c967d0debb04
Diffstat (limited to 'contrib/libs/jinja2cpp/src/render_context.h')
-rw-r--r--contrib/libs/jinja2cpp/src/render_context.h182
1 files changed, 182 insertions, 0 deletions
diff --git a/contrib/libs/jinja2cpp/src/render_context.h b/contrib/libs/jinja2cpp/src/render_context.h
new file mode 100644
index 0000000000..f6edcf444e
--- /dev/null
+++ b/contrib/libs/jinja2cpp/src/render_context.h
@@ -0,0 +1,182 @@
+#ifndef JINJA2CPP_SRC_RENDER_CONTEXT_H
+#define JINJA2CPP_SRC_RENDER_CONTEXT_H
+
+#include "internal_value.h"
+#include <jinja2cpp/error_info.h>
+#include <jinja2cpp/utils/i_comparable.h>
+
+#include <contrib/restricted/expected-lite/include/nonstd/expected.hpp>
+
+#include <list>
+#include <deque>
+
+namespace jinja2
+{
+template<typename CharT>
+class TemplateImpl;
+
+struct IRendererCallback : IComparable
+{
+ virtual ~IRendererCallback() {}
+ virtual TargetString GetAsTargetString(const InternalValue& val) = 0;
+ virtual OutStream GetStreamOnString(TargetString& str) = 0;
+ virtual std::variant<EmptyValue,
+ nonstd::expected<std::shared_ptr<TemplateImpl<char>>, ErrorInfo>,
+ nonstd::expected<std::shared_ptr<TemplateImpl<wchar_t>>, ErrorInfoW>> LoadTemplate(const std::string& fileName) const = 0;
+ virtual std::variant<EmptyValue,
+ nonstd::expected<std::shared_ptr<TemplateImpl<char>>, ErrorInfo>,
+ nonstd::expected<std::shared_ptr<TemplateImpl<wchar_t>>, ErrorInfoW>> LoadTemplate(const InternalValue& fileName) const = 0;
+ virtual void ThrowRuntimeError(ErrorCode code, ValuesList extraParams) = 0;
+};
+
+class RenderContext
+{
+public:
+ RenderContext(const InternalValueMap& extValues, const InternalValueMap& globalValues, IRendererCallback* rendererCallback)
+ : m_rendererCallback(rendererCallback)
+ {
+ m_externalScope = &extValues;
+ m_globalScope = &globalValues;
+ EnterScope();
+ (*m_currentScope)["self"] = CreateMapAdapter(InternalValueMap());
+ }
+
+ RenderContext(const RenderContext& other)
+ : m_rendererCallback(other.m_rendererCallback)
+ , m_externalScope(other.m_externalScope)
+ , m_globalScope(other.m_globalScope)
+ , m_boundScope(other.m_boundScope)
+ , m_scopes(other.m_scopes)
+ {
+ m_currentScope = &m_scopes.back();
+ }
+
+ InternalValueMap& EnterScope()
+ {
+ m_scopes.push_back(InternalValueMap());
+ m_currentScope = &m_scopes.back();
+ return *m_currentScope;
+ }
+
+ void ExitScope()
+ {
+ m_scopes.pop_back();
+ if (!m_scopes.empty())
+ m_currentScope = &m_scopes.back();
+ else
+ m_currentScope = nullptr;
+ }
+
+ auto FindValue(const std::string& val, bool& found) const
+ {
+ auto finder = [&val, &found](auto& map) mutable
+ {
+ auto p = map.find(val);
+ if (p != map.end())
+ found = true;
+
+ return p;
+ };
+
+ if (m_boundScope)
+ {
+ auto valP = finder(*m_boundScope);
+ if (found)
+ return valP;
+ }
+
+ for (auto p = m_scopes.rbegin(); p != m_scopes.rend(); ++ p)
+ {
+ auto valP = finder(*p);
+ if (found)
+ return valP;
+ }
+
+ auto valP = finder(*m_externalScope);
+ if (found)
+ return valP;
+
+ return finder(*m_globalScope);
+ }
+
+ auto& GetCurrentScope() const
+ {
+ return *m_currentScope;
+ }
+
+ auto& GetCurrentScope()
+ {
+ return *m_currentScope;
+ }
+ auto& GetGlobalScope()
+ {
+ return m_scopes.front();
+ }
+ auto GetRendererCallback()
+ {
+ return m_rendererCallback;
+ }
+ RenderContext Clone(bool includeCurrentContext) const
+ {
+ if (!includeCurrentContext)
+ return RenderContext(m_emptyScope, *m_globalScope, m_rendererCallback);
+
+ return RenderContext(*this);
+ }
+
+ void BindScope(InternalValueMap* scope)
+ {
+ m_boundScope = scope;
+ }
+
+ bool IsEqual(const RenderContext& other) const
+ {
+ if (!IsEqual(m_rendererCallback, other.m_rendererCallback))
+ return false;
+ if (!IsEqual(this->m_currentScope, other.m_currentScope))
+ return false;
+ if (!IsEqual(m_externalScope, other.m_externalScope))
+ return false;
+ if (!IsEqual(m_globalScope, other.m_globalScope))
+ return false;
+ if (!IsEqual(m_boundScope, other.m_boundScope))
+ return false;
+ if (m_emptyScope != other.m_emptyScope)
+ return false;
+ if (m_scopes != other.m_scopes)
+ return false;
+ return true;
+ }
+
+private:
+
+ bool IsEqual(const IRendererCallback* lhs, const IRendererCallback* rhs) const
+ {
+ if (lhs && rhs)
+ return lhs->IsEqual(*rhs);
+ if ((!lhs && rhs) || (lhs && !rhs))
+ return false;
+ return true;
+ }
+
+ bool IsEqual(const InternalValueMap* lhs, const InternalValueMap* rhs) const
+ {
+ if (lhs && rhs)
+ return *lhs == *rhs;
+ if ((!lhs && rhs) || (lhs && !rhs))
+ return false;
+ return true;
+ }
+
+private:
+ IRendererCallback* m_rendererCallback{};
+ InternalValueMap* m_currentScope{};
+ const InternalValueMap* m_externalScope{};
+ const InternalValueMap* m_globalScope{};
+ const InternalValueMap* m_boundScope{};
+ InternalValueMap m_emptyScope;
+ std::deque<InternalValueMap> m_scopes;
+};
+} // namespace jinja2
+
+#endif // JINJA2CPP_SRC_RENDER_CONTEXT_H