mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
[AltStoreCore] Flattens optional values when @Managed/@AsyncManaged.wrappedValue is also optional
This commit is contained in:
19
AltStoreCore/Protocols/OptionalProtocol.swift
Normal file
19
AltStoreCore/Protocols/OptionalProtocol.swift
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// OptionalProtocol.swift
|
||||
// AltStoreCore
|
||||
//
|
||||
// Created by Riley Testut on 5/11/23.
|
||||
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// Public so we can use as generic constraint.
|
||||
public protocol OptionalProtocol
|
||||
{
|
||||
associatedtype Wrapped
|
||||
|
||||
static var none: Self { get }
|
||||
}
|
||||
|
||||
extension Optional: OptionalProtocol {}
|
||||
@@ -71,6 +71,7 @@ public extension AsyncManaged
|
||||
/// @dynamicMemberLookup
|
||||
public extension AsyncManaged
|
||||
{
|
||||
// Non-optional values
|
||||
subscript<T>(dynamicMember keyPath: KeyPath<ManagedObject, T>) -> T {
|
||||
get async {
|
||||
let result = await self.perform { $0[keyPath: keyPath] }
|
||||
@@ -78,7 +79,7 @@ public extension AsyncManaged
|
||||
}
|
||||
}
|
||||
|
||||
// Optionals
|
||||
// Optional wrapped value
|
||||
subscript<Wrapped, T>(dynamicMember keyPath: KeyPath<Wrapped, T>) -> T? where ManagedObject == Optional<Wrapped> {
|
||||
get async {
|
||||
guard let wrappedValue else { return nil }
|
||||
@@ -87,4 +88,14 @@ public extension AsyncManaged
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// Optional wrapped value + optional property (flattened)
|
||||
subscript<Wrapped, T>(dynamicMember keyPath: KeyPath<Wrapped, T>) -> T where ManagedObject == Optional<Wrapped>, T: OptionalProtocol {
|
||||
get async {
|
||||
guard let wrappedValue else { return T.none }
|
||||
|
||||
let result = await self.perform { _ in wrappedValue[keyPath: keyPath] }
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,13 +80,14 @@ public extension Managed
|
||||
/// @dynamicMemberLookup
|
||||
public extension Managed
|
||||
{
|
||||
// Non-optional values
|
||||
subscript<T>(dynamicMember keyPath: KeyPath<ManagedObject, T>) -> T
|
||||
{
|
||||
let result = self.perform { $0[keyPath: keyPath] }
|
||||
return result
|
||||
}
|
||||
|
||||
// Optionals
|
||||
// Optional wrapped value
|
||||
subscript<Wrapped, T>(dynamicMember keyPath: KeyPath<Wrapped, T>) -> T? where ManagedObject == Optional<Wrapped>
|
||||
{
|
||||
guard let wrappedValue else { return nil }
|
||||
@@ -94,4 +95,13 @@ public extension Managed
|
||||
let result = self.perform { _ in wrappedValue[keyPath: keyPath] }
|
||||
return result
|
||||
}
|
||||
|
||||
// Optional wrapped value + optional property (flattened)
|
||||
subscript<Wrapped, T>(dynamicMember keyPath: KeyPath<Wrapped, T>) -> T where ManagedObject == Optional<Wrapped>, T: OptionalProtocol
|
||||
{
|
||||
guard let wrappedValue else { return T.none }
|
||||
|
||||
let result = self.perform { _ in wrappedValue[keyPath: keyPath] }
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user