mirror of
https://github.com/facebook/sapling.git
synced 2024-10-05 14:28:17 +03:00
config: allow unordered_set in config
Summary: A future diff will create a ConfigSetting<std::unordered_set<T>>. Reviewed By: kmancini Differential Revision: D45162159 fbshipit-source-id: a67b3b94d708ae694041753d7dffaa6f0ff974de
This commit is contained in:
parent
2c8e74370b
commit
f23137cda1
@ -32,11 +32,10 @@ bool isValidAbsolutePath(string_view path) {
|
||||
// reject relative paths.
|
||||
return path.starts_with(detail::kRootStr);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Expected<AbsolutePath, string> FieldConverter<AbsolutePath>::fromString(
|
||||
std::string expandConvData(
|
||||
std::string_view value,
|
||||
const std::map<string, string>& convData) const {
|
||||
const std::map<std::string, std::string>& convData) {
|
||||
auto sString = std::string{value};
|
||||
for (auto varName : kEnvVars) {
|
||||
auto it = convData.find(std::string{varName});
|
||||
@ -53,6 +52,14 @@ Expected<AbsolutePath, string> FieldConverter<AbsolutePath>::fromString(
|
||||
}
|
||||
}
|
||||
}
|
||||
return sString;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Expected<AbsolutePath, string> FieldConverter<AbsolutePath>::fromString(
|
||||
std::string_view value,
|
||||
const std::map<string, string>& convData) const {
|
||||
auto sString = expandConvData(value, convData);
|
||||
|
||||
if (!isValidAbsolutePath(sString)) {
|
||||
return folly::makeUnexpected<string>(
|
||||
@ -70,6 +77,20 @@ Expected<AbsolutePath, string> FieldConverter<AbsolutePath>::fromString(
|
||||
}
|
||||
}
|
||||
|
||||
Expected<RelativePath, string> FieldConverter<RelativePath>::fromString(
|
||||
std::string_view value,
|
||||
const std::map<string, string>& convData) const {
|
||||
auto sString = expandConvData(value, convData);
|
||||
try {
|
||||
return RelativePath{sString};
|
||||
} catch (const std::exception& ex) {
|
||||
return folly::makeUnexpected<string>(fmt::format(
|
||||
"Failed to convert value '{}' to a relative path, error : {}",
|
||||
value,
|
||||
ex.what()));
|
||||
}
|
||||
}
|
||||
|
||||
Expected<string, string> FieldConverter<string>::fromString(
|
||||
std::string_view value,
|
||||
const std::map<string, string>& /* unused */) const {
|
||||
|
@ -51,6 +51,24 @@ class FieldConverter<AbsolutePath> {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class FieldConverter<RelativePath> {
|
||||
public:
|
||||
/**
|
||||
* Convert the passed string piece to a repository RelativePath.
|
||||
* @param convData is a map of conversion data that can be used by conversions
|
||||
* method (for example $HOME value.)
|
||||
* @return the converted RelativePath or an error message.
|
||||
*/
|
||||
folly::Expected<RelativePath, std::string> fromString(
|
||||
std::string_view value,
|
||||
const std::map<std::string, std::string>& convData) const;
|
||||
|
||||
std::string toDebugString(const RelativePath& path) const {
|
||||
return path.value();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class FieldConverter<std::string> {
|
||||
public:
|
||||
@ -135,6 +153,36 @@ class FieldConverter<std::vector<T>> {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class FieldConverter<std::unordered_set<T>> {
|
||||
public:
|
||||
folly::Expected<std::unordered_set<T>, std::string> fromString(
|
||||
std::string_view value,
|
||||
const std::map<std::string, std::string>& convData) const {
|
||||
// TODO(xavierd): directly construct the set without the vector middle-step
|
||||
return FieldConverter<std::vector<T>>{}
|
||||
.fromString(value, convData)
|
||||
.then([](std::vector<T> vec) {
|
||||
return std::unordered_set<T>{
|
||||
std::make_move_iterator(vec.begin()),
|
||||
std::make_move_iterator(vec.end())};
|
||||
});
|
||||
}
|
||||
|
||||
std::string toDebugString(const std::unordered_set<T>& value) const {
|
||||
std::vector<std::string> serializedElements;
|
||||
serializedElements.resize(value.size());
|
||||
std::transform(
|
||||
value.begin(),
|
||||
value.end(),
|
||||
serializedElements.begin(),
|
||||
[](auto& element) {
|
||||
return FieldConverter<T>{}.toDebugString(element);
|
||||
});
|
||||
return fmt::to_string(fmt::join(serializedElements, ", "));
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* FieldConverter implementation for integers, floating point, and bool types
|
||||
*/
|
||||
|
@ -432,3 +432,17 @@ TEST_F(ConfigSettingTest, setArrayOptional) {
|
||||
checkSet(
|
||||
setting, std::vector<std::optional<std::string>>{"foo"}, "[\"foo\"]");
|
||||
}
|
||||
|
||||
TEST_F(ConfigSettingTest, setRelativePath) {
|
||||
ConfigSetting<RelativePath> setting{"test:value", RelativePath{}, nullptr};
|
||||
checkSet(setting, RelativePath{"foo/bar"}, "foo/bar");
|
||||
}
|
||||
|
||||
TEST_F(ConfigSettingTest, setUnorderedSet) {
|
||||
ConfigSetting<std::unordered_set<std::string>> setting{
|
||||
"test:value", std::unordered_set<std::string>{}, nullptr};
|
||||
checkSet(
|
||||
setting,
|
||||
std::unordered_set<std::string>{"1", "2", "3", "4"},
|
||||
"[\"1\", \"2\", \"3\", \"4\"]");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user