From 0482d59df84883c302d20017b720fd1b36cd9ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Coye=20de=20Brune=CC=81lis?= Date: Tue, 11 Jul 2023 10:04:57 +0200 Subject: [PATCH] chore: PR Feedback --- .../Asynchronous/ParallelTaskMapper.swift | 4 +- .../ClosureKit/AsyncCurriedClosure.swift | 49 ------- .../ClosureKit/CurriedClosure.swift | 10 +- .../Extensions/Bundle+Extension.swift | 1 + .../Extensions/Collection+Safe.swift | 2 + .../UTAsyncCurriedClosure.swift | 122 ------------------ .../UTCurriedClosure.swift | 14 +- 7 files changed, 21 insertions(+), 181 deletions(-) delete mode 100644 Sources/InfomaniakCore/ClosureKit/AsyncCurriedClosure.swift delete mode 100644 Tests/InfomaniakCoreTests/UTAsyncCurriedClosure.swift diff --git a/Sources/InfomaniakCore/Asynchronous/ParallelTaskMapper.swift b/Sources/InfomaniakCore/Asynchronous/ParallelTaskMapper.swift index 82f5cfc..f550655 100644 --- a/Sources/InfomaniakCore/Asynchronous/ParallelTaskMapper.swift +++ b/Sources/InfomaniakCore/Asynchronous/ParallelTaskMapper.swift @@ -30,8 +30,8 @@ public typealias SequenceableCollection = Sequence & Collection /// @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) public struct ParallelTaskMapper { - /// internal processing TaskQueue - let taskQueue: TaskQueue + /// private processing TaskQueue + private let taskQueue: TaskQueue /// Init function /// - Parameter concurrency: execution depth, keep default for optimized threading. diff --git a/Sources/InfomaniakCore/ClosureKit/AsyncCurriedClosure.swift b/Sources/InfomaniakCore/ClosureKit/AsyncCurriedClosure.swift deleted file mode 100644 index 720625a..0000000 --- a/Sources/InfomaniakCore/ClosureKit/AsyncCurriedClosure.swift +++ /dev/null @@ -1,49 +0,0 @@ -/* - Infomaniak kDrive - iOS App - Copyright (C) 2023 Infomaniak Network SA - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -import Foundation - -/// Represents `any` (ie. all of them not the type) curried closure, of arbitrary type. -/// -/// Supports concurrency and error -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) -public typealias AsyncCurriedClosure = (Input) async throws -> Output - -/// Execute the closure without waiting, discarding result -postfix operator ~ - -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) -public postfix func ~ (x: @escaping AsyncCurriedClosure) { - Task { - try? await x(()) - } -} - -/// A closure that take no argument and return nothing, but technically curried. -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) -public typealias AsyncClosure = AsyncCurriedClosure - -/// Append an AsyncClosure to another one -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) -public func + (_ lhs: @escaping AsyncClosure, _ rhs: @escaping AsyncClosure) -> AsyncClosure { - let closure: AsyncClosure = { _ in - try await lhs(()) - try await rhs(()) - } - return closure -} diff --git a/Sources/InfomaniakCore/ClosureKit/CurriedClosure.swift b/Sources/InfomaniakCore/ClosureKit/CurriedClosure.swift index 783a3c0..8689a07 100644 --- a/Sources/InfomaniakCore/ClosureKit/CurriedClosure.swift +++ b/Sources/InfomaniakCore/ClosureKit/CurriedClosure.swift @@ -19,17 +19,17 @@ import Foundation /// Represents `any` (ie. all of them not the type) curried closure, of arbitrary type. -/// -/// see `AsyncCurriedClosure` if you need support for structured concurrency or error feedback -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) public typealias CurriedClosure = (Input) -> Output /// A closure that take no argument and return nothing, but technically curried. -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) +/// +/// Calling this closure type requires the use of `Void` which is, in swift, an empty tuple `()`. public typealias SimpleClosure = CurriedClosure /// Append a SimpleClosure to another one -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) +/// +/// This allows you to append / prepend a closure to another one with the + operator. +/// This is not function composition. public func + (_ lhs: @escaping SimpleClosure, _ rhs: @escaping SimpleClosure) -> SimpleClosure { let closure: SimpleClosure = { _ in lhs(()) diff --git a/Sources/InfomaniakCore/Extensions/Bundle+Extension.swift b/Sources/InfomaniakCore/Extensions/Bundle+Extension.swift index 887b370..d586776 100644 --- a/Sources/InfomaniakCore/Extensions/Bundle+Extension.swift +++ b/Sources/InfomaniakCore/Extensions/Bundle+Extension.swift @@ -19,6 +19,7 @@ import Foundation public extension Bundle { + /// Returns `true` if executing in app extension context var isExtension: Bool { return bundleURL.pathExtension == "appex" } diff --git a/Sources/InfomaniakCore/Extensions/Collection+Safe.swift b/Sources/InfomaniakCore/Extensions/Collection+Safe.swift index c86e9c1..e130ca8 100644 --- a/Sources/InfomaniakCore/Extensions/Collection+Safe.swift +++ b/Sources/InfomaniakCore/Extensions/Collection+Safe.swift @@ -26,6 +26,8 @@ public extension Collection { } public extension Array { + /// Returns an `ArraySlice` for the specified indexes if possible. + /// The Slice is bounded to the size of the current collection. subscript(safe range: Range) -> ArraySlice { return self[Swift.min(range.startIndex, endIndex) ..< Swift.min(range.endIndex, endIndex)] } diff --git a/Tests/InfomaniakCoreTests/UTAsyncCurriedClosure.swift b/Tests/InfomaniakCoreTests/UTAsyncCurriedClosure.swift deleted file mode 100644 index 7d4471a..0000000 --- a/Tests/InfomaniakCoreTests/UTAsyncCurriedClosure.swift +++ /dev/null @@ -1,122 +0,0 @@ -/* - Infomaniak Core - iOS - Copyright (C) 2023 Infomaniak Network SA - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -import InfomaniakCore -import XCTest - -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) -public final class CountedFulfillmentTestExpectation: XCTestExpectation { - private(set) var currentFulfillmentCount = 0 - - override public func fulfill() { - currentFulfillmentCount += 1 - super.fulfill() - } -} - -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) -final class UTAsyncCurriedClosure: XCTestCase { - func testAppendToClosure() async { - // GIVEN - let expectationA = CountedFulfillmentTestExpectation(description: "Closure is called") - let expectationB = CountedFulfillmentTestExpectation(description: "Closure is called") - let expectations = [expectationA, expectationB] - - let a: AsyncClosure = { _ in - XCTAssertEqual(expectationA.currentFulfillmentCount, 0, "expectationA should not be fulfilled") - XCTAssertEqual(expectationB.currentFulfillmentCount, 0, "expectationB should not be fulfilled") - expectationA.fulfill() - - let randomShortTime = UInt64.random(in: 1 ... 100) - try await Task.sleep(nanoseconds: randomShortTime) - } - - let b: AsyncClosure = { _ in - XCTAssertEqual(expectationA.currentFulfillmentCount, 1, "expectationA should be fulfilled") - XCTAssertEqual(expectationB.currentFulfillmentCount, 0, "expectationB should not be fulfilled") - expectationB.fulfill() - - let randomShortTime = UInt64.random(in: 1 ... 100) - try await Task.sleep(nanoseconds: randomShortTime) - } - - // WHEN - let computation = a + b - do { - let _ = try await computation~ - } - - // THEN - catch { - XCTFail("error: \(error)") - } - - await fulfillment(of: expectations) - } - - func testAppendToClosure_3chain() async { - // GIVEN - let expectationA = CountedFulfillmentTestExpectation(description: "Closure is called") - let expectationB = CountedFulfillmentTestExpectation(description: "Closure is called") - let expectationC = CountedFulfillmentTestExpectation(description: "Closure is called") - let expectations = [expectationA, expectationB, expectationC] - - let a: AsyncClosure = { _ in - XCTAssertEqual(expectationA.currentFulfillmentCount, 0, "expectationA should not be fulfilled") - XCTAssertEqual(expectationB.currentFulfillmentCount, 0, "expectationB should not be fulfilled") - XCTAssertEqual(expectationC.currentFulfillmentCount, 0, "expectationC should not be fulfilled") - expectationA.fulfill() - - let randomShortTime = UInt64.random(in: 1 ... 100) - try await Task.sleep(nanoseconds: randomShortTime) - } - - let b: AsyncClosure = { _ in - XCTAssertEqual(expectationA.currentFulfillmentCount, 1, "expectationA should be fulfilled") - XCTAssertEqual(expectationB.currentFulfillmentCount, 0, "expectationB should not be fulfilled") - XCTAssertEqual(expectationC.currentFulfillmentCount, 0, "expectationC should not be fulfilled") - expectationB.fulfill() - - let randomShortTime = UInt64.random(in: 1 ... 100) - try await Task.sleep(nanoseconds: randomShortTime) - } - - let c: AsyncClosure = { _ in - XCTAssertEqual(expectationA.currentFulfillmentCount, 1, "expectation should be fulfilled") - XCTAssertEqual(expectationB.currentFulfillmentCount, 1, "expectation should be fulfilled") - XCTAssertEqual(expectationC.currentFulfillmentCount, 0, "expectationC should not be fulfilled") - expectationC.fulfill() - - let randomShortTime = UInt64.random(in: 1 ... 100) - try await Task.sleep(nanoseconds: randomShortTime) - } - - // WHEN - let computation = a + b + c - do { - let _ = try await computation~ - } - - // THEN - catch { - XCTFail("error: \(error)") - } - - await fulfillment(of: expectations) - } -} diff --git a/Tests/InfomaniakCoreTests/UTCurriedClosure.swift b/Tests/InfomaniakCoreTests/UTCurriedClosure.swift index 2a75168..7033ae3 100644 --- a/Tests/InfomaniakCoreTests/UTCurriedClosure.swift +++ b/Tests/InfomaniakCoreTests/UTCurriedClosure.swift @@ -19,7 +19,15 @@ import InfomaniakCore import XCTest -@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) +public final class CountedFulfillmentTestExpectation: XCTestExpectation { + private(set) var currentFulfillmentCount = 0 + + override public func fulfill() { + currentFulfillmentCount += 1 + super.fulfill() + } +} + final class UTCurriedClosure: XCTestCase { func testAppendToClosure() { // GIVEN @@ -41,7 +49,7 @@ final class UTCurriedClosure: XCTestCase { // WHEN let computation = a + b - let _ = computation~ + computation(()) // THEN wait(for: expectations, timeout: 10.0) @@ -77,7 +85,7 @@ final class UTCurriedClosure: XCTestCase { // WHEN let computation = a + b + c - let _ = computation~ + computation(()) // THEN wait(for: expectations, timeout: 10.0)