diff --git a/src/libstore/content-address.cc b/src/libstore/content-address.cc index fcf12a9cdfe..4b918cfcb9c 100644 --- a/src/libstore/content-address.cc +++ b/src/libstore/content-address.cc @@ -35,7 +35,7 @@ std::string renderLegacyContentAddress(LegacyContentAddress ca) { + makeFileIngestionPrefix(fsh.method) + fsh.hash.to_string(Base32, true); }, - [](IPFSHash ih) { + [](IPFSHash ih) { // FIXME do Base-32 for consistency return "ipfs:" + ih.to_string(); } @@ -86,7 +86,7 @@ LegacyContentAddress parseLegacyContentAddress(std::string_view rawCa) { .hash = Hash::parseNonSRIUnprefixed(rest, std::move(hashType)), }; } else if (prefix == "ipfs") { - auto hash = IPFSHash::from_string(rest); + auto hash = IPFSHash::from_string(rest); if (hash.hash.type != htSHA256) throw Error("This IPFS hash should have type SHA-256: %s", hash.to_string()); return hash; @@ -134,10 +134,7 @@ std::string renderContentAddress(ContentAddress ca) .hash = fsh.hash }}); }, - [](IPFSInfo fsh) { - throw Error("ipfs info not handled"); - }, - [&](IPFSHash ih) { + [&](IPFSHashWithOptValue ih) { result += "ipfs:"; result += ih.to_string(); }, @@ -214,7 +211,9 @@ ContentAddress parseContentAddress(std::string_view rawCa) refs, }; } else if (tag == "ipfs") { - info = IPFSHash::from_string(rest); + info = IPFSHashWithOptValue { + IPFSHash::from_string(rest) + }; } else throw UsageError("content address tag \"%s\" is unrecognized. Recogonized tages are \"text\", \"fixed\", or \"ipfs\"", tag); @@ -241,10 +240,10 @@ void to_json(nlohmann::json& j, const LegacyContentAddress & ca) { { "hash", foh.hash.to_string(Base32, false) }, }; }, - [](IPFSHash ih) { + [](IPFSHash ih) { return nlohmann::json { { "type", "ipfs" }, - { "hash", ih.to_string() }, + { "hash", ih }, }; }, }, ca); @@ -270,97 +269,96 @@ void from_json(const nlohmann::json& j, LegacyContentAddress & ca) { throw Error("invalid type: %s", type); } -// f01781114 is the cid prefix for a base16 cbor sha1. This hash -// stores the ContentAddress information. +// Needed until https://github.com/nlohmann/json/pull/2117 + +void to_json(nlohmann::json& j, const std::optional & c) { + if (!c) + j = nullptr; + else + to_json(j, *c); +} -void to_json(nlohmann::json& j, const ContentAddress & ca) +void from_json(const nlohmann::json& j, std::optional & c) { + if (j.is_null()) { + c = std::nullopt; + } else { + // Dummy value to set tag bit. + c = TextHash { .hash = Hash { htSHA256 } }; + from_json(j, *c); + } +} + +template +void to_json(nlohmann::json& j, const ContentAddressT & c) { - if (std::holds_alternative(ca.info)) { - auto info = std::get(ca.info); - - // FIXME: ipfs sort order is weird, it always puts type before - // references, so we rename it to qtype so it always comes - // before references - j = nlohmann::json { - { "qtype", "ipfs" }, - { "name", ca.name }, - { "references", info.references }, - { "cid", nlohmann::json { - { "/", (IPFSHash { .hash = info.hash }).to_string() } - } } - }; - } else throw Error("cannot convert to json"); + j = nlohmann::json { + { "name", c.name }, + { "info", c.info }, + }; } -void from_json(const nlohmann::json& j, ContentAddress & ca) +template +void from_json(const nlohmann::json& j, ContentAddressT & c) { - std::string_view type = j.at("qtype").get(); - if (type == "ipfs") { - auto cid = j.at("cid").at("/").get(); - ca = ContentAddress { - .name = j.at("name"), - .info = IPFSInfo { - IPFSHash::from_string(cid).hash, - j.at("references").get>(), - }, - }; - } else - throw Error("invalid type: %s", type); + c.name = j.at("name"); + from_json(j.at("info"), c.info); } -void to_json(nlohmann::json& j, const PathReferences & references) +template