/* @file JsonPrinter.hpp * * author: Roland Conybeare, Aug 2022 */ #pragma once #include "xo/reflect/Reflect.hpp" #include "xo/reflect/TypeDrivenMap.hpp" #include "xo/reflect/TaggedPtr.hpp" //#include #include namespace xo { namespace json { class PrintJson; class JsonPrinter { public: using Reflect = xo::reflect::Reflect; using TaggedPtr = xo::reflect::TaggedPtr; using TypeDescr = xo::reflect::TypeDescr; using TypeId = xo::reflect::TypeId; public: JsonPrinter(PrintJson const * pjson) : pjson_{pjson} {} virtual ~JsonPrinter() = default; PrintJson const * pjson() const { return pjson_; } /* print tagged pointer in json format */ virtual void print_json(TaggedPtr tp, std::ostream * p_os) const = 0; void report_internal_type_consistency_error(TypeDescr td1, TypeDescr td2, std::ostream * p_os) const; /* convenience method for derived printers. * retrieves contents of tp as a T*, complains to *p_os if that fails. * * (Failure would occur if printer for type T was instead installed * for some unrelated type U) */ template T * check_recover_native(TaggedPtr tp, std::ostream * p_os) const { T * x = tp.recover_native(); if (!x) { this->report_internal_type_consistency_error(Reflect::require(), tp.td(), p_os); } return x; } /*check_recover_native*/ void assign_pjson(PrintJson const * pjson) { assert(this->pjson_ == nullptr || this->pjson_ == pjson); this->pjson_ = pjson; } /*assign_pjson*/ private: /* a json printers is installed into one PrintJson instance; * capture address of that instance at install time */ PrintJson const * pjson_ = nullptr; }; /*JsonPrinter*/ /* AsStringJsonPrinter * prints a T-instance by using operator<< and surrounding in quotes. * * e.g: * T & x = ..; * std::ostream * p_os = ..; * * *p_os << "\"" << x << "\"" * */ template class AsStringJsonPrinter : public JsonPrinter { public: AsStringJsonPrinter(PrintJson const * pjson) : JsonPrinter(pjson) {} virtual void print_json(TaggedPtr tp, std::ostream * p_os) const override { T * x = this->check_recover_native(tp, p_os); if(x) { *p_os << "\"" << *x << "\""; } } /*print_json*/ }; /*AsStringJsonPrinter*/ } /*namespace json*/ } /*namespace xo*/ /* end JsonPrinter.hpp */