diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 19932f80..dd3d8e50 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -43,6 +43,7 @@ EA33624728931B050071C351 /* Initable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA33624628931B050071C351 /* Initable.swift */; }; EA3C3B4C2894823E000CA526 /* AnyProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3B4B2894823E000CA526 /* AnyProxy.swift */; }; EA4DB18528CA967F00103EE3 /* SelectorGroupHandlerBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB18428CA967F00103EE3 /* SelectorGroupHandlerBase.swift */; }; + EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */; }; EA84F6B128B94A2500D67ABC /* CodableColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F6B028B94A2500D67ABC /* CodableColor.swift */; }; EA89200228AECF2A006B9984 /* UIButton+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89200128AECF2A006B9984 /* UIButton+Publisher.swift */; }; EA89200428AECF4B006B9984 /* UITextField+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89200328AECF4B006B9984 /* UITextField+Publisher.swift */; }; @@ -139,6 +140,7 @@ EA33624628931B050071C351 /* Initable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Initable.swift; sourceTree = ""; }; EA3C3B4B2894823E000CA526 /* AnyProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyProxy.swift; sourceTree = ""; }; EA4DB18428CA967F00103EE3 /* SelectorGroupHandlerBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroupHandlerBase.swift; sourceTree = ""; }; + EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyEquatable.swift; sourceTree = ""; }; EA84F6B028B94A2500D67ABC /* CodableColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableColor.swift; sourceTree = ""; }; EA89200128AECF2A006B9984 /* UIButton+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+Publisher.swift"; sourceTree = ""; }; EA89200328AECF4B006B9984 /* UITextField+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextField+Publisher.swift"; sourceTree = ""; }; @@ -317,6 +319,7 @@ isa = PBXGroup; children = ( EA3361C4289030FC0071C351 /* Accessable.swift */, + EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */, EA3361AC288B26190071C351 /* DataTrackable.swift */, EA3361A9288B25E40071C351 /* Disabling.swift */, EAF7F0A1289AFB3900B287F5 /* Errorable.swift */, @@ -599,6 +602,7 @@ EA3362402892EF6C0071C351 /* Label.swift in Sources */, EAF7F0B3289B1ADC00B287F5 /* LabelAttributeAction.swift in Sources */, EA33622E2891EA3C0071C351 /* DispatchQueue+Once.swift in Sources */, + EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */, EAF7F0AF289B144C00B287F5 /* LabelAttributeUnderline.swift in Sources */, EA3361C5289030FC0071C351 /* Accessable.swift in Sources */, EA33622C2891E73B0071C351 /* FontProtocol.swift in Sources */, diff --git a/VDS/Components/Label/Attributes/LabelAttributeAction.swift b/VDS/Components/Label/Attributes/LabelAttributeAction.swift index 42cf634d..a7a96c3e 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeAction.swift +++ b/VDS/Components/Label/Attributes/LabelAttributeAction.swift @@ -15,6 +15,18 @@ public protocol LabelAttributeActionable: LabelAttributeModel { public struct LabelAttributeActionModel: LabelAttributeActionable { + public static func == (lhs: LabelAttributeActionModel, rhs: LabelAttributeActionModel) -> Bool { + lhs.isEqual(rhs) + } + + public func isEqual(_ equatable: AnyEquatable) -> Bool { + guard let equatable = equatable as? Self else { + return false + } + + return id == equatable.id && range == equatable.range + } + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/VDS/Components/Label/Attributes/LabelAttributeColor.swift b/VDS/Components/Label/Attributes/LabelAttributeColor.swift index d95b570b..0313cd43 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeColor.swift +++ b/VDS/Components/Label/Attributes/LabelAttributeColor.swift @@ -9,6 +9,13 @@ import Foundation import UIKit public struct LabelAttributeColor: LabelAttributeModel { + public func isEqual(_ equatable: AnyEquatable) -> Bool { + guard let equatable = equatable as? Self else { + return false + } + + return id == equatable.id && range == equatable.range && color == equatable.color + } //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/VDS/Components/Label/Attributes/LabelAttributeFont.swift b/VDS/Components/Label/Attributes/LabelAttributeFont.swift index 80a65fbc..5f0eeefb 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeFont.swift +++ b/VDS/Components/Label/Attributes/LabelAttributeFont.swift @@ -8,7 +8,18 @@ import Foundation import UIKit -public struct LabelAttributeFont: LabelAttributeModel { +public struct LabelAttributeFont: LabelAttributeModel { + public func isEqual(_ equatable: AnyEquatable) -> Bool { + guard let equatable = equatable as? Self else { + return false + } + + return id == equatable.id + && range == equatable.range + && color == equatable.color + && style == equatable.style + } + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/VDS/Components/Label/Attributes/LabelAttributeModel.swift b/VDS/Components/Label/Attributes/LabelAttributeModel.swift index 1de2130e..c3209f68 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeModel.swift +++ b/VDS/Components/Label/Attributes/LabelAttributeModel.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -public protocol LabelAttributeModel: Identifiable where ID == UUID { +public protocol LabelAttributeModel: AnyEquatable, Withable, Equatable, Identifiable where ID == UUID { var location: Int { get set } var length: Int { get set } func setAttribute(on attributedString: NSMutableAttributedString) @@ -18,4 +18,9 @@ extension LabelAttributeModel { public var range: NSRange { NSRange(location: location, length: length) } + + public static func == (lhs: any LabelAttributeModel, rhs: any LabelAttributeModel) -> Bool { + lhs.isEqual(rhs) + } + } diff --git a/VDS/Components/Label/Attributes/LabelAttributeStrikeThrough.swift b/VDS/Components/Label/Attributes/LabelAttributeStrikeThrough.swift index 1955c81e..7c44120e 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeStrikeThrough.swift +++ b/VDS/Components/Label/Attributes/LabelAttributeStrikeThrough.swift @@ -8,7 +8,16 @@ import Foundation import UIKit -public struct LabelAttributeStrikeThrough: LabelAttributeModel { +public struct LabelAttributeStrikeThrough: LabelAttributeModel { + public func isEqual(_ equatable: AnyEquatable) -> Bool { + guard let equatable = equatable as? Self else { + return false + } + + return id == equatable.id + && range == equatable.range + } + public var id = UUID() public var location: Int public var length: Int diff --git a/VDS/Components/Label/Attributes/LabelAttributeUnderline.swift b/VDS/Components/Label/Attributes/LabelAttributeUnderline.swift index aa24a491..c2ce4a1e 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeUnderline.swift +++ b/VDS/Components/Label/Attributes/LabelAttributeUnderline.swift @@ -9,6 +9,19 @@ import Foundation import UIKit public struct LabelAttributeUnderline: LabelAttributeModel { + + public func isEqual(_ equatable: AnyEquatable) -> Bool { + guard let equatable = equatable as? Self else { + return false + } + + return id == equatable.id + && range == equatable.range + && color == equatable.color + && style == equatable.style + && pattern == equatable.pattern + } + public var id = UUID() public var location: Int public var length: Int diff --git a/VDS/Components/Label/LabelModel.swift b/VDS/Components/Label/LabelModel.swift index aa506db3..04d19e04 100644 --- a/VDS/Components/Label/LabelModel.swift +++ b/VDS/Components/Label/LabelModel.swift @@ -13,7 +13,26 @@ public protocol LabelModel: Modelable, Labelable { var attributes: [any LabelAttributeModel]? { get set } } -public struct DefaultLabelModel: LabelModel { +public struct DefaultLabelModel: LabelModel, AnyEquatable, Equatable { + public static func == (lhs: DefaultLabelModel, rhs: DefaultLabelModel) -> Bool { + lhs.isEqual(rhs) + } + + public func isEqual(_ equatable: AnyEquatable) -> Bool { + guard let equatable = equatable as? Self else { + return false + } + + return id == equatable.id + && attributes == equatable.attributes + && text == equatable.text + && surface == equatable.surface + && typograpicalStyle == equatable.typograpicalStyle + && textPosition == equatable.textPosition + && surface == equatable.surface + && disabled == equatable.disabled + } + public var id = UUID() public var text: String? public var attributes: [any LabelAttributeModel]? diff --git a/VDS/Protocols/AnyEquatable.swift b/VDS/Protocols/AnyEquatable.swift new file mode 100644 index 00000000..2e1708ac --- /dev/null +++ b/VDS/Protocols/AnyEquatable.swift @@ -0,0 +1,52 @@ +// +// AnyEquatable.swift +// VDS +// +// Created by Matt Bruce on 9/15/22. +// + +import Foundation + +public protocol AnyEquatable { + func isEqual(_ equatable: AnyEquatable) -> Bool +} + +func == (lhs: AnyEquatable?, rhs: AnyEquatable?) -> Bool { + switch (lhs, rhs) { + case (.some(let lhs), .some(let rhs)): + return lhs.isEqual(rhs) + case (.none, .none): + return true + default: + return false + } +} + +func != (lhs: AnyEquatable?, rhs: AnyEquatable?) -> Bool { + return !(lhs == rhs) +} + +func == (lhs: [AnyEquatable]?, rhs: [AnyEquatable]?) -> Bool { + switch (lhs, rhs) { + case (.some(let lhs), .some(let rhs)): + return lhs == rhs + case (.none, .none): + return true + default: + return false + } +} + +func != (lhs: [AnyEquatable]?, rhs: [AnyEquatable]?) -> Bool { + return !(lhs == rhs) +} + +func == (lhs: [AnyEquatable], rhs: [AnyEquatable]) -> Bool { + return lhs.elementsEqual(rhs, by: { (lhsElement, rhsElement) -> Bool in + return lhsElement == rhsElement + }) +} + +func != (lhs: [AnyEquatable], rhs: [AnyEquatable]) -> Bool { + return !(lhs == rhs) +}