fs/Path: add WithSuffix()

This commit is contained in:
Max Kellermann 2022-07-14 15:59:55 +02:00
parent 458084d79b
commit fe3ab7b937
5 changed files with 65 additions and 0 deletions

View File

@ -48,6 +48,21 @@ AllocatedPath::FromUTF8Throw(std::string_view path_utf8)
#endif
}
void
AllocatedPath::SetSuffix(const_pointer new_suffix) noexcept
{
assert(new_suffix != nullptr);
assert(*new_suffix == '.');
const auto end = value.end();
auto begin = end;
if (auto old = GetSuffix())
begin = std::next(value.begin(), old - value.data());
value.replace(begin, end, new_suffix);
}
void
AllocatedPath::ChopSeparators() noexcept
{

View File

@ -304,6 +304,27 @@ public:
return Path{*this}.GetSuffix();
}
/**
* Replace the suffix of this path (or append the suffix if
* there is none currently).
*
* @param new_suffix the new filename suffix (must start with
* a dot)
*/
void SetSuffix(const_pointer new_suffix) noexcept;
/**
* Return a copy of this path but with the given suffix
* (replacing the existing suffix if there is one).
*
* @param new_suffix the new filename suffix (must start with
* a dot)
*/
[[gnu::pure]]
AllocatedPath WithSuffix(const_pointer new_suffix) const noexcept {
return Path{*this}.WithSuffix(new_suffix);
}
/**
* Returns the filename extension (excluding the dot) or
* nullptr if the path does not have one.

View File

@ -173,6 +173,16 @@ public:
[[gnu::pure]]
const_pointer GetSuffix() const noexcept;
/**
* Return a copy of this path but with the given suffix
* (replacing the existing suffix if there is one).
*
* @param new_suffix the new filename suffix (must start with
* a dot)
*/
[[gnu::pure]]
AllocatedPath WithSuffix(const_pointer new_suffix) const noexcept;
/**
* Returns the filename extension (excluding the dot) or
* nullptr if the path does not have one.

View File

@ -26,6 +26,14 @@ Path::GetDirectoryName() const noexcept
return AllocatedPath::FromFS(PathTraitsFS::GetParent(c_str()));
}
AllocatedPath
Path::WithSuffix(const_pointer new_suffix) const noexcept
{
AllocatedPath result{*this};
result.SetSuffix(new_suffix);
return result;
}
AllocatedPath
operator/(Path a, Path b) noexcept
{

View File

@ -96,3 +96,14 @@ TEST(Path, Suffix)
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("/foo/.bar.abc")).GetSuffix(), ".abc");
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("/foo/.bar.abc.def")).GetSuffix(), ".def");
}
TEST(Path, WithSuffix)
{
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("foo")).WithSuffix(".abc").c_str(), "foo.abc");
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("/foo/bar")).WithSuffix(".abc").c_str(), "/foo/bar.abc");
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("/foo.xyz/bar")).WithSuffix(".abc").c_str(), "/foo.xyz/bar.abc");
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("/foo.abc/bar.def")).WithSuffix(".xyz").c_str(), "/foo.abc/bar.xyz");
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("/foo.abc/bar.def.ghi")).WithSuffix(".xyz").c_str(), "/foo.abc/bar.def.xyz");
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("/foo/.bar.abc")).WithSuffix(".xyz").c_str(), "/foo/.bar.xyz");
EXPECT_STREQ(Path::FromFS(PATH_LITERAL("/foo/.bar.abc.def")).WithSuffix(".xyz").c_str(), "/foo/.bar.abc.xyz");
}