#pragma once #include "resource.h" #include #include #include #include namespace NJson2Udf { using namespace NKikimr; using namespace NUdf; using namespace NYql; using namespace NDom; template class TAsJsonNode: public TBoxedValue { public: TAsJsonNode(TSourcePosition pos) : Pos_(pos) { } static TStringRef Name(); static bool DeclareSignature( const TStringRef& name, TType* userType, IFunctionTypeInfoBuilder& builder, bool typesOnly) { Y_UNUSED(userType); if (name != Name()) { return false; } auto optionalSourceType = builder.Optional()->Item().Build(); auto resourceType = builder.Resource(JSON_NODE_RESOURCE_NAME); builder.Args() ->Add(optionalSourceType) .Done() .Returns(resourceType); if (!typesOnly) { builder.Implementation(new TAsJsonNode(builder.GetSourcePosition())); } builder.IsStrict(); return true; } private: const size_t MaxParseErrors = 10; static TUnboxedValue Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder); TUnboxedValue Run( const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { Y_UNUSED(valueBuilder); try { if (!args[0].HasValue()) { return MakeEntity(); } return Interpret(args[0], valueBuilder); } catch (const std::exception& e) { UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data()); } } TSourcePosition Pos_; }; template <> TStringRef TAsJsonNode::Name() { return TStringRef::Of("Utf8AsJsonNode"); } template <> TUnboxedValue TAsJsonNode::Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder) { return MakeString(sourceValue.AsStringRef(), valueBuilder); } template <> TStringRef TAsJsonNode::Name() { return TStringRef::Of("DoubleAsJsonNode"); } template <> TUnboxedValue TAsJsonNode::Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder) { Y_UNUSED(valueBuilder); return MakeDouble(sourceValue.Get()); } template <> TStringRef TAsJsonNode::Name() { return TStringRef::Of("BoolAsJsonNode"); } template <> TUnboxedValue TAsJsonNode::Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder) { Y_UNUSED(valueBuilder); return MakeBool(sourceValue.Get()); } template <> TStringRef TAsJsonNode::Name() { return TStringRef::Of("JsonAsJsonNode"); } template <> TUnboxedValue TAsJsonNode::Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder) { return TryParseJsonDom(sourceValue.AsStringRef(), valueBuilder); } }