-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPrice.swift
91 lines (74 loc) · 2.5 KB
/
Price.swift
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
//
// Price.swift
// SwiftBeanCountModel
//
// Created by Steffen Kötte on 2018-05-13.
// Copyright © 2018 Steffen Kötte. All rights reserved.
//
import Foundation
/// Errors a price can throw
public enum PriceError: Error {
/// the price is listed in its own commodity
case sameCommodity(String)
}
/// Price of a commodity in another commodity on a given date
public struct Price {
/// Date of the Price
public let date: Date
/// `CommoditySymbol` of the Price
public let commoditySymbol: CommoditySymbol
/// `Amount` of the Price
public let amount: Amount
/// MetaData of the Price
public let metaData: [String: String]
/// Create a price
///
/// - Parameters:
/// - date: date of the price
/// - commodity: commodity
/// - amount: amount
/// - Throws: PriceError.sameCommodity if the commodity and the commodity of the amount are the same
public init(date: Date, commoditySymbol: CommoditySymbol, amount: Amount, metaData: [String: String] = [:]) throws {
self.date = date
self.commoditySymbol = commoditySymbol
self.amount = amount
self.metaData = metaData
guard commoditySymbol != amount.commoditySymbol else {
throw PriceError.sameCommodity(commoditySymbol)
}
}
}
extension Price: CustomStringConvertible {
private static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter
}()
/// Returns the price string for the ledger.
public var description: String {
var result = "\(Self.dateFormatter.string(from: date)) price \(commoditySymbol) \(amount)"
if !metaData.isEmpty {
result += "\n\(metaData.map { " \($0): \"\($1)\"" }.joined(separator: "\n"))"
}
return result
}
}
extension PriceError: LocalizedError {
public var errorDescription: String? {
switch self {
case let .sameCommodity(error):
return "Invalid Price, using same commodity: \(error)"
}
}
}
extension Price: Equatable {
/// Retuns if the two prices are equal
///
/// - Parameters:
/// - lhs: price 1
/// - rhs: price 2
/// - Returns: true if the prices are equal, false otherwise
public static func == (lhs: Price, rhs: Price) -> Bool {
lhs.date == rhs.date && lhs.commoditySymbol == rhs.commoditySymbol && lhs.amount == rhs.amount && lhs.metaData == rhs.metaData
}
}