aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yaml/fyamlcpp/fyamlcpp.h
diff options
context:
space:
mode:
authorinnokentii <innokentii@yandex-team.com>2023-02-01 16:01:14 +0300
committerinnokentii <innokentii@yandex-team.com>2023-02-01 16:01:14 +0300
commit96b135245109ad10d4e6a51d9f7fa61add23e839 (patch)
tree754dd793a8952d93f8da462c781404f3563114f8 /library/cpp/yaml/fyamlcpp/fyamlcpp.h
parentacce22d4812c919616875de449eb6eb69006593a (diff)
downloadydb-96b135245109ad10d4e6a51d9f7fa61add23e839.tar.gz
Add basic yaml config resolver
Diffstat (limited to 'library/cpp/yaml/fyamlcpp/fyamlcpp.h')
-rw-r--r--library/cpp/yaml/fyamlcpp/fyamlcpp.h593
1 files changed, 593 insertions, 0 deletions
diff --git a/library/cpp/yaml/fyamlcpp/fyamlcpp.h b/library/cpp/yaml/fyamlcpp/fyamlcpp.h
new file mode 100644
index 00000000000..7437b74ef7f
--- /dev/null
+++ b/library/cpp/yaml/fyamlcpp/fyamlcpp.h
@@ -0,0 +1,593 @@
+#pragma once
+
+#include <util/generic/yexception.h>
+#include <util/system/compiler.h>
+#include <util/system/yassert.h>
+#include <util/stream/str.h>
+
+#include <memory>
+#include <optional>
+
+struct fy_node;
+struct fy_document;
+struct fy_diag;
+struct fy_document_iterator;
+struct fy_node_pair;
+
+namespace NFyaml {
+
+struct TFyamlEx : public yexception {};
+
+enum class ENodeType {
+ Scalar,
+ Sequence,
+ Mapping,
+};
+
+namespace NDetail {
+
+class IBasicUserData {
+public:
+ virtual ~IBasicUserData() = default;
+};
+
+template <class T>
+class TUserDataHolder : public IBasicUserData {
+public:
+ TUserDataHolder(IBasicUserData* next, T* data)
+ : Next_(next)
+ , Data_(data)
+ {}
+
+private:
+ std::unique_ptr<IBasicUserData> Next_ = nullptr;
+ std::unique_ptr<T> Data_ = nullptr;
+};
+
+void RethrowError(fy_diag* diag);
+
+void RethrowOnError(bool isError, fy_node* node);
+
+void RethrowOnError(bool isError, fy_node_pair* pair);
+
+void RethrowOnError(bool isError, fy_diag* diag);
+
+void FreeChar(char* mem);
+
+} // namespace NDetail
+
+class TNodeRef;
+class TDocumentIterator;
+class TDocument;
+class TNode;
+class TMappingIterator;
+class TReverseMappingIterator;
+class TMapping;
+class TSequenceIterator;
+class TReverseSequenceIterator;
+class TSequence;
+class TJsonEmitter;
+
+class TDocumentIterator {
+ friend class TDocument;
+public:
+ TDocumentIterator(fy_document_iterator* iterator = nullptr);
+
+protected:
+ std::unique_ptr<fy_document_iterator, void(*)(fy_document_iterator*)> Iterator_;
+};
+
+class TNodeRef {
+ friend class TDocument;
+ friend class TDocumentNodeIterator;
+ friend class TNode;
+ friend class TMapping;
+ friend class TMappingIterator;
+ friend class TReverseMappingIterator;
+ friend class TNodePairRef;
+ friend class TSequence;
+ friend class TSequenceIterator;
+ friend class TReverseSequenceIterator;
+
+ TNodeRef(fy_node* node)
+ : Node_(node)
+ {}
+
+public:
+ TNodeRef() {};
+
+ TNodeRef(const TNodeRef& other) { Node_ = other.Node_; }
+
+ TNodeRef& operator=(const TNodeRef& other) { Node_ = other.Node_; return *this; }
+
+ TNodeRef& operator=(fy_node* node) { Node_ = node; return *this; }
+
+ bool operator==(const TNodeRef& other) const { return Node_ == other.Node_; }
+
+ explicit operator bool() const { return Node_ != nullptr; }
+
+ TString Path() const;
+
+ ENodeType Type() const;
+
+ TNode Copy() const;
+
+ bool IsAlias() const;
+
+ TNodeRef ResolveAlias() const;
+
+ TNode CreateReference() const;
+
+ TSequence Sequence() const;
+
+ TMapping Map() const;
+
+ TString Scalar() const;
+
+ void Insert(const TNodeRef& node);
+
+ bool Empty() const { return Node_ == nullptr; }
+
+ std::optional<TString> Tag() const;
+
+ void SetTag(const TString& tag);
+
+ bool RemoveTag();
+
+ bool HasAnchor() const;
+
+ void SetAnchor(const TString& anchor);
+
+ bool DeepEqual(const TNodeRef& other);
+
+ std::unique_ptr<char, void(*)(char*)> EmitToCharArray() const;
+
+protected:
+ fy_node* Node_ = nullptr;
+
+ void SetUserData(NDetail::IBasicUserData* data);
+ NDetail::IBasicUserData* UserData() const;
+ void ClearUserData();
+};
+
+class TNode {
+ friend class TDocument;
+ friend class TDocumentNodeIterator;
+ friend class TNodeRef;
+ friend class TSequence;
+
+ TNode& operator=(fy_node* node);
+public:
+ TNode(fy_node* node = nullptr);
+
+ bool operator==(const TNode& other) const { return Node_ == other.Node_; }
+
+ explicit operator bool() { return Node_ != nullptr; }
+
+ TNodeRef Ref() { return TNodeRef(Node_.get()); }
+
+private:
+ std::shared_ptr<fy_node> Node_;
+};
+
+class TNodePairRef {
+ friend class TMappingIterator;
+ friend class TReverseMappingIterator;
+ friend class TMapping;
+public:
+ TNodePairRef(fy_node_pair* pair = nullptr)
+ : Pair_(pair)
+ {}
+
+ bool operator==(const TNodePairRef& other) const { return Pair_ == other.Pair_; }
+
+ explicit operator bool() const { return Pair_ != nullptr; }
+
+ TNodeRef Key() const;
+
+ void SetKey(const TNodeRef& node);
+
+ TNodeRef Value() const;
+
+ void SetValue(const TNodeRef& node);
+
+private:
+ fy_node_pair* Pair_ = nullptr;
+};
+
+class TMappingIterator {
+ friend class TMapping;
+public:
+ TMappingIterator(const TNodeRef& node, bool end = false);
+
+ TMappingIterator(const TMappingIterator& other) {
+ Node_ = other.Node_;
+ NodePair_ = other.NodePair_;
+ }
+
+ TMappingIterator& operator=(const TMappingIterator& other) {
+ Node_ = other.Node_;
+ NodePair_ = other.NodePair_;
+ return *this;
+ }
+
+ TMappingIterator& operator++();
+
+ const TNodePairRef* operator->() const { return &NodePair_; }
+
+ TMappingIterator operator++(int) {
+ TMappingIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TMappingIterator other) const { return Node_ == other.Node_ && NodePair_ == other.NodePair_; }
+
+ const TNodePairRef& operator*() const { return NodePair_; }
+
+private:
+ TNodeRef Node_;
+ TNodePairRef NodePair_;
+};
+
+class TReverseMappingIterator {
+ friend class TMapping;
+public:
+ TReverseMappingIterator(const TNodeRef& node, bool end = false);
+
+ TReverseMappingIterator(const TReverseMappingIterator& other) {
+ Node_ = other.Node_;
+ NodePair_ = other.NodePair_;
+ }
+
+ TReverseMappingIterator& operator=(const TReverseMappingIterator& other) {
+ Node_ = other.Node_;
+ NodePair_ = other.NodePair_;
+ return *this;
+ }
+
+ TReverseMappingIterator& operator++();
+
+ const TNodePairRef* operator->() const { return &NodePair_; }
+
+ TReverseMappingIterator operator++(int) {
+ TReverseMappingIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TReverseMappingIterator other) const { return Node_ == other.Node_ && NodePair_ == other.NodePair_; }
+
+ bool operator!=(TReverseMappingIterator other) const { return !(*this == other); }
+
+ const TNodePairRef& operator*() const { return NodePair_; }
+
+private:
+ TNodeRef Node_;
+ TNodePairRef NodePair_;
+};
+
+class TMapping : public TNodeRef {
+public:
+ explicit TMapping(const TNodeRef& node)
+ : TNodeRef(node)
+ {
+ Y_VERIFY_DEBUG(Type() == ENodeType::Mapping);
+ }
+
+ TMappingIterator begin() const {
+ return TMappingIterator(Node_);
+ }
+
+ TMappingIterator end() const {
+ return TMappingIterator(Node_, true);
+ }
+
+ TReverseMappingIterator rbegin() const {
+ return TReverseMappingIterator(Node_);
+ }
+
+ TReverseMappingIterator rend() const {
+ return TReverseMappingIterator(Node_, true);
+ }
+
+ size_t size() const;
+
+ size_t empty() const;
+
+ TNodePairRef at(int index) const;
+
+ TNodePairRef operator[](int index) const;
+
+ TNodeRef at(const TString& index) const;
+
+ TNodePairRef pair_at(const TString& index) const;
+
+ TNodePairRef pair_at_opt(const TString& index) const;
+
+ TNodeRef operator[](const TString& index) const;
+
+ TNodeRef operator[](const char* str) const;
+
+ void Append(const TNodeRef& key, const TNodeRef& value);
+
+ void Prepend(const TNodeRef& key, const TNodeRef& value);
+
+ void Remove(const TNodePairRef& toRemove);
+
+ TMappingIterator Remove(const TMappingIterator& toRemove);
+
+ void Remove(const TNodeRef& key);
+};
+
+class TSequenceIterator {
+ friend class TSequence;
+public:
+ TSequenceIterator(const TNodeRef& node, bool end = false);
+
+ TSequenceIterator(const TSequenceIterator& other) {
+ Node_ = other.Node_;
+ IterNode_ = other.IterNode_;
+ Iter_ = other.Iter_;
+ }
+
+ TSequenceIterator& operator=(const TSequenceIterator& other) {
+ Node_ = other.Node_;
+ IterNode_ = other.IterNode_;
+ Iter_ = other.Iter_;
+ return *this;
+ }
+
+ TSequenceIterator& operator++();
+
+ const TNodeRef* operator->() const {
+ return &IterNode_;
+ }
+
+ TSequenceIterator operator++(int) {
+ TSequenceIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TSequenceIterator other) const { return Node_ == other.Node_ && Iter_ == other.Iter_; }
+
+ bool operator!=(TSequenceIterator other) const { return !(*this == other); }
+
+ const TNodeRef& operator*() const { return IterNode_; }
+
+ void InsertBefore(const TNodeRef& node);
+
+ void InsertAfter(const TNodeRef& node);
+
+private:
+ TNodeRef Node_;
+ TNodeRef IterNode_;
+ void* Iter_ = nullptr;
+};
+
+class TReverseSequenceIterator {
+ friend class TSequence;
+public:
+ TReverseSequenceIterator(const TNodeRef& node, bool end = false);
+
+ TReverseSequenceIterator(const TReverseSequenceIterator& other) {
+ Node_ = other.Node_;
+ IterNode_ = other.IterNode_;
+ Iter_ = other.Iter_;
+ }
+
+ TReverseSequenceIterator& operator=(const TReverseSequenceIterator& other) {
+ Node_ = other.Node_;
+ IterNode_ = other.IterNode_;
+ Iter_ = other.Iter_;
+ return *this;
+ }
+
+ TReverseSequenceIterator& operator++();
+
+ const TNodeRef* operator->() const {
+ return &IterNode_;
+ }
+
+ TReverseSequenceIterator operator++(int) {
+ TReverseSequenceIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TReverseSequenceIterator other) const { return Node_ == other.Node_ && Iter_ == other.Iter_; }
+
+ bool operator!=(TReverseSequenceIterator other) const { return !(*this == other); }
+
+ const TNodeRef& operator*() const { return IterNode_; }
+
+ void InsertBefore(const TNodeRef& node);
+
+ void InsertAfter(const TNodeRef& node);
+
+private:
+ TNodeRef Node_;
+ TNodeRef IterNode_;
+ void* Iter_ = nullptr;
+};
+
+class TSequence : public TNodeRef {
+public:
+ explicit TSequence(const TNodeRef& node)
+ : TNodeRef(node)
+ {
+ Y_VERIFY_DEBUG(Type() == ENodeType::Sequence);
+ }
+
+ TSequenceIterator begin() const {
+ return TSequenceIterator(Node_);
+ }
+
+ TSequenceIterator end() const {
+ return TSequenceIterator(Node_, true);
+ }
+
+ TReverseSequenceIterator rbegin() const {
+ return TReverseSequenceIterator(Node_);
+ }
+
+ TReverseSequenceIterator rend() const {
+ return TReverseSequenceIterator(Node_, true);
+ }
+
+ size_t size() const;
+
+ size_t empty() const;
+
+ TNodeRef at(int index) const;
+
+ TNodeRef operator[](int index) const;
+
+ void Append(const TNodeRef& node);
+
+ void Prepend(const TNodeRef& node);
+
+ void InsertBefore(const TNodeRef& mark, const TNodeRef& node);
+
+ void InsertAfter(const TNodeRef& mark, const TNodeRef& node);
+
+ TNode Remove(const TNodeRef& toRemove);
+
+ TSequenceIterator Remove(const TSequenceIterator& toRemove);
+
+ TReverseSequenceIterator Remove(const TReverseSequenceIterator& toRemove);
+};
+
+class TDocumentNodeIterator
+ : public TDocumentIterator
+{
+public:
+ TDocumentNodeIterator(TNodeRef&& node);
+
+ TDocumentNodeIterator(const TDocumentNodeIterator& other)
+ : TDocumentIterator(other.Iterator_.get())
+ , Node_(other.Node_)
+ {}
+
+ TDocumentNodeIterator& operator=(const TDocumentNodeIterator& other) {
+ Iterator_.reset(other.Iterator_.get());
+ Node_ = other.Node_;
+ return *this;
+ }
+
+ TDocumentNodeIterator& operator++();
+
+ TNodeRef* operator->() {
+ return &Node_;
+ }
+
+ TDocumentNodeIterator operator++(int) {
+ TDocumentNodeIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TDocumentNodeIterator other) const { return Node_ == other.Node_; }
+
+ bool operator!=(TDocumentNodeIterator other) const { return !(*this == other); }
+
+ TNodeRef& operator*() { return Node_; }
+
+private:
+ TNodeRef Node_;
+};
+
+class TDocument {
+ friend class TNode;
+ friend class TJsonEmitter;
+
+ TDocument(fy_document* doc = nullptr, fy_diag* diag = nullptr);
+
+public:
+ TDocument(TDocument&& other)
+ : Document_(std::move(other.Document_))
+ , Diag_(std::move(other.Diag_))
+ {}
+
+ static TDocument Parse(const char* cstr);
+
+ TDocument Clone() const;
+
+ template <class... Args>
+ size_t Scanf(const char* fmt, Args&& ...args) {
+ Y_VERIFY_DEBUG(Document_);
+ return fy_document_scanf(Document_.get(), fmt, std::forward<Args>(args)...);
+ }
+
+ void InsertAt(const char* path, const TNodeRef& node);
+
+ template <class... Args>
+ TNodeRef Buildf(const char* fmt, Args&& ...args) {
+ Y_VERIFY_DEBUG(Document_);
+ return fy_node_buildf(Document_.get(), fmt, std::forward<Args>(args)...);
+ }
+
+ TNodeRef Buildf(const char* content);
+
+ void Resolve();
+
+ bool HasDirectives();
+
+ bool HasExplicitDocumentStart();
+
+ bool HasExplicitDocumentEnd();
+
+ void SetParent(const TDocument& doc);
+
+ TNodeRef Root();
+
+ void SetRoot(const TNodeRef& node);
+
+ TDocumentNodeIterator begin() {
+ auto it = TDocumentNodeIterator(Root());
+ ++it;
+ return it;
+ }
+
+
+ TDocumentNodeIterator end() {
+ return TDocumentNodeIterator(TNodeRef(nullptr));
+ }
+
+ TNodeRef CreateAlias(const TString& name);
+
+ std::unique_ptr<char, void(*)(char*)> EmitToCharArray() const;
+
+private:
+ std::unique_ptr<fy_document, void(*)(fy_document*)> Document_;
+ std::unique_ptr<fy_diag, void(*)(fy_diag*)> Diag_;
+
+ static void DestroyUserData(fy_node *fyn, void *meta, void *user) {
+ Y_UNUSED(fyn);
+ Y_UNUSED(user);
+ if (meta) {
+ auto* data = reinterpret_cast<NDetail::IBasicUserData*>(meta);
+ delete data;
+ }
+ }
+
+ bool RegisterUserDataCleanup();
+ void UnregisterUserDataCleanup();
+};
+
+class TJsonEmitter {
+public:
+ TJsonEmitter(const TDocument& doc) : Document_(doc) {}
+
+ std::unique_ptr<char, void(*)(char*)> EmitToCharArray() const;
+
+private:
+ const TDocument& Document_;
+
+ fy_document* Document() const {
+ return Document_.Document_.get();
+ }
+};
+
+} // namesapce NFyaml