14 const std::filesystem::path&
path,
17 return { code,
path, std::nullopt, std::move(detail) };
24 ?
static_cast<char8_t>(
value + (
u8'a' -
u8'A'))
30 std::u8string_view
left,
31 std::u8string_view
right)
noexcept
33 return left.size() ==
right.size() && std::equal(
35 [] (
char8_t a,
char8_t b)
37 return foldedAscii(a) == foldedAscii(b);
44 return error == std::errc::no_such_file_or_directory ||
45 error == std::errc::not_a_directory;
49 [[
nodiscard]] std::expected<std::vector<std::u8string>, DataError>
52 if (
input.empty() ||
input.find(
'\0') != std::string_view::npos ||
53 input.front() ==
'/' ||
input.front() ==
'\\' ||
54 input.find(
':') != std::string_view::npos)
58 "resource path must be a nonempty relative UTF-8 path"));
67 const auto end =
separator == std::string_view::npos
76 "parent traversal or a terminal dot is not a resource file"));
87 utf8.push_back(
static_cast<char8_t>(
byte));
100 "resource path must name a file"));
107 [[
nodiscard]] std::expected<std::filesystem::path, DataError>
110 std::u8string_view
wanted)
112 std::error_code
error;
119 directory,
"cannot enumerate resource directory: " +
123 std::filesystem::path
match;
124 const std::filesystem::directory_iterator end;
133 "multiple directory entries match the legacy ASCII case"));
143 "cannot finish enumerating resource directory: " +
152 "resource path component was not found"));
161 std::span<const std::filesystem::path>
roots)
167 "at least one explicit absolute resource root is required"));
173 if (
root.empty() || !
root.is_absolute() ||
174 root.native().find(std::filesystem::path::value_type{}) !=
175 std::filesystem::path::string_type::npos)
179 "resource roots must be explicit absolute paths without NUL"));
189 std::error_code
error;
195 "cannot inspect resource root: " +
error.message()));
197 if (!
error && std::filesystem::exists(status) &&
198 !std::filesystem::is_directory(status))
202 "resource root exists but is not a directory"));
205 if (std::find(result.roots_.begin(), result.roots_.end(),
normalized) ==
208 result.roots_.push_back(std::move(
normalized));
217 std::string_view relativePath)
const
227 for (
const auto&
root : roots_)
230 bool missing =
false;
238 return std::unexpected(
match.error());
251 std::error_code
error;
257 "cannot inspect resource file: " +
error.message()));
259 if (!
error && std::filesystem::is_regular_file(status))
265 catch (
const std::filesystem::filesystem_error&
error)
273 "resource file was not found in the explicit roots: " +
274 std::string(relativePath)));
std::atomic< float > left
std::atomic< float > right
std::filesystem::path directory
std::expected< std::filesystem::path, DataError > resolve(std::string_view relativePath) const
std::span< const std::filesystem::path > roots() const noexcept
static std::expected< ResourcePaths, DataError > create(std::span< const std::filesystem::path > roots)