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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#if compiler(>=5.11)
@available(FoundationPredicateRegex 0.4, *)
extension PredicateExpressions {
public struct StringContainsRegex<
Subject : PredicateExpression,
Regex : PredicateExpression
> : PredicateExpression, CustomStringConvertible
where
Subject.Output : BidirectionalCollection,
Subject.Output.SubSequence == Substring,
Regex.Output : RegexComponent
{
public typealias Output = Bool
public let subject: Subject
public let regex: Regex
public init(subject: Subject, regex: Regex) {
self.subject = subject
self.regex = regex
}
public var description: String {
"StringContainsRegex(subject: \(subject), regex: \(regex))"
}
public func evaluate(_ bindings: PredicateBindings) throws -> Bool {
try subject.evaluate(bindings).contains(regex.evaluate(bindings))
}
}
@_disfavoredOverload
public static func build_contains<Subject, Regex>(_ subject: Subject, _ regex: Regex) -> StringContainsRegex<Subject, Regex> {
StringContainsRegex(subject: subject, regex: regex)
}
}
@available(FoundationPredicateRegex 0.4, *)
extension PredicateExpressions {
public struct PredicateRegex: Sendable, Codable, RegexComponent, CustomStringConvertible {
private struct _Storage: @unchecked Sendable {
let regex: Regex<AnyRegexOutput>
}
private let _storage: _Storage
public let stringRepresentation: String
public var regex: Regex<AnyRegexOutput> { _storage.regex }
public var description: String { stringRepresentation }
public init?(_ component: some RegexComponent) {
let regex = Regex<AnyRegexOutput>(component.regex)
guard let stringRep = regex._literalPattern else {
return nil
}
self._storage = _Storage(regex: regex)
self.stringRepresentation = stringRep
}
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
self.stringRepresentation = try container.decode(String.self)
self._storage = _Storage(regex: try Regex<AnyRegexOutput>(self.stringRepresentation))
}
public func encode(to encoder: any Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(stringRepresentation)
}
}
public static func build_Arg(_ component: some RegexComponent) -> Value<PredicateRegex> {
guard let supportedComponent = PredicateRegex(component) else {
fatalError("The provided regular expression is not supported by this predicate")
}
return Value(supportedComponent)
}
}
@available(FoundationPredicateRegex 0.4, *)
extension PredicateExpressions.StringContainsRegex : Sendable where Subject : Sendable, Regex : Sendable {}
@available(FoundationPredicateRegex 0.4, *)
extension PredicateExpressions.StringContainsRegex : Codable where Subject : Codable, Regex : Codable {
public func encode(to encoder: any Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(subject)
try container.encode(regex)
}
public init(from decoder: any Decoder) throws {
var container = try decoder.unkeyedContainer()
self.subject = try container.decode(Subject.self)
self.regex = try container.decode(Regex.self)
}
}
@available(FoundationPredicateRegex 0.4, *)
extension PredicateExpressions.StringContainsRegex : StandardPredicateExpression where Subject : StandardPredicateExpression, Regex : StandardPredicateExpression {}
#endif
|