import Foundation /// A `Sendable` snapshot of a copy an account is looking for, with the listings that meet it. public struct Want: Sendable, Equatable { // MARK: Properties /// The want's identifier. public let id: UUID /// What is wanted: words that must each appear in a listing's title, e.g. `Nightward #7`. public let title: String /// The lowest grade wanted, or `nil` for any. public let minGrade: Double? /// The most the account would pay, in euro cents, or `nil` for any price. public let maxPriceCents: Int? /// Whether only slabbed copies are wanted. public let slabbedOnly: Bool /// Whether new matches alert the account. public let alerts: Bool /// The listings for sale that meet the want, newest first. Wants match within the EU alone. public let matches: [Listing] /// The number of matches listed since the account last looked at its wants. public let newMatchCount: Int // MARK: Initializers public init( id: UUID, title: String, minGrade: Double?, maxPriceCents: Int?, slabbedOnly: Bool, alerts: Bool, matches: [Listing], newMatchCount: Int ) { self.id = id self.title = title self.minGrade = minGrade self.maxPriceCents = maxPriceCents self.slabbedOnly = slabbedOnly self.alerts = alerts self.matches = matches self.newMatchCount = newMatchCount } } // MARK: - Extensions public extension Want { // MARK: Computed /// The filter finding the want's matches: the title's words, within the limits set, shipping from the EU. var filter: ListingFilter { Self.filter(title: title, minGrade: minGrade, maxPriceCents: maxPriceCents, slabbedOnly: slabbedOnly) } // MARK: Methods /// The filter finding a want's matches. static func filter( title: String, minGrade: Double?, maxPriceCents: Int?, slabbedOnly: Bool ) -> ListingFilter { .init( query: title.replacingOccurrences(of: "ยท", with: " "), isSlabbed: slabbedOnly ? true : nil, gradeMin: minGrade, priceMax: maxPriceCents, shipsFrom: .eu ) } }