/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef META_EXT_SERIALIZATION_SERIALISER_H #define META_EXT_SERIALIZATION_SERIALISER_H #include #include #include META_BEGIN_NAMESPACE() template struct NamedValue { NamedValue(BASE_NS::string_view name, Type& v) : name(name), value(v) {} BASE_NS::string_view name; Type& value; }; template NamedValue(BASE_NS::string_view name, const Type& v) -> NamedValue; struct AutoSerializeTag {}; inline AutoSerializeTag AutoSerialize() { return {}; } class SerializerBase { public: operator ReturnError() const { return state_; } explicit operator bool() const { return state_; } SerializerBase& SetState(ReturnError s) { state_ = s; return *this; } protected: ReturnError state_ { GenericError::SUCCESS }; }; class ExportSerializer : public SerializerBase { public: ExportSerializer(IExportContext& context) : context_(context) {} template ExportSerializer& operator&(const NamedValue& nv) { if (state_) { if constexpr (is_enum_v>) { using UT = BASE_NS::underlying_type_t>; SetState(context_.ExportValue(nv.name, static_cast(nv.value))); } else { SetState(context_.ExportValue(nv.name, nv.value)); } } return *this; } template ExportSerializer& operator&(const NamedValue>& nv) { if (auto p = interface_pointer_cast(nv.value.GetProperty())) { *this& NamedValue(nv.name, p); } else { SetState(GenericError::FAIL); } return *this; } template ExportSerializer& operator&(const NamedValue>& nv) { if (auto p = interface_pointer_cast(nv.value.GetProperty())) { *this& NamedValue(nv.name, p); } else { SetState(GenericError::FAIL); } return *this; } template ExportSerializer& operator&(const NamedValue>& nv) { if (state_) { SetState(context_.ExportWeakPtr(nv.name, interface_pointer_cast(nv.value))); } return *this; } ExportSerializer& operator&(AutoSerializeTag) { if (state_) { SetState(context_.AutoExport()); } return *this; } private: IExportContext& context_; }; class ImportSerializer : public SerializerBase { public: ImportSerializer(IImportContext& context) : context_(context) {} template ImportSerializer& operator&(const NamedValue& nv) { if (state_) { if constexpr (is_enum_v>) { using UT = BASE_NS::underlying_type_t>; UT v {}; if (SetState(context_.ImportValue(nv.name, v))) { nv.value = static_cast(v); } } else { SetState(context_.ImportValue(nv.name, nv.value)); } } return *this; } template ImportSerializer& operator&(const NamedValue>& nv) { if (auto p = interface_pointer_cast(nv.value.GetProperty())) { *this& NamedValue(nv.name, p); } else { SetState(GenericError::FAIL); } return *this; } template ImportSerializer& operator&(const NamedValue>& nv) { if (auto p = interface_pointer_cast(nv.value.GetProperty())) { *this& NamedValue(nv.name, p); } else { SetState(GenericError::FAIL); } return *this; } template ImportSerializer& operator&(const NamedValue>& nv) { if (state_) { IObject::WeakPtr p; SetState(context_.ImportWeakPtr(nv.name, p)); if (state_) { nv.value = interface_pointer_cast>(p); } } return *this; } ImportSerializer& operator&(AutoSerializeTag) { if (state_) { SetState(context_.AutoImport()); } return *this; } private: IImportContext& context_; }; template class Serializer { Serializer(Context& c); }; template<> class Serializer : public ImportSerializer { public: Serializer(IImportContext& c) : ImportSerializer(c) {} }; template<> class Serializer : public ExportSerializer { public: Serializer(IExportContext& c) : ExportSerializer(c) {} }; META_END_NAMESPACE() #endif