archive.hpp cstddef filesystem fstream map optional string string_view vector serif/utils/serialize/record.hpp src/include/serif/utils/serialize/serialize.hpp src/lib/serif/utils/serialize/archive.cpp src/lib/serif/utils/serialize/format.hpp serif::utils::serialize::WriteOptions serif::utils::serialize::ReadOptions serif::utils::serialize::Entry serif::utils::serialize::Pack serif::utils::serialize::Reader serif serif::utils serif::utils::serialize #pragmaonce #include<cstddef> #include<filesystem> #include<fstream> #include<map> #include<optional> #include<string> #include<string_view> #include<vector> #include"serif/utils/serialize/record.hpp" namespaceserif::utils::serialize{ enumclassFormat{binary,text}; enumclassVersionTolerance{same_major,exact,any}; structWriteOptions{ Formatformat{Format::binary}; std::stringauthor; std::stringcomment; std::map<std::string,std::string>metadata; }; structReadOptions{ VersionToleranceversion_tolerance{VersionTolerance::same_major}; std::uint64_tmaximum_index_bytes{64*1024*1024}; std::uint64_tmaximum_payload_bytes{1024ULL*1024*1024}; std::uint64_tmaximum_entries{1000000}; std::uint64_tmaximum_depth{128}; }; structEntry{ std::stringpath; std::stringtype; std::uint32_tversion{1}; std::uint32_tkind{0}; std::uint64_tcount{0}; std::uint64_toffset{0}; std::uint64_tbytes{0}; std::stringchecksum; }; structPack{ Noderoot{.type="pack"}; std::optional<Error>error; }; template<typenameT> [[nodiscard]]Fieldnamed(std::stringname,constT&value){returnfield(std::move(name),value);} voidadd_component(Pack&pack,Fieldcomponent); template<typename...T> [[nodiscard]]Packpack(constT&...values){ Packresult; std::size_tindex=0; ([&]{ ifconstexpr(std::same_as<std::remove_cvref_t<T>,Field>){ add_component(result,values); }elseifconstexpr(requires{Serializer<std::remove_cvref_t<T>>::key;}){ add_component(result,field(std::string{Serializer<std::remove_cvref_t<T>>::key},values)); }else{ add_component(result,field("component_"+std::to_string(index),values)); } ++index; }(),...); returnresult; } [[nodiscard]]Result<void>write(conststd::filesystem::path&path,constPack&contents,constWriteOptions&options={}); classReader{ public: [[nodiscard]]staticResult<Reader>open(conststd::filesystem::path&path,ReadOptionsoptions={}); [[nodiscard]]conststd::vector<Entry>&ledger()constnoexcept{returnm_entries;} [[nodiscard]]conststd::string&serif_version()constnoexcept{returnm_version;} [[nodiscard]]Formatformat()constnoexcept{returnm_format;} [[nodiscard]]boolcontains(std::string_viewpath)const; [[nodiscard]]Result<Node>node(std::string_viewpath)const; [[nodiscard]]Result<Node>metadata()const{returnnode("provenance");} template<typenameT> [[nodiscard]]Result<T>read(std::string_viewpath={})const{ if(path.empty()){ ifconstexpr(requires{Serializer<T>::key;}){ path=Serializer<T>::key; }else{ returnstd::unexpected(Error{"","Specifythearchivepathforatypewithoutadefaultcomponentname."}); } } autosaved=node(path); if(!saved){ returnstd::unexpected(saved.error()); } autovalue=decode<T>(*saved); if(!value){ value.error().path=std::string{path}+(value.error().path.empty()?"":"/"+value.error().path); } returnvalue; } [[nodiscard]]Result<void>validate()const; private: mutablestd::ifstreamm_file; std::vector<Entry>m_entries; std::stringm_version; Formatm_format{Format::binary}; ReadOptionsm_options; }; }