Skip to content

Commit

Permalink
Swift-Concurrency adoption (#52)
Browse files Browse the repository at this point in the history
* enabled swift concurrency

* fixed Swift Concurrency warnings

* sendable support for merge strategy closures

* sendable conformance for relationship

* sendable conformance for models

* removed swift concurrency flag
  • Loading branch information
KazaiMazai authored Aug 12, 2024
1 parent e9ee8f0 commit b078d58
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 18 deletions.
4 changes: 3 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ let package = Package(
),
.target(
name: "SwiftletModel",

dependencies: [
"SwiftletModelMacros",
.product(name: "Collections", package: "swift-collections")
]),
]
),

.testTarget(
name: "SwiftletModelTests",
Expand Down
29 changes: 19 additions & 10 deletions Sources/SwiftletModel/Model/MergeStrategy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

import Foundation

public struct MergeStrategy<T> {
let merge: (_ old: T, _ new: T) -> T
public struct MergeStrategy<T>: Sendable {
let merge: @Sendable (_ old: T, _ new: T) -> T

public init(merge: @escaping (T, T) -> T) {
public init(merge: @Sendable @escaping (T, T) -> T) {
self.merge = merge
}
}
Expand All @@ -33,10 +33,13 @@ public extension MergeStrategy {

public extension MergeStrategy {

static func patch<Entity, Value>(_ keyPath: WritableKeyPath<Entity, Value?>) -> MergeStrategy<Entity> {
static func patch<Entity, Value>(
_ keyPath: @Sendable @escaping @autoclosure () -> WritableKeyPath<Entity, Value?>
) -> MergeStrategy<Entity> {

MergeStrategy<Entity> { old, new in
var new = new
new[keyPath: keyPath] = new[keyPath: keyPath] ?? old[keyPath: keyPath]
new[keyPath: keyPath()] = new[keyPath: keyPath()] ?? old[keyPath: keyPath()]
return new
}
}
Expand All @@ -49,21 +52,27 @@ public extension MergeStrategy {
}

public extension MergeStrategy {
static func append<Entity, Value>(_ keyPath: WritableKeyPath<Entity, [Value]>) -> MergeStrategy<Entity> {
static func append<Entity, Value>(
_ keyPath: @Sendable @escaping @autoclosure () -> WritableKeyPath<Entity, [Value]>
) -> MergeStrategy<Entity> {

MergeStrategy<Entity> { old, new in
var new = new
new[keyPath: keyPath] = [old[keyPath: keyPath], new[keyPath: keyPath]].flatMap { $0 }
new[keyPath: keyPath()] = [old[keyPath: keyPath()], new[keyPath: keyPath()]].flatMap { $0 }
return new
}
}

static func append<Entity, Value>(_ keyPath: WritableKeyPath<Entity, [Value]?>) -> MergeStrategy<Entity> {
static func append<Entity, Value>(
_ keyPath: @Sendable @escaping @autoclosure () -> WritableKeyPath<Entity, [Value]?>
) -> MergeStrategy<Entity> {

MergeStrategy<Entity> { old, new in
var new = new
let result = [old[keyPath: keyPath], new[keyPath: keyPath]]
let result = [old[keyPath: keyPath()], new[keyPath: keyPath()]]
.compactMap { $0 }
.flatMap { $0 }
new[keyPath: keyPath] = result.isEmpty ? nil : result
new[keyPath: keyPath()] = result.isEmpty ? nil : result
return new
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftletModel/Relationship/DecodingStrategy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

public struct RelationDecodingStrategy: OptionSet {
public struct RelationDecodingStrategy: OptionSet, Sendable {
public let rawValue: UInt

public init(rawValue: UInt) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftletModel/Relationship/EncodingStrategy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

public enum RelationEncodingStrategy {
public enum RelationEncodingStrategy: Sendable {
case plain
case keyedContainer
case explicitKeyedContainer
Expand Down
6 changes: 6 additions & 0 deletions Sources/SwiftletModel/Relationship/Relation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ extension Relation {

extension Relation.State: Codable where T: Codable { }

// MARK: - Sendable

extension Relation: Sendable where Entity: Sendable, Entity.ID: Sendable { }

extension Relation.State: Sendable where T: Sendable, T.ID: Sendable { }

// MARK: - Private State

extension Relation {
Expand Down
5 changes: 5 additions & 0 deletions Sources/SwiftletModel/Relationship/Relationship.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,8 @@ extension Relationship: Codable where Value: Codable, Entity: Codable {
try relation = .init(from: decoder)
}
}

// MARK: - Sendable

extension Relationship: Sendable where Entity: Sendable, Entity.ID: Sendable { }

2 changes: 1 addition & 1 deletion Tests/SwiftletModelTests/Models/Attachment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extension Attachment {
}

@EntityModel
struct Attachment: Codable {
struct Attachment: Codable, Sendable {
let id: String
var kind: Kind

Expand Down
2 changes: 1 addition & 1 deletion Tests/SwiftletModelTests/Models/Chat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

@EntityModel
struct Chat: Codable {
struct Chat: Codable, Sendable {
let id: String

@Relationship(inverse: \.chats)
Expand Down
2 changes: 1 addition & 1 deletion Tests/SwiftletModelTests/Models/Message.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

@EntityModel
struct Message: Codable {
struct Message: Codable, Sendable {
let id: String
let text: String

Expand Down
4 changes: 2 additions & 2 deletions Tests/SwiftletModelTests/Models/User.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

@EntityModel
struct CurrentUser: Codable {
struct CurrentUser: Codable, Sendable {
static let id: String = "current"

var id: String = CurrentUser.id
Expand All @@ -32,7 +32,7 @@ extension User {
}

@EntityModel
struct User: Codable {
struct User: Codable, Sendable {
let id: String
private(set) var name: String?
private(set) var avatar: Avatar?
Expand Down

0 comments on commit b078d58

Please sign in to comment.