Files
ccn/Packages/Persistence/Sources/Public/Models/Listing.swift
T

160 lines
4.6 KiB
Swift

import Foundation
/// A `Sendable` snapshot of one copy for sale, with the shop selling it.
public struct Listing: Sendable, Equatable {
// MARK: Properties
/// The listing's URL slug.
public let slug: String
/// The shop selling the copy.
public let shop: Shop
/// The listing's title, e.g. `Nightward #1`.
public let title: String
/// The series the copy belongs to, e.g. `Nightward (2019 series)`.
public let seriesTitle: String
/// The issue or volume, e.g. `#1, cover A`.
public let issueLabel: String
/// The publisher's name.
public let publisher: String
/// The cover year.
public let year: Int
/// The format token, e.g. `single-issues`.
public let format: String
/// The printing in a few words, e.g. `1st print`.
public let printing: String
/// The printing in full, e.g. `First printing, direct edition`.
public let printingDetail: String
/// Whether the copy is a first printing.
public let isFirstPrint: Bool
/// The company that graded and slabbed the copy, or `nil` for a raw copy.
public let grader: String?
/// The numeric grade, or `nil` for formats that are not graded.
public let grade: Double?
/// The condition as the seller states it, e.g. `NM` or `Like new`.
public let condition: String
/// The grader's certificate number, or `nil` for a raw copy.
public let certNumber: String?
/// The page quality, or `nil` when not stated.
public let pageQuality: String?
/// Why the issue is a key, or `nil` when it is not one.
public let keyNotes: String?
/// The seller's notes on the copy.
public let sellerNotes: String
/// The asking price, in euro cents.
public let priceCents: Int
/// The shipping cost to the Netherlands, in euro cents.
public let shippingCents: Int
/// Whether the seller takes offers on the copy.
public let acceptsOffers: Bool
/// The placeholder cover shown until listings carry photos.
public let cover: Cover
/// When the copy was listed.
public let listedAt: Date
// MARK: Initializers
public init(
slug: String,
shop: Shop,
title: String,
seriesTitle: String,
issueLabel: String,
publisher: String,
year: Int,
format: String,
printing: String,
printingDetail: String,
isFirstPrint: Bool,
grader: String?,
grade: Double?,
condition: String,
certNumber: String?,
pageQuality: String?,
keyNotes: String?,
sellerNotes: String,
priceCents: Int,
shippingCents: Int,
acceptsOffers: Bool,
cover: Cover,
listedAt: Date
) {
self.slug = slug
self.shop = shop
self.title = title
self.seriesTitle = seriesTitle
self.issueLabel = issueLabel
self.publisher = publisher
self.year = year
self.format = format
self.printing = printing
self.printingDetail = printingDetail
self.isFirstPrint = isFirstPrint
self.grader = grader
self.grade = grade
self.condition = condition
self.certNumber = certNumber
self.pageQuality = pageQuality
self.keyNotes = keyNotes
self.sellerNotes = sellerNotes
self.priceCents = priceCents
self.shippingCents = shippingCents
self.acceptsOffers = acceptsOffers
self.cover = cover
self.listedAt = listedAt
}
}
// MARK: - Extensions
public extension Listing {
// MARK: Computed
/// Whether the issue is a key.
var isKey: Bool {
keyNotes != nil
}
/// Whether the copy is graded and slabbed by a grading company.
var isSlabbed: Bool {
grader != nil
}
}
// MARK: - Structs
public extension Listing {
/// A placeholder cover: lettering on a toned ground.
struct Cover: Sendable, Equatable {
// MARK: Properties
/// The tone token naming the cover's colours, e.g. `navy`.
public let tone: String
/// The title lettering, one line per newline.
public let title: String
/// The publisher's imprint line.
public let imprint: String
/// The issue number or volume marker.
public let number: String
// MARK: Initializers
public init(
tone: String,
title: String,
imprint: String,
number: String
) {
self.tone = tone
self.title = title
self.imprint = imprint
self.number = number
}
}
}