aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/content-address.hh
blob: 368a7ec48a5abc67aac61f6d71187a24519c30c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#pragma once
///@file

#include <variant>
#include "hash.hh"
#include "comparator.hh"

namespace nix {

/**
 * An enumeration of the ways we can serialize file system objects.
 */
enum struct FileIngestionMethod : uint8_t {
    /**
     * Flat-file hashing. Directly ingest the contents of a single file
     */
    Flat = false,
    /**
     * Recursive (or NAR) hashing. Serializes the file-system object in Nix
     * Archive format and ingest that
     */
    Recursive = true
};

/**
 * Somewhat obscure, used by \ref Derivation derivations and
 * `builtins.toFile` currently.
 */
struct TextHash {
    /**
     * Hash of the contents of the text/file.
     */
    Hash hash;

    GENERATE_CMP(TextHash, me->hash);
};

/**
 * For path computed by makeFixedOutputPath.
 */
struct FixedOutputHash {
    /**
     * How the file system objects are serialized
     */
    FileIngestionMethod method;
    /**
     * Hash of that serialization
     */
    Hash hash;

    std::string printMethodAlgo() const;

    GENERATE_CMP(FixedOutputHash, me->method, me->hash);
};

/**
 * We've accumulated several types of content-addressed paths over the
 * years; fixed-output derivations support multiple hash algorithms and
 * serialisation methods (flat file vs NAR). Thus, ‘ca’ has one of the
 * following forms:
 *
 * - ‘text:sha256:<sha256 hash of file contents>’: For paths
 *   computed by Store::makeTextPath() / Store::addTextToStore().
 *
 * - ‘fixed:<r?>:<ht>:<h>’: For paths computed by
 *   Store::makeFixedOutputPath() / Store::addToStore().
 */
typedef std::variant<
    TextHash,
    FixedOutputHash
> ContentAddress;

/**
 * Compute the prefix to the hash algorithm which indicates how the
 * files were ingested.
 */
std::string makeFileIngestionPrefix(const FileIngestionMethod m);

/**
 * Compute the content-addressability assertion (ValidPathInfo::ca) for
 * paths created by Store::makeFixedOutputPath() / Store::addToStore().
 */
std::string makeFixedOutputCA(FileIngestionMethod method, const Hash & hash);

std::string renderContentAddress(ContentAddress ca);

std::string renderContentAddress(std::optional<ContentAddress> ca);

ContentAddress parseContentAddress(std::string_view rawCa);

std::optional<ContentAddress> parseContentAddressOpt(std::string_view rawCaOpt);

Hash getContentAddressHash(const ContentAddress & ca);

/*
  We only have one way to hash text with references, so this is single-value
  type is only useful in std::variant.
*/
struct TextHashMethod { };
struct FixedOutputHashMethod {
  FileIngestionMethod fileIngestionMethod;
  HashType hashType;
};

/**
 * Ways of content addressing but not a complete ContentAddress.
 *
 * A ContentAddress without a Hash.
 */
typedef std::variant<
    TextHashMethod,
    FixedOutputHashMethod
  > ContentAddressMethod;

ContentAddressMethod parseContentAddressMethod(std::string_view rawCaMethod);

std::string renderContentAddressMethod(ContentAddressMethod caMethod);

}