diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-09-22 11:31:33 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-09-22 11:31:33 +0200 |
commit | 92ac8df0ec0b81d3655229f488201634e99088f8 (patch) | |
tree | eacea83f51cacc05897b95f2a4dfb6a587f15fd4 /src/libstore/content-address.cc | |
parent | e7f1109f06444d5facbfe9839e33a6183e2e4780 (diff) | |
parent | ca30abb3fb36440e5a13161c39647189036fc18f (diff) |
Merge branch 'add-ca-to-store' of https://github.com/hercules-ci/nix
Diffstat (limited to 'src/libstore/content-address.cc')
-rw-r--r-- | src/libstore/content-address.cc | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/src/libstore/content-address.cc b/src/libstore/content-address.cc index 0885c3d0e..74215c545 100644 --- a/src/libstore/content-address.cc +++ b/src/libstore/content-address.cc @@ -37,48 +37,86 @@ std::string renderContentAddress(ContentAddress ca) { }, ca); } -ContentAddress parseContentAddress(std::string_view rawCa) { - auto rest = rawCa; +std::string renderContentAddressMethod(ContentAddressMethod cam) { + return std::visit(overloaded { + [](TextHashMethod &th) { + return std::string{"text:"} + printHashType(htSHA256); + }, + [](FixedOutputHashMethod &fshm) { + return "fixed:" + makeFileIngestionPrefix(fshm.fileIngestionMethod) + printHashType(fshm.hashType); + } + }, cam); +} + +/* + Parses content address strings up to the hash. + */ +static ContentAddressMethod parseContentAddressMethodPrefix(std::string_view & rest) { + std::string_view wholeInput { rest }; std::string_view prefix; { auto optPrefix = splitPrefixTo(rest, ':'); if (!optPrefix) - throw UsageError("not a content address because it is not in the form '<prefix>:<rest>': %s", rawCa); + throw UsageError("not a content address because it is not in the form '<prefix>:<rest>': %s", wholeInput); prefix = *optPrefix; } auto parseHashType_ = [&](){ auto hashTypeRaw = splitPrefixTo(rest, ':'); if (!hashTypeRaw) - throw UsageError("content address hash must be in form '<algo>:<hash>', but found: %s", rawCa); + throw UsageError("content address hash must be in form '<algo>:<hash>', but found: %s", wholeInput); HashType hashType = parseHashType(*hashTypeRaw); return std::move(hashType); }; // Switch on prefix if (prefix == "text") { - // No parsing of the method, "text" only support flat. + // No parsing of the ingestion method, "text" only support flat. HashType hashType = parseHashType_(); if (hashType != htSHA256) throw Error("text content address hash should use %s, but instead uses %s", printHashType(htSHA256), printHashType(hashType)); - return TextHash { - .hash = Hash::parseNonSRIUnprefixed(rest, std::move(hashType)), - }; + return TextHashMethod {}; } else if (prefix == "fixed") { // Parse method auto method = FileIngestionMethod::Flat; if (splitPrefix(rest, "r:")) method = FileIngestionMethod::Recursive; HashType hashType = parseHashType_(); - return FixedOutputHash { - .method = method, - .hash = Hash::parseNonSRIUnprefixed(rest, std::move(hashType)), + return FixedOutputHashMethod { + .fileIngestionMethod = method, + .hashType = std::move(hashType), }; } else throw UsageError("content address prefix '%s' is unrecognized. Recogonized prefixes are 'text' or 'fixed'", prefix); -}; +} + +ContentAddress parseContentAddress(std::string_view rawCa) { + auto rest = rawCa; + + ContentAddressMethod caMethod = parseContentAddressMethodPrefix(rest); + + return std::visit( + overloaded { + [&](TextHashMethod thm) { + return ContentAddress(TextHash { + .hash = Hash::parseNonSRIUnprefixed(rest, htSHA256) + }); + }, + [&](FixedOutputHashMethod fohMethod) { + return ContentAddress(FixedOutputHash { + .method = fohMethod.fileIngestionMethod, + .hash = Hash::parseNonSRIUnprefixed(rest, std::move(fohMethod.hashType)), + }); + }, + }, caMethod); +} + +ContentAddressMethod parseContentAddressMethod(std::string_view caMethod) { + std::string_view asPrefix {std::string{caMethod} + ":"}; + return parseContentAddressMethodPrefix(asPrefix); +} std::optional<ContentAddress> parseContentAddressOpt(std::string_view rawCaOpt) { return rawCaOpt == "" ? std::optional<ContentAddress> {} : parseContentAddress(rawCaOpt); |