@@ -270,45 +270,65 @@ struct FieldConfig<std::unordered_map<std::string, Value>> {
270270 using Type = std::unordered_map<std::string, Value>;
271271 template <typename MainClass, auto I, typename Value2>
272272 inline constexpr Type Read (Value2&& value) const {
273- if (!this ->Additional ) {
274- throw std::runtime_error (" Invalid Flags" );
275- }
276273 Type response;
277- constexpr auto fields = boost::pfr::names_as_array<MainClass>();
278- for (const auto & [name, value2] : userver::formats::common::Items (std::forward<Value2>(value))) {
279- auto it = std::find (fields.begin (), fields.end (), name);
280- if (it == fields.end ()) {
281- response.emplace (name, value2.template As <Value>());
274+ if (this ->Additional ) {
275+ constexpr auto fields = boost::pfr::names_as_array<MainClass>();
276+ for (const auto & [name, value] : userver::formats::common::Items (std::forward<Value2>(value))) {
277+ auto it = std::find (fields.begin (), fields.end (), name);
278+ if (it == fields.end ()) {
279+ response.emplace (name, value.template As <Value>());
280+ }
282281 }
282+ return response;
283+ }
284+ constexpr auto fieldName = boost::pfr::get_name<I, MainClass>();
285+ for (const auto & [name, value] : userver::formats::common::Items (value[fieldName])) {
286+ response.emplace (name, value.template As <Value>());
283287 }
284288 return response;
285289 }
286290 template <typename MainClass, auto I, typename Value2>
287291 inline constexpr std::optional<Type> TryRead (Value2&& value) const {
288- if (!this ->Additional ) {
289- throw std::runtime_error (" Invalid Flags" );
290- }
291292 Type response;
292- constexpr auto fields = boost::pfr::names_as_array<MainClass>();
293- constexpr auto name = boost::pfr::get_name<I, MainClass>();
294- for (const auto & [name2, value2] : userver::formats::common::Items (std::forward<Value2>(value))) {
295- if (std::find (fields.begin (), fields.end (), name2) == fields.end ()) {
296- auto New = parse::TryParse (value2, parse::To<Value>{});
297- if (!New) {
298- return std::nullopt ;
299- };
300- response.emplace (name, *New);
293+ if (this ->Additional ) {
294+ constexpr auto fields = boost::pfr::names_as_array<MainClass>();
295+ for (const auto & [name, value] : userver::formats::common::Items (std::forward<Value2>(value))) {
296+ if (std::find (fields.begin (), fields.end (), name) == fields.end ()) {
297+ auto New = parse::TryParse (value, parse::To<Value>{});
298+ if (!New) {
299+ return std::nullopt ;
300+ }
301+ response.emplace (name, *New);
302+ }
303+ }
304+ return response;
305+ }
306+ constexpr auto fieldName = boost::pfr::get_name<I, MainClass>();
307+ for (const auto & [name, value] : userver::formats::common::Items (value[fieldName])) {
308+ auto New = parse::TryParse (value, parse::To<Value>{});
309+ if (!New) {
310+ return std::nullopt ;
301311 }
312+ response.emplace (name, *New);
302313 }
303314 return response;
304315 }
305316 inline constexpr std::optional<std::string> Check (const Type&) const {
306317 return std::nullopt ;
307318 }
308- constexpr auto Write (const Type& value, std::string_view, const auto &, auto & builder) const {
319+ template <typename Builder>
320+ constexpr auto Write (const Type& value, std::string_view fieldName, const auto &, Builder& builder) const {
321+ if (this ->Additional ) {
322+ for (const auto & [name, value2] : value) {
323+ builder[name] = value2;
324+ };
325+ return ;
326+ };
327+ Builder newBuilder;
309328 for (const auto & [name, value2] : value) {
310- builder [name] = value2;
329+ newBuilder [name] = value2;
311330 };
331+ builder[static_cast <std::string>(fieldName)] = newBuilder.ExtractValue ();
312332 };
313333};
314334template <typename Element>
0 commit comments