From 92c8546e301d3cd823ed6c5e696b8433476858a4 Mon Sep 17 00:00:00 2001 From: Andrew Roan Date: Wed, 27 Mar 2024 16:33:22 -0500 Subject: [PATCH 1/3] Add inlinable notations to public generic methods to encourage generic specializations by the compiler feature/add-inlinable-notations-to-encourage-generic-specialization --- .../CoreDataRepository+Aggregate.swift | 19 ++++++++++++++++++- .../CoreDataRepository+Batch.swift | 6 ++++++ .../CoreDataRepository+CRUD.swift | 8 +++++++- .../CoreDataRepository+Fetch.swift | 4 ++++ .../Internal/AggregateSubscription.swift | 3 +++ .../AggregateThrowingSubscription.swift | 3 +++ .../Internal/BaseSubscription.swift | 9 +++++++++ .../Internal/CountSubscription.swift | 3 +++ .../Internal/CountThrowingSubscription.swift | 3 +++ .../Internal/FetchSubscription.swift | 2 ++ .../Internal/FetchThrowingSubscription.swift | 2 ++ .../NSFetchRequest+AggregateHelpers.swift | 2 ++ .../NSManagedObject+CRUDHelpers.swift | 1 + .../NSManagedObjectContext+CRUDHelpers.swift | 2 ++ .../NSManagedObjectContext+Child.swift | 2 ++ .../NSManagedObjectContext+Scratchpad.swift | 1 + .../Internal/ReadSubscription.swift | 5 +++++ .../Internal/ReadThrowingSubscription.swift | 5 +++++ .../Internal/Subscription.swift | 7 +++++++ .../Internal/ThrowingSubscription.swift | 7 +++++++ 20 files changed, 92 insertions(+), 2 deletions(-) diff --git a/Sources/CoreDataRepository/CoreDataRepository+Aggregate.swift b/Sources/CoreDataRepository/CoreDataRepository+Aggregate.swift index e44fcca..c24b650 100644 --- a/Sources/CoreDataRepository/CoreDataRepository+Aggregate.swift +++ b/Sources/CoreDataRepository/CoreDataRepository+Aggregate.swift @@ -15,6 +15,7 @@ extension CoreDataRepository { // MARK: Count /// Get the count or quantity of managed object instances that satisfy the predicate. + @inlinable public func count( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -35,6 +36,7 @@ extension CoreDataRepository { } /// Subscribe to the count or quantity of managed object instances that satisfy the predicate. + @inlinable public func countSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -55,6 +57,7 @@ extension CoreDataRepository { } /// Subscribe to the count or quantity of managed object instances that satisfy the predicate. + @inlinable public func countThrowingSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -77,6 +80,7 @@ extension CoreDataRepository { // MARK: Sum /// Get the sum of a managed object's numeric property for all instances that satisfy the predicate. + @inlinable public func sum( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -95,6 +99,7 @@ extension CoreDataRepository { } /// Subscribe to the sum of a managed object's numeric property for all instances that satisfy the predicate. + @inlinable public func sumSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -120,6 +125,7 @@ extension CoreDataRepository { } /// Subscribe to the sum of a managed object's numeric property for all instances that satisfy the predicate. + @inlinable public func sumThrowingSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -147,6 +153,7 @@ extension CoreDataRepository { // MARK: Average /// Get the average of a managed object's numeric property for all instances that satisfy the predicate. + @inlinable public func average( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -165,6 +172,7 @@ extension CoreDataRepository { } /// Subscribe to the average of a managed object's numeric property for all instances that satisfy the predicate. + @inlinable public func averageSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -190,6 +198,7 @@ extension CoreDataRepository { } /// Subscribe to the average of a managed object's numeric property for all instances that satisfy the predicate. + @inlinable public func averageThrowingSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -217,6 +226,7 @@ extension CoreDataRepository { // MARK: Min /// Get the min or minimum of a managed object's numeric property for all instances that satisfy the predicate. + @inlinable public func min( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -236,6 +246,7 @@ extension CoreDataRepository { /// Subscribe to the min or minimum of a managed object's numeric property for all instances that satisfy the /// predicate. + @inlinable public func minSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -262,6 +273,7 @@ extension CoreDataRepository { /// Subscribe to the min or minimum of a managed object's numeric property for all instances that satisfy the /// predicate. + @inlinable public func minThrowingSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -289,6 +301,7 @@ extension CoreDataRepository { // MARK: Max /// Get the max or maximum of a managed object's numeric property for all instances that satisfy the predicate. + @inlinable public func max( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -308,6 +321,7 @@ extension CoreDataRepository { /// Subscribe to the max or maximum of a managed object's numeric property for all instances that satisfy the /// predicate. + @inlinable public func maxSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -334,6 +348,7 @@ extension CoreDataRepository { /// Subscribe to the max or maximum of a managed object's numeric property for all instances that satisfy the /// predicate. + @inlinable public func maxThrowingSubscription( predicate: NSPredicate, entityDesc: NSEntityDescription, @@ -360,6 +375,7 @@ extension CoreDataRepository { // MARK: Internals + @usableFromInline enum AggregateFunction: String { case count case sum @@ -379,7 +395,8 @@ extension CoreDataRepository { return value } - private static func send( + @usableFromInline + static func send( function: AggregateFunction, context: NSManagedObjectContext, predicate: NSPredicate, diff --git a/Sources/CoreDataRepository/CoreDataRepository+Batch.swift b/Sources/CoreDataRepository/CoreDataRepository+Batch.swift index 06d8010..30a03f3 100644 --- a/Sources/CoreDataRepository/CoreDataRepository+Batch.swift +++ b/Sources/CoreDataRepository/CoreDataRepository+Batch.swift @@ -29,6 +29,7 @@ extension CoreDataRepository { /// Create a batch of unmanaged models. /// /// This operation is non-atomic. Each instance may succeed or fail individually. + @inlinable public func create( _ items: [Model], transactionAuthor: String? = nil @@ -68,6 +69,7 @@ extension CoreDataRepository { } /// Create a batch of unmanaged models. + @inlinable public func createAtomically( _ items: [Model], transactionAuthor: String? = nil @@ -92,6 +94,7 @@ extension CoreDataRepository { /// Read a batch of unmanaged models. /// /// This operation is non-atomic. Each instance may succeed or fail individually. + @inlinable public func read( urls: [URL], as _: Model.Type @@ -130,6 +133,7 @@ extension CoreDataRepository { } /// Read a batch of unmanaged models. + @inlinable public func readAtomically( urls: [URL], as _: Model.Type @@ -163,6 +167,7 @@ extension CoreDataRepository { /// Update the store with a batch of unmanaged models. /// /// This operation is non-atomic. Each instance may succeed or fail individually. + @inlinable public func update( _ items: [Model], transactionAuthor: String? = nil @@ -205,6 +210,7 @@ extension CoreDataRepository { } /// Update the store with a batch of unmanaged models. + @inlinable public func updateAtomically( _ items: [Model], transactionAuthor: String? = nil diff --git a/Sources/CoreDataRepository/CoreDataRepository+CRUD.swift b/Sources/CoreDataRepository/CoreDataRepository+CRUD.swift index d82281b..f08cb68 100644 --- a/Sources/CoreDataRepository/CoreDataRepository+CRUD.swift +++ b/Sources/CoreDataRepository/CoreDataRepository+CRUD.swift @@ -11,6 +11,7 @@ import Foundation extension CoreDataRepository { /// Create an instance in the store. + @inlinable public func create( _ item: Model, transactionAuthor: String? = nil @@ -37,6 +38,7 @@ extension CoreDataRepository { } /// Read an instance from the store. + @inlinable public func read( _ url: URL, of _: Model.Type @@ -50,6 +52,7 @@ extension CoreDataRepository { } /// Update the store with an unmanaged model. + @inlinable public func update( _ url: URL, with item: Model, @@ -93,6 +96,7 @@ extension CoreDataRepository { } /// Subscribe to updates of an instance in the store. + @inlinable public func readSubscription(_ url: URL, of _: Model.Type) -> AsyncStream> { @@ -120,6 +124,7 @@ extension CoreDataRepository { } /// Subscribe to updates of an instance in the store. + @inlinable public func readThrowingSubscription(_ url: URL, of _: Model.Type) -> AsyncThrowingStream { @@ -146,7 +151,8 @@ extension CoreDataRepository { } } - private static func getObjectId( + @usableFromInline + static func getObjectId( fromUrl url: URL, context: NSManagedObjectContext ) -> Result { diff --git a/Sources/CoreDataRepository/CoreDataRepository+Fetch.swift b/Sources/CoreDataRepository/CoreDataRepository+Fetch.swift index edb321c..c01bb0d 100644 --- a/Sources/CoreDataRepository/CoreDataRepository+Fetch.swift +++ b/Sources/CoreDataRepository/CoreDataRepository+Fetch.swift @@ -11,6 +11,7 @@ import Foundation extension CoreDataRepository { /// Fetch items from the store with a ``NSFetchRequest``. + @inlinable public func fetch( _ request: NSFetchRequest, as _: Model.Type @@ -21,6 +22,7 @@ extension CoreDataRepository { } /// Fetch items from the store with a ``NSFetchRequest`` and receive updates as the store changes. + @inlinable public func fetchSubscription( _ request: NSFetchRequest, of _: Model.Type @@ -39,6 +41,7 @@ extension CoreDataRepository { } /// Fetch items from the store with a ``NSFetchRequest`` and receive updates as the store changes. + @inlinable public func fetchThrowingSubscription( _ request: NSFetchRequest, of _: Model.Type @@ -57,6 +60,7 @@ extension CoreDataRepository { } /// Fetch items from the store with a ``NSFetchRequest`` and transform the results. + @inlinable public func fetch( request: NSFetchRequest, operation: @escaping (_ results: [Managed]) throws -> Output diff --git a/Sources/CoreDataRepository/Internal/AggregateSubscription.swift b/Sources/CoreDataRepository/Internal/AggregateSubscription.swift index 1b18262..2dc54c3 100644 --- a/Sources/CoreDataRepository/Internal/AggregateSubscription.swift +++ b/Sources/CoreDataRepository/Internal/AggregateSubscription.swift @@ -10,7 +10,9 @@ import CoreData import Foundation /// Subscription provider that sends updates when an aggregate fetch request changes +@usableFromInline final class AggregateSubscription: Subscription where Value: Numeric { + @usableFromInline override func fetch() { frc.managedObjectContext.perform { [weak self, frc, request] in guard frc.fetchedObjects != nil else { @@ -37,6 +39,7 @@ final class AggregateSubscription: Subscription: ThrowingSubscription where Value: Numeric { + @usableFromInline override func fetch() { frc.managedObjectContext.perform { [weak self, frc, request] in guard frc.fetchedObjects != nil else { @@ -39,6 +41,7 @@ final class AggregateThrowingSubscription: ThrowingSubscription let frc: NSFetchedResultsController + @usableFromInline init( fetchRequest: NSFetchRequest, fetchResultControllerRequest: NSFetchRequest, @@ -35,14 +37,17 @@ class BaseSubscription< start() } + @usableFromInline func fetch() { fatalError("\(Self.self).\(#function) is not implemented.") } + @usableFromInline func controllerDidChangeContent(_: NSFetchedResultsController) { fetch() } + @usableFromInline func start() { do { try frc.performFetch() @@ -53,18 +58,22 @@ class BaseSubscription< } } + @usableFromInline func manualFetch() { fetch() } + @usableFromInline func cancel() { fatalError("\(Self.self).\(#function) is not implemented.") } + @usableFromInline func fail(_: CoreDataError) { fatalError("\(Self.self).\(#function) is not implemented.") } + @usableFromInline func send(_: Output) { fatalError("\(Self.self).\(#function) is not implemented.") } diff --git a/Sources/CoreDataRepository/Internal/CountSubscription.swift b/Sources/CoreDataRepository/Internal/CountSubscription.swift index 6231855..ada7150 100644 --- a/Sources/CoreDataRepository/Internal/CountSubscription.swift +++ b/Sources/CoreDataRepository/Internal/CountSubscription.swift @@ -10,7 +10,9 @@ import CoreData import Foundation /// Subscription provider that sends updates when a count fetch request changes +@usableFromInline final class CountSubscription: Subscription where Value: Numeric { + @usableFromInline override func fetch() { frc.managedObjectContext.perform { [weak self, frc] in if (frc.fetchedObjects ?? []).isEmpty { @@ -27,6 +29,7 @@ final class CountSubscription: Subscription: ThrowingSubscription where Value: Numeric { + @usableFromInline override func fetch() { frc.managedObjectContext.perform { [weak self, frc] in if (frc.fetchedObjects ?? []).isEmpty { @@ -29,6 +31,7 @@ final class CountThrowingSubscription: ThrowingSubscription: Subscription< [Model], Model.ManagedModel, Model.ManagedModel > { + @usableFromInline override func fetch() { frc.managedObjectContext.perform { [weak self, frc, request] in guard frc.fetchedObjects != nil else { diff --git a/Sources/CoreDataRepository/Internal/FetchThrowingSubscription.swift b/Sources/CoreDataRepository/Internal/FetchThrowingSubscription.swift index 580863a..342d570 100644 --- a/Sources/CoreDataRepository/Internal/FetchThrowingSubscription.swift +++ b/Sources/CoreDataRepository/Internal/FetchThrowingSubscription.swift @@ -10,11 +10,13 @@ import CoreData import Foundation /// Subscription provider that sends updates when a fetch request changes +@usableFromInline final class FetchThrowingSubscription: ThrowingSubscription< [Model], Model.ManagedModel, Model.ManagedModel > { + @usableFromInline override func fetch() { frc.managedObjectContext.perform { [weak self, frc, request] in guard frc.fetchedObjects != nil else { diff --git a/Sources/CoreDataRepository/Internal/NSFetchRequest+AggregateHelpers.swift b/Sources/CoreDataRepository/Internal/NSFetchRequest+AggregateHelpers.swift index 5180b6d..2025a2c 100644 --- a/Sources/CoreDataRepository/Internal/NSFetchRequest+AggregateHelpers.swift +++ b/Sources/CoreDataRepository/Internal/NSFetchRequest+AggregateHelpers.swift @@ -11,6 +11,7 @@ import Foundation extension NSFetchRequest { /// Helper function for building an aggregate fetch request + @usableFromInline static func request( function: CoreDataRepository.AggregateFunction, predicate: NSPredicate, @@ -39,6 +40,7 @@ extension NSFetchRequest { } /// Helper function for building a count fetch request + @usableFromInline static func countRequest( predicate: NSPredicate, entityDesc: NSEntityDescription diff --git a/Sources/CoreDataRepository/Internal/NSManagedObject+CRUDHelpers.swift b/Sources/CoreDataRepository/Internal/NSManagedObject+CRUDHelpers.swift index de2501f..df84314 100644 --- a/Sources/CoreDataRepository/Internal/NSManagedObject+CRUDHelpers.swift +++ b/Sources/CoreDataRepository/Internal/NSManagedObject+CRUDHelpers.swift @@ -11,6 +11,7 @@ import Foundation extension NSManagedObject { /// Helper function to handle casting ``NSManagedObject`` to a sub-class. + @usableFromInline func asManagedModel() throws -> T where T: NSManagedObject { guard let repoManaged = self as? T else { throw CoreDataError.fetchedObjectFailedToCastToExpectedType diff --git a/Sources/CoreDataRepository/Internal/NSManagedObjectContext+CRUDHelpers.swift b/Sources/CoreDataRepository/Internal/NSManagedObjectContext+CRUDHelpers.swift index cee2d24..21ff7de 100644 --- a/Sources/CoreDataRepository/Internal/NSManagedObjectContext+CRUDHelpers.swift +++ b/Sources/CoreDataRepository/Internal/NSManagedObjectContext+CRUDHelpers.swift @@ -11,6 +11,7 @@ import Foundation extension NSManagedObjectContext { /// Helper function for getting the ``NSManagedObjectID`` from an ``URL`` + @usableFromInline func objectId(from url: URL) -> Result { guard let objectId = persistentStoreCoordinator?.managedObjectID(forURIRepresentation: url) else { return .failure(CoreDataError.failedToGetObjectIdFromUrl(url)) @@ -19,6 +20,7 @@ extension NSManagedObjectContext { } /// Helper function for checking that a managed object is not deleted in the store + @usableFromInline func notDeletedObject(for id: NSManagedObjectID) throws -> NSManagedObject { let object: NSManagedObject = try existingObject(with: id) guard !object.isDeleted else { diff --git a/Sources/CoreDataRepository/Internal/NSManagedObjectContext+Child.swift b/Sources/CoreDataRepository/Internal/NSManagedObjectContext+Child.swift index 3fcc544..d93fea6 100644 --- a/Sources/CoreDataRepository/Internal/NSManagedObjectContext+Child.swift +++ b/Sources/CoreDataRepository/Internal/NSManagedObjectContext+Child.swift @@ -11,6 +11,7 @@ import Foundation extension NSManagedObjectContext { /// Helper function for error mapping a throwing operation in a temporary context + @usableFromInline func performInChild( schedule: NSManagedObjectContext.ScheduledTaskType = .immediate, _ block: @escaping (NSManagedObjectContext) throws -> Output @@ -30,6 +31,7 @@ extension NSManagedObjectContext { } /// Helper function for getting a temporary context + @usableFromInline func childContext() -> NSManagedObjectContext { let child = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) child.automaticallyMergesChangesFromParent = true diff --git a/Sources/CoreDataRepository/Internal/NSManagedObjectContext+Scratchpad.swift b/Sources/CoreDataRepository/Internal/NSManagedObjectContext+Scratchpad.swift index f4f76d0..2991388 100644 --- a/Sources/CoreDataRepository/Internal/NSManagedObjectContext+Scratchpad.swift +++ b/Sources/CoreDataRepository/Internal/NSManagedObjectContext+Scratchpad.swift @@ -10,6 +10,7 @@ import CoreData import Foundation extension NSManagedObjectContext { + @usableFromInline func performInScratchPad( schedule: NSManagedObjectContext.ScheduledTaskType = .immediate, _ block: @escaping (NSManagedObjectContext) throws -> Output diff --git a/Sources/CoreDataRepository/Internal/ReadSubscription.swift b/Sources/CoreDataRepository/Internal/ReadSubscription.swift index ac2fb3d..cf0328f 100644 --- a/Sources/CoreDataRepository/Internal/ReadSubscription.swift +++ b/Sources/CoreDataRepository/Internal/ReadSubscription.swift @@ -11,12 +11,14 @@ import CoreData import Foundation /// Subscription provider that sends updates when a single ``NSManagedObject`` changes +@usableFromInline final class ReadSubscription { private let objectId: NSManagedObjectID private let context: NSManagedObjectContext private var cancellables: Set private let continuation: AsyncStream>.Continuation + @usableFromInline func manualFetch() { context.perform { [weak self, context, objectId] in guard let object = context.object(with: objectId) as? Model.ManagedModel else { @@ -31,11 +33,13 @@ final class ReadSubscription { } } + @usableFromInline func cancel() { continuation.finish() cancellables.forEach { $0.cancel() } } + @usableFromInline func start() { context.perform { [weak self, context, objectId] in guard let object = context.object(with: objectId) as? Model.ManagedModel else { @@ -53,6 +57,7 @@ final class ReadSubscription { } } + @usableFromInline init( objectId: NSManagedObjectID, context: NSManagedObjectContext, diff --git a/Sources/CoreDataRepository/Internal/ReadThrowingSubscription.swift b/Sources/CoreDataRepository/Internal/ReadThrowingSubscription.swift index 1852789..3a57f5c 100644 --- a/Sources/CoreDataRepository/Internal/ReadThrowingSubscription.swift +++ b/Sources/CoreDataRepository/Internal/ReadThrowingSubscription.swift @@ -10,12 +10,14 @@ import Combine import CoreData import Foundation +@usableFromInline final class ReadThrowingSubscription { private let objectId: NSManagedObjectID private let context: NSManagedObjectContext private var cancellables: Set private let continuation: AsyncThrowingStream.Continuation + @usableFromInline func manualFetch() { context.perform { [weak self, context, objectId] in guard let object = context.object(with: objectId) as? Model.ManagedModel else { @@ -30,11 +32,13 @@ final class ReadThrowingSubscription { } } + @usableFromInline func cancel() { continuation.finish() cancellables.forEach { $0.cancel() } } + @usableFromInline func start() { context.perform { [weak self, context, objectId] in guard let object = context.object(with: objectId) as? Model.ManagedModel else { @@ -52,6 +56,7 @@ final class ReadThrowingSubscription { } } + @usableFromInline init( objectId: NSManagedObjectID, context: NSManagedObjectContext, diff --git a/Sources/CoreDataRepository/Internal/Subscription.swift b/Sources/CoreDataRepository/Internal/Subscription.swift index be9912b..1a91d99 100644 --- a/Sources/CoreDataRepository/Internal/Subscription.swift +++ b/Sources/CoreDataRepository/Internal/Subscription.swift @@ -10,6 +10,7 @@ import CoreData import Foundation /// Base class for other subscriptions. +@usableFromInline class Subscription< Output, RequestResult: NSFetchRequestResult, @@ -17,6 +18,7 @@ class Subscription< >: BaseSubscription { let continuation: AsyncStream>.Continuation + @usableFromInline init( fetchRequest: NSFetchRequest, fetchResultControllerRequest: NSFetchRequest, @@ -31,14 +33,17 @@ class Subscription< ) } + @usableFromInline override func cancel() { continuation.finish() } + @usableFromInline override final func fail(_ error: CoreDataError) { continuation.yield(.failure(error)) } + @usableFromInline override final func send(_ value: Output) { continuation.yield(.success(value)) } @@ -47,6 +52,7 @@ class Subscription< // MARK: where RequestResult == ControllerResult extension Subscription where RequestResult == ControllerResult { + @usableFromInline convenience init( request: NSFetchRequest, context: NSManagedObjectContext, @@ -64,6 +70,7 @@ extension Subscription where RequestResult == ControllerResult { // MARK: where RequestResult == NSDictionary, ControllerResult == NSManagedObject extension Subscription where RequestResult == NSDictionary, ControllerResult == NSManagedObject { + @usableFromInline convenience init( request: NSFetchRequest, context: NSManagedObjectContext, diff --git a/Sources/CoreDataRepository/Internal/ThrowingSubscription.swift b/Sources/CoreDataRepository/Internal/ThrowingSubscription.swift index 1f5be5f..3b74347 100644 --- a/Sources/CoreDataRepository/Internal/ThrowingSubscription.swift +++ b/Sources/CoreDataRepository/Internal/ThrowingSubscription.swift @@ -10,6 +10,7 @@ import CoreData import Foundation /// Base class for other subscriptions. +@usableFromInline class ThrowingSubscription< Output, RequestResult: NSFetchRequestResult, @@ -17,6 +18,7 @@ class ThrowingSubscription< >: BaseSubscription { private let continuation: AsyncThrowingStream.Continuation + @usableFromInline init( fetchRequest: NSFetchRequest, fetchResultControllerRequest: NSFetchRequest, @@ -31,14 +33,17 @@ class ThrowingSubscription< ) } + @usableFromInline override func cancel() { continuation.finish() } + @usableFromInline override final func fail(_ error: CoreDataError) { continuation.yield(with: .failure(error)) } + @usableFromInline override final func send(_ value: Output) { continuation.yield(with: .success(value)) } @@ -47,6 +52,7 @@ class ThrowingSubscription< // MARK: where RequestResult == ControllerResult extension ThrowingSubscription where RequestResult == ControllerResult { + @usableFromInline convenience init( request: NSFetchRequest, context: NSManagedObjectContext, @@ -64,6 +70,7 @@ extension ThrowingSubscription where RequestResult == ControllerResult { // MARK: where RequestResult == NSDictionary, ControllerResult == NSManagedObject extension ThrowingSubscription where RequestResult == NSDictionary, ControllerResult == NSManagedObject { + @usableFromInline convenience init( request: NSFetchRequest, context: NSManagedObjectContext, From 24df2e5e9ff638c6072b12258f7d030282061667 Mon Sep 17 00:00:00 2001 From: Andrew Roan Date: Wed, 27 Mar 2024 16:46:14 -0500 Subject: [PATCH 2/3] Add inlinable notation to non-generic public methods as it may allow other compiler optimizations feature/add-inlinable-notations-to-encourage-generic-specialization --- Sources/CoreDataRepository/CoreDataRepository+Batch.swift | 5 +++++ Sources/CoreDataRepository/CoreDataRepository+CRUD.swift | 1 + Sources/CoreDataRepository/UnmanagedReadOnlyModel.swift | 1 + 3 files changed, 7 insertions(+) diff --git a/Sources/CoreDataRepository/CoreDataRepository+Batch.swift b/Sources/CoreDataRepository/CoreDataRepository+Batch.swift index 30a03f3..2b04142 100644 --- a/Sources/CoreDataRepository/CoreDataRepository+Batch.swift +++ b/Sources/CoreDataRepository/CoreDataRepository+Batch.swift @@ -11,6 +11,7 @@ import Foundation extension CoreDataRepository { /// Execute a NSBatchInsertRequest against the store. + @inlinable public func insert( _ request: NSBatchInsertRequest, transactionAuthor: String? = nil @@ -149,6 +150,7 @@ extension CoreDataRepository { } /// Execute a NSBatchUpdateRequest against the store. + @inlinable public func update( _ request: NSBatchUpdateRequest, transactionAuthor: String? = nil @@ -238,6 +240,7 @@ extension CoreDataRepository { } /// Execute a NSBatchDeleteRequest against the store. + @inlinable public func delete( _ request: NSBatchDeleteRequest, transactionAuthor: String? = nil @@ -256,6 +259,7 @@ extension CoreDataRepository { /// Delete from the store with a batch of unmanaged models. /// /// This operation is non-atomic. Each instance may succeed or fail individually. + @inlinable public func delete( urls: [URL], transactionAuthor: String? = nil @@ -295,6 +299,7 @@ extension CoreDataRepository { } /// Delete from the store with a batch of unmanaged models. + @inlinable public func deleteAtomically( urls: [URL], transactionAuthor: String? = nil diff --git a/Sources/CoreDataRepository/CoreDataRepository+CRUD.swift b/Sources/CoreDataRepository/CoreDataRepository+CRUD.swift index f08cb68..10bb39f 100644 --- a/Sources/CoreDataRepository/CoreDataRepository+CRUD.swift +++ b/Sources/CoreDataRepository/CoreDataRepository+CRUD.swift @@ -75,6 +75,7 @@ extension CoreDataRepository { } /// Delete an instance from the store. + @inlinable public func delete( _ url: URL, transactionAuthor: String? = nil diff --git a/Sources/CoreDataRepository/UnmanagedReadOnlyModel.swift b/Sources/CoreDataRepository/UnmanagedReadOnlyModel.swift index 7cbf6f7..85a6b42 100644 --- a/Sources/CoreDataRepository/UnmanagedReadOnlyModel.swift +++ b/Sources/CoreDataRepository/UnmanagedReadOnlyModel.swift @@ -81,6 +81,7 @@ public protocol UnmanagedReadOnlyModel: Equatable { } extension UnmanagedReadOnlyModel { + @inlinable public static func managedFetchRequest() -> NSFetchRequest { NSFetchRequest( entityName: ManagedModel.entity().name ?? ManagedModel.entity() From 467294ee08c309b6e4dac85b02503e34b10591d6 Mon Sep 17 00:00:00 2001 From: Andrew Roan Date: Tue, 2 Apr 2024 22:35:48 -0500 Subject: [PATCH 3/3] Add more inlinable notations after git merge feature/add-inlinable-notations-to-encourage-generic-specialization --- Sources/CoreDataRepository/CoreDataBatchError.swift | 2 ++ Sources/CoreDataRepository/CoreDataError.swift | 2 ++ Sources/CoreDataRepository/CoreDataRepository+Custom.swift | 1 + Sources/CoreDataRepository/CoreDataRepository.swift | 1 + Sources/CoreDataRepository/NSManagedObject+Helpers.swift | 2 +- .../CoreDataRepository/NSManagedObjectContext+Helpers.swift | 4 ++-- 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Sources/CoreDataRepository/CoreDataBatchError.swift b/Sources/CoreDataRepository/CoreDataBatchError.swift index 310cfe9..f112fa1 100644 --- a/Sources/CoreDataRepository/CoreDataBatchError.swift +++ b/Sources/CoreDataRepository/CoreDataBatchError.swift @@ -21,10 +21,12 @@ public struct CoreDataBatchError: Error { /// The underlying error. public let error: CoreDataError + @inlinable public var localizedDescription: String { error.localizedDescription } + @inlinable public init(item: T, error: CoreDataError) { self.item = item self.error = error diff --git a/Sources/CoreDataRepository/CoreDataError.swift b/Sources/CoreDataRepository/CoreDataError.swift index 324da18..2d52621 100644 --- a/Sources/CoreDataRepository/CoreDataError.swift +++ b/Sources/CoreDataRepository/CoreDataError.swift @@ -108,6 +108,7 @@ public enum CoreDataError: Error, Hashable, Sendable { extension CoreDataError: CustomNSError { public static let errorDomain: String = "CoreDataRepository" + @inlinable public var errorCode: Int { switch self { case .failedToGetObjectIdFromUrl: @@ -133,6 +134,7 @@ extension CoreDataError: CustomNSError { public static let urlUserInfoKey: String = "ObjectIdUrl" + @inlinable public var errorUserInfo: [String: Any] { switch self { case let .failedToGetObjectIdFromUrl(url): diff --git a/Sources/CoreDataRepository/CoreDataRepository+Custom.swift b/Sources/CoreDataRepository/CoreDataRepository+Custom.swift index 2a151e2..153d82e 100644 --- a/Sources/CoreDataRepository/CoreDataRepository+Custom.swift +++ b/Sources/CoreDataRepository/CoreDataRepository+Custom.swift @@ -15,6 +15,7 @@ extension CoreDataRepository { /// /// The caller is responsible for saving the contexts and cleaning up if needed. /// All this method provides is the contexts and mapping `Error` into ``CoreDataError``. + @inlinable public func custom( schedule: NSManagedObjectContext.ScheduledTaskType = .enqueued, block: @escaping ( diff --git a/Sources/CoreDataRepository/CoreDataRepository.swift b/Sources/CoreDataRepository/CoreDataRepository.swift index ce50e20..66dd223 100644 --- a/Sources/CoreDataRepository/CoreDataRepository.swift +++ b/Sources/CoreDataRepository/CoreDataRepository.swift @@ -29,6 +29,7 @@ public final class CoreDataRepository { /// to be performed in. public let context: NSManagedObjectContext + @inlinable public init(context: NSManagedObjectContext) { self.context = context } diff --git a/Sources/CoreDataRepository/NSManagedObject+Helpers.swift b/Sources/CoreDataRepository/NSManagedObject+Helpers.swift index 911c6c5..b1bbfca 100644 --- a/Sources/CoreDataRepository/NSManagedObject+Helpers.swift +++ b/Sources/CoreDataRepository/NSManagedObject+Helpers.swift @@ -11,7 +11,7 @@ import Foundation extension NSManagedObject { /// Helper function to handle casting ``NSManagedObject`` to a sub-class. - @inlinable + @inlinable public func asManagedModel() throws -> T where T: NSManagedObject { guard let repoManaged = self as? T else { throw CoreDataError.fetchedObjectFailedToCastToExpectedType diff --git a/Sources/CoreDataRepository/NSManagedObjectContext+Helpers.swift b/Sources/CoreDataRepository/NSManagedObjectContext+Helpers.swift index 346f814..accba7a 100644 --- a/Sources/CoreDataRepository/NSManagedObjectContext+Helpers.swift +++ b/Sources/CoreDataRepository/NSManagedObjectContext+Helpers.swift @@ -11,7 +11,7 @@ import Foundation extension NSManagedObjectContext { /// Helper function for getting the ``NSManagedObjectID`` from an ``URL`` - @inlinable + @inlinable public func objectId(from url: URL) -> Result { guard let objectId = persistentStoreCoordinator?.managedObjectID(forURIRepresentation: url) else { return .failure(CoreDataError.failedToGetObjectIdFromUrl(url)) @@ -20,7 +20,7 @@ extension NSManagedObjectContext { } /// Helper function for checking that a managed object is not deleted in the store - @inlinable + @inlinable public func notDeletedObject(for id: NSManagedObjectID) throws -> NSManagedObject { let object: NSManagedObject = try existingObject(with: id) guard !object.isDeleted else {