diff --git a/src/olympic/keel/include/keel/typeconv.hpp b/src/olympic/keel/include/keel/typeconv.hpp index 07a238f0..494e4c1e 100644 --- a/src/olympic/keel/include/keel/typeconv.hpp +++ b/src/olympic/keel/include/keel/typeconv.hpp @@ -174,6 +174,73 @@ class Converter: public BaseConverter { }; + +template +class ConverterFunc: public BaseConverter { + private: + template + struct ParamExtractor { + using Src = SrcType; + using Dst = DstType; + }; + + template + static auto makeParamExtractor(ox::Error (*)(keel::Context&, S&, D&)) { + return ParamExtractor{}; + } + + public: + using SrcType = decltype(makeParamExtractor(Func))::Src; + using DstType = decltype(makeParamExtractor(Func))::Dst; + + [[nodiscard]] + constexpr ox::StringView srcTypeName() const noexcept final { + return ox::ModelTypeName_v; + } + + [[nodiscard]] + constexpr int srcTypeVersion() const noexcept final { + return ox::ModelTypeVersion_v; + } + + [[nodiscard]] + constexpr bool srcMatches(ox::StringViewCR pSrcTypeName, int pSrcTypeVersion) const noexcept final { + constexpr auto SrcTypeName = ox::requireModelTypeName(); + constexpr auto SrcTypeVersion = ox::requireModelTypeVersion(); + return pSrcTypeName == SrcTypeName + && pSrcTypeVersion == SrcTypeVersion; + } + + [[nodiscard]] + constexpr bool dstMatches(ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept final { + constexpr auto DstTypeName = ox::StringView{ox::requireModelTypeName()}; + constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); + return dstTypeName == DstTypeName + && dstTypeVersion == DstTypeVersion; + } + + ox::Result> convertPtrToPtr( + keel::Context &ctx, Wrap &src) const noexcept final { + ox::Result> dst{makeWrap()}; + OX_RETURN_ERROR(convert(ctx, wrapCast(src), wrapCast(*dst.value))); + return dst; + } + + ox::Result> convertBuffToPtr( + keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final { + OX_REQUIRE_M(src, readAsset(srcBuff)); + ox::Result> dst{makeWrap()}; + OX_RETURN_ERROR(convert(ctx, src, wrapCast(*dst.value))); + return dst; + } + + protected: + ox::Error convert(keel::Context &ctx, SrcType &src, DstType &dst) const noexcept { + return Func(ctx, src, dst); + } + +}; + ox::Result> convert( keel::Context &ctx, ox::BufferView const&srcBuffer,