components.hpp string_view tuple utility serif/utils/serialize/record.hpp src/include/serif/utils/serialize/physics.hpp serif::utils::serialize::NamedMember serif::utils::serialize::StructSerializer serif::utils::serialize::EnumSerializer serif serif::utils serif::utils::serialize #pragmaonce #include<string_view> #include<tuple> #include<utility> #include"serif/utils/serialize/record.hpp" namespaceserif::utils::serialize{ template<typenameOwner,typenameValueT> structNamedMember{ usingValue=ValueT; std::string_viewname; ValueOwner::*pointer; }; template<typenameOwner,typenameValue> [[nodiscard]]constexprautomember_field(std::string_viewname,ValueOwner::*pointer){ returnNamedMember<Owner, Value>{name,pointer}; } template<typenameT> structStructSerializer{ [[nodiscard]]staticNodesave(constT&value){ returnstd::apply([&](constauto&...fields){ returnobject(Serializer<T>::key,field(std::string{fields.name},value.*fields.pointer)...); },Serializer<T>::members); } [[nodiscard]]staticResult<T>load(constNode&node){ autoresult=std::apply([&](constauto&...fields){ returnread_object(node,Serializer<T>::key,[](auto&&...values){ returnT{std::forward<decltype(values)>(values)...}; },member<typenamestd::remove_cvref_t<decltype(fields)>::Value>(fields.name)...); },Serializer<T>::members); if(!result){returnresult;} ifconstexpr(requires{result->validate();}){result->validate();} ifconstexpr(requires{Serializer<T>::valid(*result);}){ if(!Serializer<T>::valid(*result)){ returnstd::unexpected(Error{"","Savedparameterslieoutsidethevaliddomainfor"+std::string{Serializer<T>::key}}); } } returnresult; } }; template<typenameT> structEnumSerializer{ [[nodiscard]]staticNodesave(Tvalue){ for(constauto&[choice,name]:Serializer<T>::choices){ if(choice==value){return{.type=std::string{Serializer<T>::key},.value=std::string{name}};} } return{.type="unsupported",.value=std::string{"Theenumerationvalueisnotregistered."}}; } [[nodiscard]]staticResult<T>load(constNode&node){ constauto*name=std::get_if<std::string>(&node.value); if(node.type==Serializer<T>::key&&name!=nullptr&&node.children.empty()){ for(constauto&[choice,spelling]:Serializer<T>::choices){ if(*name==spelling){returnchoice;} } } returnstd::unexpected(Error{"","Unknownsavedenumerationchoicefor"+std::string{Serializer<T>::key}}); } }; }