Coverage Report

Created: 2026-05-16 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/AK/StringUtils.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3
 * Copyright (c) 2020, Fei Wu <f.eiwu@yahoo.com>
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#pragma once
9
10
#include <AK/Concepts.h>
11
#include <AK/EnumBits.h>
12
#include <AK/Forward.h>
13
14
namespace AK {
15
16
namespace Detail {
17
template<Concepts::AnyString T, Concepts::AnyString U>
18
inline constexpr bool IsHashCompatible<T, U> = true;
19
}
20
21
enum class CaseSensitivity {
22
    CaseInsensitive,
23
    CaseSensitive,
24
};
25
26
enum class ReplaceMode {
27
    All,
28
    FirstOnly,
29
};
30
31
enum class TrimMode {
32
    Left,
33
    Right,
34
    Both
35
};
36
37
enum class TrimWhitespace {
38
    Yes,
39
    No,
40
};
41
42
enum class SplitBehavior : unsigned {
43
    // Neither keep empty substrings nor keep the trailing separator.
44
    // This is the default behavior if unspecified.
45
    Nothing = 0,
46
47
    // If two separators follow each other without any characters
48
    // in between, keep a "" in the resulting vector. (or only the
49
    // separator if KeepTrailingSeparator is used)
50
    KeepEmpty = 1,
51
52
    // Do not strip off the separator at the end of the string.
53
    KeepTrailingSeparator = 2,
54
};
55
AK_ENUM_BITWISE_OPERATORS(SplitBehavior);
56
57
enum class TrailingCodePointTransformation : u8 {
58
    // Default behaviour; Puts the first typographic letter unit of each word, if lowercase, in titlecase; the other characters in lowercase.
59
    Lowercase,
60
    // Puts the first typographic letter unit of each word, if lowercase, in titlecase; other characters are unaffected. (https://drafts.csswg.org/css-text/#valdef-text-transform-capitalize)
61
    PreserveExisting,
62
};
63
64
struct MaskSpan {
65
    size_t start;
66
    size_t length;
67
68
    bool operator==(MaskSpan const& other) const
69
0
    {
70
0
        return start == other.start && length == other.length;
71
0
    }
72
};
73
74
namespace StringUtils {
75
76
#ifndef KERNEL
77
bool matches(StringView str, StringView mask, CaseSensitivity = CaseSensitivity::CaseInsensitive, Vector<MaskSpan>* match_spans = nullptr);
78
#endif
79
80
template<typename T = int>
81
Optional<T> convert_to_int(StringView, TrimWhitespace = TrimWhitespace::Yes);
82
template<typename T = unsigned>
83
Optional<T> convert_to_uint(StringView, TrimWhitespace = TrimWhitespace::Yes);
84
template<typename T = unsigned>
85
Optional<T> convert_to_uint_from_hex(StringView, TrimWhitespace = TrimWhitespace::Yes);
86
template<typename T = unsigned>
87
Optional<T> convert_to_uint_from_octal(StringView, TrimWhitespace = TrimWhitespace::Yes);
88
#ifndef KERNEL
89
template<typename T>
90
Optional<T> convert_to_floating_point(StringView, TrimWhitespace = TrimWhitespace::Yes);
91
#endif
92
bool equals_ignoring_ascii_case(StringView, StringView);
93
bool ends_with(StringView a, StringView b, CaseSensitivity);
94
bool starts_with(StringView, StringView, CaseSensitivity);
95
bool contains(StringView, StringView, CaseSensitivity);
96
bool is_whitespace(StringView);
97
StringView trim(StringView string, StringView characters, TrimMode mode);
98
StringView trim_whitespace(StringView string, TrimMode mode);
99
100
Optional<size_t> find(StringView haystack, char needle, size_t start = 0);
101
Optional<size_t> find(StringView haystack, StringView needle, size_t start = 0);
102
Optional<size_t> find_last(StringView haystack, char needle);
103
Optional<size_t> find_last(StringView haystack, StringView needle);
104
Optional<size_t> find_last_not(StringView haystack, char needle);
105
106
#ifndef KERNEL
107
Vector<size_t> find_all(StringView haystack, StringView needle);
108
#endif
109
110
enum class SearchDirection {
111
    Forward,
112
    Backward
113
};
114
Optional<size_t> find_any_of(StringView haystack, StringView needles, SearchDirection);
115
116
ByteString to_snakecase(StringView);
117
ByteString to_titlecase(StringView);
118
ByteString invert_case(StringView);
119
120
ByteString replace(StringView, StringView needle, StringView replacement, ReplaceMode);
121
ErrorOr<String> replace(String const&, StringView needle, StringView replacement, ReplaceMode);
122
123
size_t count(StringView, StringView needle);
124
size_t count(StringView, char needle);
125
126
}
127
128
}
129
130
#if USING_AK_GLOBALLY
131
using AK::CaseSensitivity;
132
using AK::ReplaceMode;
133
using AK::SplitBehavior;
134
using AK::TrailingCodePointTransformation;
135
using AK::TrimMode;
136
using AK::TrimWhitespace;
137
#endif