mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			72 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			72 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Swift
		
	
| // Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
 | |
| 
 | |
| import Foundation
 | |
| import SessionUtilitiesKit
 | |
| 
 | |
| internal protocol ValidatableResponse {
 | |
|     associatedtype ValidationData
 | |
|     associatedtype ValidationResponse
 | |
|     
 | |
|     /// This valid controls the number of successful responses for a response to be considered "valid", a
 | |
|     /// positive number indicates an exact number of responses required whereas a negative number indicates
 | |
|     /// a dividing factor, eg.
 | |
|     /// 2 = Two nodes need to have returned success responses
 | |
|     /// -2 = 50% of the nodes need to have returned success responses
 | |
|     /// -4 = 25% of the nodes need to have returned success responses
 | |
|     static var requiredSuccessfulResponses: Int { get }
 | |
|     
 | |
|     @discardableResult static func validated(
 | |
|         map validResultMap: [String: ValidationResponse],
 | |
|         totalResponseCount: Int
 | |
|     ) throws -> [String: ValidationResponse]
 | |
|     
 | |
|     @discardableResult func validResultMap(
 | |
|         swarmPublicKey: String,
 | |
|         validationData: ValidationData,
 | |
|         using dependencies: Dependencies
 | |
|     ) throws -> [String: ValidationResponse]
 | |
| }
 | |
| 
 | |
| // MARK: - Convenience
 | |
| 
 | |
| internal extension ValidatableResponse {
 | |
|     @discardableResult static func validated(
 | |
|         map validResultMap: [String: ValidationResponse],
 | |
|         totalResponseCount: Int
 | |
|     ) throws -> [String: ValidationResponse] {
 | |
|         let numSuccessResponses: Int = validResultMap.count
 | |
|         let successPercentage: CGFloat = (CGFloat(numSuccessResponses) / CGFloat(totalResponseCount))
 | |
|         
 | |
|         guard
 | |
|             (   // Positive value is an exact number comparison
 | |
|                 Self.requiredSuccessfulResponses >= 0 &&
 | |
|                 numSuccessResponses >= Self.requiredSuccessfulResponses
 | |
|             ) || (
 | |
|                 // Negative value is a "divisor" for a percentage comparison
 | |
|                 Self.requiredSuccessfulResponses < 0 &&
 | |
|                 successPercentage >= abs(1 / CGFloat(Self.requiredSuccessfulResponses))
 | |
|             )
 | |
|         else { throw SnodeAPIError.responseFailedValidation }
 | |
|         
 | |
|         return validResultMap
 | |
|     }
 | |
| }
 | |
| 
 | |
| internal extension ValidatableResponse where ValidationData == Void {
 | |
|     @discardableResult func validResultMap(
 | |
|         swarmPublicKey: String,
 | |
|         using dependencies: Dependencies
 | |
|     ) throws -> [String: ValidationResponse] {
 | |
|         return try validResultMap(swarmPublicKey: swarmPublicKey, validationData: (), using: dependencies)
 | |
|     }
 | |
| }
 | |
| 
 | |
| internal extension ValidatableResponse where ValidationResponse == Bool {
 | |
|     @discardableResult static func validated(map validResultMap: [String: Bool]) throws -> [String: Bool] {
 | |
|         return try validated(
 | |
|             map: validResultMap.filter { $0.value },
 | |
|             totalResponseCount: validResultMap.count
 | |
|         )
 | |
|     }
 | |
| }
 |