//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2022-2023 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 // //===----------------------------------------------------------------------===// @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions { public struct OptionalFlatMap< LHS : PredicateExpression, Wrapped, RHS : PredicateExpression, Result > : PredicateExpression where LHS.Output == Optional { public typealias Output = Optional public let wrapped: LHS public let transform: RHS public let variable: Variable public init(_ wrapped: LHS, _ builder: (Variable) -> RHS) where RHS.Output == Result { self.wrapped = wrapped self.variable = Variable() self.transform = builder(variable) } public init(_ wrapped: LHS, _ builder: (Variable) -> RHS) where RHS.Output == Optional { self.wrapped = wrapped self.variable = Variable() self.transform = builder(variable) } public func evaluate(_ bindings: PredicateBindings) throws -> Output { var mutableBindings = bindings return try wrapped.evaluate(bindings).flatMap { inner in mutableBindings[variable] = inner return try transform.evaluate(mutableBindings) as! Result? } } } public static func build_flatMap(_ wrapped: LHS, _ builder: (Variable) -> RHS) -> OptionalFlatMap where RHS.Output == Result { OptionalFlatMap(wrapped, builder) } public static func build_flatMap(_ wrapped: LHS, _ builder: (Variable) -> RHS) -> OptionalFlatMap where RHS.Output == Optional { OptionalFlatMap(wrapped, builder) } public struct NilCoalesce< LHS : PredicateExpression, RHS : PredicateExpression > : PredicateExpression where LHS.Output == Optional { public typealias Output = RHS.Output public let lhs: LHS public let rhs: RHS public init(lhs: LHS, rhs: RHS) { self.lhs = lhs self.rhs = rhs } public func evaluate(_ bindings: PredicateBindings) throws -> Output { try lhs.evaluate(bindings) ?? rhs.evaluate(bindings) } } public static func build_NilCoalesce(lhs: LHS, rhs: RHS) -> NilCoalesce { NilCoalesce(lhs: lhs, rhs: rhs) } public struct ForcedUnwrap< Inner : PredicateExpression, Wrapped > : PredicateExpression where Inner.Output == Optional { public typealias Output = Wrapped public let inner: Inner public init(_ inner: Inner) { self.inner = inner } public func evaluate(_ bindings: PredicateBindings) throws -> Wrapped { let input = try inner.evaluate(bindings) if let result = input { return result } throw PredicateError(.forceUnwrapFailure("Found nil when unwrapping value of type '\(type(of: input))'")) } } public static func build_ForcedUnwrap(_ inner: Inner) -> ForcedUnwrap where Inner.Output == Optional { ForcedUnwrap(inner) } } @available(FoundationPreview 0.3, *) extension PredicateExpressions.OptionalFlatMap : CustomStringConvertible { public var description: String { "OptionalFlatMap(wrapped: \(wrapped), variable: \(variable), transform: \(transform))" } } @available(FoundationPreview 0.3, *) extension PredicateExpressions.NilCoalesce : CustomStringConvertible { public var description: String { "NilCoalesce(lhs: \(lhs), rhs: \(rhs))" } } @available(FoundationPreview 0.3, *) extension PredicateExpressions.ForcedUnwrap : CustomStringConvertible { public var description: String { "ForcedUnwrap(inner: \(inner))" } } @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.OptionalFlatMap : StandardPredicateExpression where LHS : StandardPredicateExpression, RHS : StandardPredicateExpression {} @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.NilCoalesce : StandardPredicateExpression where LHS : StandardPredicateExpression, RHS : StandardPredicateExpression {} @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.ForcedUnwrap : StandardPredicateExpression where Inner : StandardPredicateExpression {} @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.OptionalFlatMap : Codable where LHS : Codable, RHS : Codable { public func encode(to encoder: Encoder) throws { var container = encoder.unkeyedContainer() try container.encode(wrapped) try container.encode(transform) try container.encode(variable) } public init(from decoder: Decoder) throws { var container = try decoder.unkeyedContainer() wrapped = try container.decode(LHS.self) transform = try container.decode(RHS.self) variable = try container.decode(PredicateExpressions.Variable.self) } } @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.NilCoalesce : Codable where LHS : Codable, RHS : Codable { public func encode(to encoder: Encoder) throws { var container = encoder.unkeyedContainer() try container.encode(lhs) try container.encode(rhs) } public init(from decoder: Decoder) throws { var container = try decoder.unkeyedContainer() lhs = try container.decode(LHS.self) rhs = try container.decode(RHS.self) } } @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.ForcedUnwrap : Codable where Inner : Codable { public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try container.encode(inner) } public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() inner = try container.decode(Inner.self) } } @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.OptionalFlatMap : Sendable where LHS : Sendable, RHS : Sendable {} @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.NilCoalesce : Sendable where LHS : Sendable, RHS : Sendable {} @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions.ForcedUnwrap : Sendable where Inner : Sendable {} @available(macOS 14, iOS 17, tvOS 17, watchOS 10, *) extension PredicateExpressions { public struct NilLiteral : StandardPredicateExpression, Codable, Sendable { public typealias Output = Optional public init() {} public func evaluate(_ bindings: PredicateBindings) throws -> Output { nil } public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try container.encodeNil() } public init(from decoder: Decoder) throws {} } public static func build_NilLiteral() -> NilLiteral { NilLiteral() } }