78 lines
2.2 KiB
Swift
78 lines
2.2 KiB
Swift
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
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|