diff --git a/MVMCore/MVMCore/ActionHandling/ActionActionsModel.swift b/MVMCore/MVMCore/ActionHandling/ActionActionsModel.swift index ba7fa10..b36ae29 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionActionsModel.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionActionsModel.swift @@ -64,6 +64,14 @@ public struct ActionActionsModel: ActionModelProtocol { try container.encodeIfPresent(extraParameters, forKey: .extraParameters) try container.encodeIfPresent(analyticsData, forKey: .analyticsData) } + + public func isEqual(to model: any ModelProtocol) -> Bool { + guard let model = model as? Self else { return false } + return actions.areEqual(to: model.actions) + && concurrent == model.concurrent + && extraParameters == model.extraParameters + && analyticsData == model.analyticsData + } } extension ActionActionsModel: CustomDebugStringConvertible { diff --git a/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift b/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift index ac7ee02..2da0e0c 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift @@ -115,6 +115,23 @@ public struct ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, try container.encodeIfPresent(analyticsData, forKey: .analyticsData) try container.encodeIfPresent(fallbackResponse, forKey: .fallbackResponse) } + + public func isEqual(to model: any ModelProtocol) -> Bool { + guard let model = model as? Self else { return false } + return pageType == model.pageType + && baseURL == model.baseURL + && appContext == model.appContext + && requestURL == model.requestURL + && modules == model.modules + && presentationStyle == model.presentationStyle + && tabBarIndex == model.tabBarIndex + && background == model.background + && clientParameters == model.clientParameters + && customTimeoutTime == model.customTimeoutTime + && extraParameters == model.extraParameters + && analyticsData == model.analyticsData + && fallbackResponse == model.fallbackResponse + } } extension ActionOpenPageModel: CustomDebugStringConvertible { diff --git a/MVMCore/MVMCore/Models/ActionType/ActionModelProtocol.swift b/MVMCore/MVMCore/Models/ActionType/ActionModelProtocol.swift index 24f5011..d6cb1c7 100644 --- a/MVMCore/MVMCore/Models/ActionType/ActionModelProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/ActionModelProtocol.swift @@ -37,4 +37,11 @@ public extension ActionModelProtocol { var debugDescription: String { return actionType } + + func isEqual(to model: any ModelProtocol) -> Bool { + guard let model = model as? Self else { return false } + return model.actionType == actionType + && model.extraParameters == extraParameters + && model.analyticsData == analyticsData + } } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModel.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModel.swift index 9e63c27..3fae967 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModel.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModel.swift @@ -8,7 +8,8 @@ import Foundation -public class ClientParameterModel: Codable { +public class ClientParameterModel: Equatable, Codable { + var timeout: Double? var list: [ClientParameterModelProtocol] @@ -33,4 +34,9 @@ public class ClientParameterModel: Codable { try container.encodeIfPresent(timeout, forKey: .timeout) try container.encodeModels(list, forKey: .list) } + + public static func == (lhs: ClientParameterModel, rhs: ClientParameterModel) -> Bool { + return lhs.list.areEqual(to: rhs.list) + && lhs.timeout == rhs.timeout + } } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift index bbde12c..8ba8950 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift @@ -30,4 +30,9 @@ public extension ClientParameterModelProtocol { static var categoryName: String { return "\(ClientParameterModelProtocol.self)" } + + func isEqual(to model: any ModelProtocol) -> Bool { + guard let model = model as? Self else { return false } + return type == model.type + } } diff --git a/MVMCore/MVMCore/Models/Model/ModelProtocol.swift b/MVMCore/MVMCore/Models/Model/ModelProtocol.swift index 960f593..302b91d 100644 --- a/MVMCore/MVMCore/Models/Model/ModelProtocol.swift +++ b/MVMCore/MVMCore/Models/Model/ModelProtocol.swift @@ -30,6 +30,9 @@ public protocol ModelProtocol: Codable { /// Convenience function to encode model using an unkeyed container. func encode(unkeyedContainer: inout UnkeyedEncodingContainer) throws + + /// Deep checks if the curent model is equal to another model. Defaults to false unless implemented otherwise. + func isEqual(to model: ModelProtocol) -> Bool } extension ModelProtocol { @@ -49,4 +52,47 @@ extension ModelProtocol { public func encode(unkeyedContainer: inout UnkeyedEncodingContainer) throws { try unkeyedContainer.encode(self) } + + public func isEqual(to model: ModelProtocol) -> Bool { + return false + } +} + +public extension Optional { + + /// Checks if the curent model is equal to another model. + func isEqual(to model: ModelProtocol?) -> Bool { + guard let self = self as? ModelProtocol else { + return model == nil + } + guard let model = model else { + return false + } + return self.isEqual(to: model) + } +} + + +public extension Array /*where Element == ModelProtocol*/ { + /// Checks if all the models in the given array match another given array of models. + func areEqual(to models: [ModelProtocol]) -> Bool { + guard count == models.count, let self = self as? [ModelProtocol] else { return false } + return models.indices.allSatisfy { index in + self[index].isEqual(to: models[index]) + } + } +} + +public extension Optional where Wrapped: Collection { + + func areEqual(to models: [ModelProtocol]?) -> Bool { + guard let self = self as? [ModelProtocol] else { + return models == nil + } + guard let models = models else { + return false + } + return self.areEqual(to: models) + } + }