Specialize std::optional<StorePath> so this is backwards compatible

While I am cautious to break parametricity, I think it's OK in this
cases---we're not about to try to do some crazy polymorphic protocol
anytime soon.
This commit is contained in:
John Ericson 2020-08-07 17:05:14 +00:00
parent 8b175f58d1
commit 47644e49ca
2 changed files with 21 additions and 0 deletions

View file

@ -70,6 +70,20 @@ void write(const Store & store, Sink & out, const StorePath & storePath)
out << store.printStorePath(storePath); out << store.printStorePath(storePath);
} }
template<>
std::optional<StorePath> read(const Store & store, Source & from, Phantom<std::optional<StorePath>> _)
{
auto s = readString(from);
return s == "" ? std::optional<StorePath> {} : store.parseStorePath(s);
}
template<>
void write(const Store & store, Sink & out, const std::optional<StorePath> & storePathOpt)
{
out << (storePathOpt ? store.printStorePath(*storePathOpt) : "");
}
} }

View file

@ -90,6 +90,13 @@ std::optional<T> read(const Store & store, Source & from, Phantom<std::optional<
template<typename T> template<typename T>
void write(const Store & store, Sink & out, const std::optional<T> & optVal); void write(const Store & store, Sink & out, const std::optional<T> & optVal);
/* Specialization which uses and empty string for the empty case, taking
advantage of the fact StorePaths always serialize to a non-empty string.
This is done primarily for backwards compatability, so that StorePath <=
std::optional<StorePath>, where <= is the compatability partial order.
*/
template<>
void write(const Store & store, Sink & out, const std::optional<StorePath> & optVal);
template<typename T> template<typename T>
std::map<std::string, T> read(const Store & store, Source & from, Phantom<std::map<std::string, T>> _) std::map<std::string, T> read(const Store & store, Source & from, Phantom<std::map<std::string, T>> _)