forked from glynos/url
-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathpath.hpp
57 lines (51 loc) · 1.98 KB
/
path.hpp
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
// Copyright 2018-20 Glyn Matthews.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef SKYR_V2_FILESYSTEM_PATH_HPP
#define SKYR_V2_FILESYSTEM_PATH_HPP
#include <filesystem>
#include <tl/expected.hpp>
#include <skyr/v2/url.hpp>
#include <skyr/v2/percent_encoding/percent_decode.hpp>
namespace skyr::inline v2 {
/// \namespace filesystem
/// Contains functions to convert from filesystem path to URLs and
/// vice versa
namespace filesystem {
///
enum class path_errc {
///
invalid_path = 1,
///
percent_decoding_error,
};
/// Converts a path object to a URL with a file protocol. Handles
/// some processing, including percent encoding
/// \param path A filesystem path
/// \returns a url object or an error on failure
inline auto from_path(const std::filesystem::path &path) -> tl::expected<url, url_parse_errc> {
/// This is weird because not every library implementation has transitioned
/// from changing the return type of generic_u8string to a std::u8string between C++17 and C++20
using namespace std::string_view_literals;
constexpr auto scheme = u8"file://"sv;
auto input = std::u8string(scheme);
auto u8string = path.generic_u8string(); // Sometimes a std::string and
// sometimes a std::u8string (correct, for C++20)
input.append(std::cbegin(u8string), std::cend(u8string));
return make_url(https://github.com/input);
}
/// Converts a URL pathname to a filesystem path
/// \param input A url object
/// \returns a path object or an error on failure
inline auto to_path(const url &input) -> tl::expected<std::filesystem::path, path_errc> {
auto pathname = input.pathname();
auto decoded = skyr::percent_decode(pathname);
if (!decoded) {
return tl::make_unexpected(path_errc::percent_decoding_error);
}
return std::filesystem::path(decoded.value());
}
} // namespace filesystem
} // namespace skyr::v2
#endif // SKYR_V2_FILESYSTEM_PATH_HPP