userver: userver/utils/text_light.hpp Source File
Loading...
Searching...
No Matches
text_light.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/text_light.hpp
4/// @brief Text utilities that do not use locales
5/// @ingroup userver_universal
6
7#include <string>
8#include <string_view>
9#include <vector>
10
11USERVER_NAMESPACE_BEGIN
12
13/// @brief Text utilities
14namespace utils::text {
15
16/// Return trimmed copy of string.
17[[nodiscard]]
18std::string Trim(const std::string& str);
19
20/// Trim string in-place.
21[[nodiscard]]
22std::string Trim(std::string&& str);
23
24/// Return trimmed view of a string.
25[[nodiscard]]
26std::string_view TrimView(std::string_view str);
27
28enum class SplitFlags {
29 kNone = 0,
30 kCompressAdjacentSeparators = 1 << 0,
31};
32
33/// Split string by separators
34///
35/// @snippet utils/text_light_test.cpp SplitMultiple
36std::vector<std::string> Split(
37 std::string_view str,
38 std::string_view separators,
39 SplitFlags split_flags = SplitFlags::kCompressAdjacentSeparators
40);
41
42/// Split string by separators and return a non-owning container of chunks.
43///
44/// @warning Initial `str` should outlive the result of the function
45///
46/// @snippet utils/text_light_test.cpp SplitStringViewMultiple
47std::vector<std::string_view> SplitIntoStringViewVector(std::string_view str, std::string_view separators);
48
49/// Join string
50std::string Join(const std::vector<std::string>& strs, std::string_view sep);
51
52/// Return number formatted
53std::string Format(double value, int ndigits);
54
55/// Return true if `hay` starts with `needle`, false otherwise.
56constexpr bool StartsWith(std::string_view hay, std::string_view needle) noexcept {
57 return hay.substr(0, needle.size()) == needle;
58}
59
60/// Return true if `hay` ends with `needle`, false otherwise.
61constexpr bool EndsWith(std::string_view hay, std::string_view needle) noexcept {
62 return hay.size() >= needle.size() && hay.substr(hay.size() - needle.size()) == needle;
63}
64
65/// Case insensitive (ASCII only) variant of StartsWith()
66bool ICaseStartsWith(std::string_view hay, std::string_view needle) noexcept;
67
68/// Case insensitive (ASCII only) variant of EndsWith()
69bool ICaseEndsWith(std::string_view hay, std::string_view needle) noexcept;
70
71/// Removes double quotes from front and back of string.
72///
73/// Examples:
74/// @code
75/// RemoveQuotes("\"test\"") // returns "test"
76/// RemoveQuotes("\"test") // returns "\"test"
77/// RemoveQuotes("'test'") // returns "'test'"
78/// RemoveQuotes("\"\"test\"\"") // returns "\"test\""
79/// @endcode
80std::string RemoveQuotes(std::string_view str);
81
82/// Checks whether the character is an ASCII character
83bool IsAscii(char ch) noexcept;
84
85/// Checks whether the character is a whitespace character in C locale
86bool IsAsciiSpace(char ch) noexcept;
87
88/// Checks if text contains only ASCII characters
89bool IsAscii(std::string_view text) noexcept;
90
91/// @brief UTF8 text utilities
92namespace utf8 {
93
94/// Returns the length in bytes of the UTF-8 code point by the first byte.
95unsigned CodePointLengthByFirstByte(unsigned char c) noexcept;
96
97/// `bytes` must not be a nullptr, `length` must not be 0.
98bool IsWellFormedCodePoint(const unsigned char* bytes, std::size_t length) noexcept;
99
100/// `bytes` must not be a nullptr, `length` must not be 0.
101bool IsValid(const unsigned char* bytes, std::size_t length) noexcept;
102
103/// returns number of utf-8 code points, text must be in utf-8 encoding
104/// @throws std::runtime_error if not a valid UTF8 text
105std::size_t GetCodePointsCount(std::string_view text);
106
107/// Removes the longest (possible empty) suffix of `str` which is a proper
108/// prefix of some utf-8 multibyte character. If `str` is not in utf-8 it may
109/// remove some suffix of length up to 3.
110void TrimTruncatedEnding(std::string& str);
111
112/// @see void TrimTruncatedEnding(std::string& str)
113/// @warning this **does not** change the original string
114void TrimViewTruncatedEnding(std::string_view& view);
115
116/// Returns position in `text` where utf-8 code point with position `pos` starts
117/// OR `text.length()` if `text` contains less than or equal to `pos` points
118/// @warning this **does not** check if `text` is valid utf-8 text
119std::size_t GetTextPosByCodePointPos(std::string_view text, std::size_t pos) noexcept;
120
121/// Removes the first `count` utf-8 code points from `text`
122/// @warning this **does not** check if `text` is valid utf-8 text
123void RemovePrefix(std::string& text, std::size_t count) noexcept;
124
125/// @see void RemovePrefix(std::string& text, std::size_t count)
126/// @warning this **does not** change the original string
127void RemoveViewPrefix(std::string_view& text, std::size_t count) noexcept;
128
129/// Takes the first `count` utf-8 code points from `text`
130/// @warning this **does not** check if `text` is valid utf-8 text
131void TakePrefix(std::string& text, std::size_t count) noexcept;
132
133/// @see void TakePrefix(std::string& text, std::size_t count)
134/// @warning this **does not** change the original string
135void TakeViewPrefix(std::string_view& text, std::size_t count) noexcept;
136
137} // namespace utf8
138
139/// Checks if text is in utf-8 encoding
140bool IsUtf8(std::string_view text) noexcept;
141
142/// Checks text on matching to the following conditions:
143/// 1. text is in utf-8 encoding
144/// 2. text does not contain any of control ascii characters
145/// 3. if flag ascii is true than text contains only ascii characters
146bool IsPrintable(std::string_view text, bool ascii_only = true) noexcept;
147
148/// Checks if there are no embedded null ('\0') characters in text
149bool IsCString(std::string_view text) noexcept;
150
151/// convert CamelCase to snake_case(underscore)
152std::string CamelCaseToSnake(std::string_view camel);
153
154/// convert snake_case or SCREAMING_SNAKE_CASE to CamelCase
155std::string SnakeCaseToCamel(std::string_view snake);
156
157} // namespace utils::text
158
159USERVER_NAMESPACE_END