1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef META_EXT_SERIALIZATION_SERIALISER_H
17 #define META_EXT_SERIALIZATION_SERIALISER_H
18 
19 #include <meta/interface/property/property.h>
20 #include <meta/interface/serialization/intf_export_context.h>
21 #include <meta/interface/serialization/intf_import_context.h>
22 
23 META_BEGIN_NAMESPACE()
24 
25 template<typename Type>
26 struct NamedValue {
NamedValueNamedValue27     NamedValue(BASE_NS::string_view name, Type& v) : name(name), value(v) {}
28 
29     BASE_NS::string_view name;
30     Type& value;
31 };
32 
33 template<typename Type>
34 NamedValue(BASE_NS::string_view name, const Type& v) -> NamedValue<const Type>;
35 
36 struct AutoSerializeTag {};
AutoSerialize()37 inline AutoSerializeTag AutoSerialize()
38 {
39     return {};
40 }
41 
42 class SerializerBase {
43 public:
ReturnError()44     operator ReturnError() const
45     {
46         return state_;
47     }
48 
49     explicit operator bool() const
50     {
51         return state_;
52     }
53 
SetState(ReturnError s)54     SerializerBase& SetState(ReturnError s)
55     {
56         state_ = s;
57         return *this;
58     }
59 
60 protected:
61     ReturnError state_ { GenericError::SUCCESS };
62 };
63 
64 class ExportSerializer : public SerializerBase {
65 public:
ExportSerializer(IExportContext & context)66     ExportSerializer(IExportContext& context) : context_(context) {}
67 
68     template<typename Type>
69     ExportSerializer& operator&(const NamedValue<Type>& nv)
70     {
71         if (state_) {
72             if constexpr (is_enum_v<BASE_NS::remove_const_t<Type>>) {
73                 using UT = BASE_NS::underlying_type_t<BASE_NS::remove_const_t<Type>>;
74                 SetState(context_.ExportValue(nv.name, static_cast<UT>(nv.value)));
75             } else {
76                 SetState(context_.ExportValue(nv.name, nv.value));
77             }
78         }
79         return *this;
80     }
81 
82     template<typename Type>
83     ExportSerializer& operator&(const NamedValue<Property<Type>>& nv)
84     {
85         if (auto p = interface_pointer_cast<IObject>(nv.value.GetProperty())) {
86             *this& NamedValue(nv.name, p);
87         } else {
88             SetState(GenericError::FAIL);
89         }
90         return *this;
91     }
92 
93     template<typename Type>
94     ExportSerializer& operator&(const NamedValue<const Property<Type>>& nv)
95     {
96         if (auto p = interface_pointer_cast<IObject>(nv.value.GetProperty())) {
97             *this& NamedValue(nv.name, p);
98         } else {
99             SetState(GenericError::FAIL);
100         }
101         return *this;
102     }
103 
104     template<typename Type>
105     ExportSerializer& operator&(const NamedValue<const BASE_NS::weak_ptr<Type>>& nv)
106     {
107         if (state_) {
108             SetState(context_.ExportWeakPtr(nv.name, interface_pointer_cast<IObject>(nv.value)));
109         }
110         return *this;
111     }
112 
113     ExportSerializer& operator&(AutoSerializeTag)
114     {
115         if (state_) {
116             SetState(context_.AutoExport());
117         }
118         return *this;
119     }
120 
121 private:
122     IExportContext& context_;
123 };
124 
125 class ImportSerializer : public SerializerBase {
126 public:
ImportSerializer(IImportContext & context)127     ImportSerializer(IImportContext& context) : context_(context) {}
128 
129     template<typename Type>
130     ImportSerializer& operator&(const NamedValue<Type>& nv)
131     {
132         if (state_) {
133             if constexpr (is_enum_v<BASE_NS::remove_const_t<Type>>) {
134                 using UT = BASE_NS::underlying_type_t<BASE_NS::remove_const_t<Type>>;
135                 UT v {};
136                 if (SetState(context_.ImportValue(nv.name, v))) {
137                     nv.value = static_cast<Type>(v);
138                 }
139             } else {
140                 SetState(context_.ImportValue(nv.name, nv.value));
141             }
142         }
143         return *this;
144     }
145 
146     template<typename Type>
147     ImportSerializer& operator&(const NamedValue<Property<Type>>& nv)
148     {
149         if (auto p = interface_pointer_cast<IObject>(nv.value.GetProperty())) {
150             *this& NamedValue(nv.name, p);
151         } else {
152             SetState(GenericError::FAIL);
153         }
154         return *this;
155     }
156 
157     template<typename Type>
158     ImportSerializer& operator&(const NamedValue<const Property<Type>>& nv)
159     {
160         if (auto p = interface_pointer_cast<IObject>(nv.value.GetProperty())) {
161             *this& NamedValue(nv.name, p);
162         } else {
163             SetState(GenericError::FAIL);
164         }
165         return *this;
166     }
167 
168     template<typename Type>
169     ImportSerializer& operator&(const NamedValue<BASE_NS::weak_ptr<Type>>& nv)
170     {
171         if (state_) {
172             IObject::WeakPtr p;
173             SetState(context_.ImportWeakPtr(nv.name, p));
174             if (state_) {
175                 nv.value = interface_pointer_cast<BASE_NS::remove_const_t<Type>>(p);
176             }
177         }
178         return *this;
179     }
180 
181     ImportSerializer& operator&(AutoSerializeTag)
182     {
183         if (state_) {
184             SetState(context_.AutoImport());
185         }
186         return *this;
187     }
188 
189 private:
190     IImportContext& context_;
191 };
192 
193 template<typename Context>
194 class Serializer {
195     Serializer(Context& c);
196 };
197 
198 template<>
199 class Serializer<IImportContext> : public ImportSerializer {
200 public:
Serializer(IImportContext & c)201     Serializer(IImportContext& c) : ImportSerializer(c) {}
202 };
203 
204 template<>
205 class Serializer<IExportContext> : public ExportSerializer {
206 public:
Serializer(IExportContext & c)207     Serializer(IExportContext& c) : ExportSerializer(c) {}
208 };
209 
210 META_END_NAMESPACE()
211 
212 #endif
213