Serenity Operating System
at master 121 lines 3.6 kB view raw
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 14namespace AK { 15 16namespace Detail { 17template<Concepts::AnyString T, Concepts::AnyString U> 18inline constexpr bool IsHashCompatible<T, U> = true; 19} 20 21enum class CaseSensitivity { 22 CaseInsensitive, 23 CaseSensitive, 24}; 25 26enum class ReplaceMode { 27 All, 28 FirstOnly, 29}; 30 31enum class TrimMode { 32 Left, 33 Right, 34 Both 35}; 36 37enum class TrimWhitespace { 38 Yes, 39 No, 40}; 41 42enum 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}; 55AK_ENUM_BITWISE_OPERATORS(SplitBehavior); 56 57struct MaskSpan { 58 size_t start; 59 size_t length; 60 61 bool operator==(MaskSpan const& other) const 62 { 63 return start == other.start && length == other.length; 64 } 65}; 66 67namespace StringUtils { 68 69bool matches(StringView str, StringView mask, CaseSensitivity = CaseSensitivity::CaseInsensitive, Vector<MaskSpan>* match_spans = nullptr); 70template<typename T = int> 71Optional<T> convert_to_int(StringView, TrimWhitespace = TrimWhitespace::Yes); 72template<typename T = unsigned> 73Optional<T> convert_to_uint(StringView, TrimWhitespace = TrimWhitespace::Yes); 74template<typename T = unsigned> 75Optional<T> convert_to_uint_from_hex(StringView, TrimWhitespace = TrimWhitespace::Yes); 76template<typename T = unsigned> 77Optional<T> convert_to_uint_from_octal(StringView, TrimWhitespace = TrimWhitespace::Yes); 78#ifndef KERNEL 79template<typename T> 80Optional<T> convert_to_floating_point(StringView, TrimWhitespace = TrimWhitespace::Yes); 81#endif 82bool equals_ignoring_ascii_case(StringView, StringView); 83bool ends_with(StringView a, StringView b, CaseSensitivity); 84bool starts_with(StringView, StringView, CaseSensitivity); 85bool contains(StringView, StringView, CaseSensitivity); 86bool is_whitespace(StringView); 87StringView trim(StringView string, StringView characters, TrimMode mode); 88StringView trim_whitespace(StringView string, TrimMode mode); 89 90Optional<size_t> find(StringView haystack, char needle, size_t start = 0); 91Optional<size_t> find(StringView haystack, StringView needle, size_t start = 0); 92Optional<size_t> find_last(StringView haystack, char needle); 93Optional<size_t> find_last(StringView haystack, StringView needle); 94Optional<size_t> find_last_not(StringView haystack, char needle); 95Vector<size_t> find_all(StringView haystack, StringView needle); 96enum class SearchDirection { 97 Forward, 98 Backward 99}; 100Optional<size_t> find_any_of(StringView haystack, StringView needles, SearchDirection); 101 102DeprecatedString to_snakecase(StringView); 103DeprecatedString to_titlecase(StringView); 104DeprecatedString invert_case(StringView); 105 106DeprecatedString replace(StringView, StringView needle, StringView replacement, ReplaceMode); 107ErrorOr<String> replace(String const&, StringView needle, StringView replacement, ReplaceMode); 108 109size_t count(StringView, StringView needle); 110 111} 112 113} 114 115#if USING_AK_GLOBALLY 116using AK::CaseSensitivity; 117using AK::ReplaceMode; 118using AK::SplitBehavior; 119using AK::TrimMode; 120using AK::TrimWhitespace; 121#endif