aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/content-address.cc
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2020-09-17 17:15:05 +0200
committerRobert Hensing <robert@roberthensing.nl>2020-09-17 20:21:04 +0200
commitdfa547c6a81d6fb7ef3d3f69a98ebe969df42828 (patch)
treefd97a53ce56825686d725e9f8743198bb1738ef3 /src/libstore/content-address.cc
parent29c82ccc77714a74e8948ce8c531de5a8d870176 (diff)
Add ContentAddressMethod and parse/render it
Diffstat (limited to 'src/libstore/content-address.cc')
-rw-r--r--src/libstore/content-address.cc62
1 files changed, 50 insertions, 12 deletions
diff --git a/src/libstore/content-address.cc b/src/libstore/content-address.cc
index 0885c3d0e..bf56d3d77 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 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);