Skip to content

Commit

Permalink
WIP, probably not working :)
Browse files Browse the repository at this point in the history
  • Loading branch information
JosephDuffy committed Mar 23, 2024
1 parent 4143320 commit 4897ae3
Show file tree
Hide file tree
Showing 4 changed files with 399 additions and 26 deletions.
108 changes: 103 additions & 5 deletions Sources/Persist/PersistMacro.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,59 @@
@attached(peer, names: suffixed(_storage), suffixed(_cache))
@attached(accessor)
public macro Persist<Key>(key: Key, storage: any Storage<Key>, cacheValue: Bool = false) = #externalMacro(module: "PersistMacros", type: "Persist")
public macro Persist<Key>(
key: Key,
storage: any Storage<Key>,
cacheValue: Bool = false
) = #externalMacro(module: "PersistMacros", type: "Persist_Storage_NoTransformer")

@attached(peer, names: suffixed(_storage), suffixed(_cache))
@attached(peer, names: suffixed(_cache))
@attached(accessor)
public macro Persist<Key, Root, Storage: Persist.Storage<Key>>(key: Key, storage: KeyPath<Root, Storage>, cacheValue: Bool = false) = #externalMacro(module: "PersistMacros", type: "Persist")
public macro Persist<Key, Root, Storage: Persist.Storage<Key>>(
key: Key,
storage: KeyPath<Root, Storage>,
cacheValue: Bool = false
) = #externalMacro(module: "PersistMacros", type: "Persist_Storage_NoTransformer")

@attached(peer, names: suffixed(_storage), suffixed(_cache))
@attached(accessor)
public macro Persist<Key>(key: Key, storage: any MutatingStorage<Key>, cacheValue: Bool = false) = #externalMacro(module: "PersistMacros", type: "Persist_Mutating")
public macro Persist<Key>(
key: Key,
storage: any MutatingStorage<Key>,
cacheValue: Bool = false
) = #externalMacro(module: "PersistMacros", type: "Persist_MutatingStorage_NoTransformer")

@attached(peer, names: suffixed(_cache))
@attached(accessor)
public macro Persist<Key, Root, MutatingStorage: Persist.MutatingStorage<Key>>(
key: Key,
storage: KeyPath<Root, MutatingStorage>,
cacheValue: Bool = false
) = #externalMacro(module: "PersistMacros", type: "Persist_MutatingStorage_NoTransformer")

@attached(peer, names: suffixed(_storage), suffixed(_cache))
@attached(accessor)
public macro Persist<Key, Root, MutatingStorage: Persist.MutatingStorage<Key>>(key: Key, storage: KeyPath<Root, MutatingStorage>, cacheValue: Bool = false) = #externalMacro(module: "PersistMacros", type: "Persist_Mutating")
public macro Persist<Key>(
key: Key,
storage: any ThrowingStorage<Key>,
cacheValue: Bool = false
) = #externalMacro(module: "PersistMacros", type: "Persist_ThrowingStorage_NoTransformer")

@attached(peer, names: suffixed(_cache))
@attached(accessor)
public macro Persist<Key, Root, ThrowingStorage: Persist.ThrowingStorage<Key>>(
key: Key,
storage: KeyPath<Root, ThrowingStorage>,
cacheValue: Bool = false
) = #externalMacro(module: "PersistMacros", type: "Persist_ThrowingStorage_NoTransformer")

@attached(peer, names: suffixed(_storage), suffixed(_cache), suffixed(_transformer))
@attached(accessor)
public macro Persist<Key, Input, Output>(
key: Key,
storage: any Storage<Key>,
transformer: any ThrowingTransformer<Input, Output>,
cacheValue: Bool = false
) = #externalMacro(module: "PersistMacros", type: "Persist_Storage_ThrowingTransformer")

import Foundation

Expand Down Expand Up @@ -138,3 +179,60 @@ public protocol ThrowingStorage<Key> {

func removeValue(forKey key: Key) throws
}

public protocol MutatingThrowingStorage<Key> {
/// The type of the key used to store values.
associatedtype Key

func getValue<Value>(forKey key: Key) throws -> Value?

mutating func setValue<Value>(_ value: Value, forKey key: Key) throws

mutating func removeValue(forKey key: Key) throws
}

public protocol Transformer<Input, Output> {
associatedtype Input
associatedtype Output

func transformInput<Input>(_ input: Input) -> Output

func transformOutput<Output>(_ output: Output) -> Input
}

public protocol ThrowingTransformer<Input, Output> {
associatedtype Input
associatedtype Output

func transformInput(_ input: Input) throws -> Output

func transformOutput(_ output: Output) throws -> Input
}

public struct JSONTransformer<Input: Codable>: ThrowingTransformer, Sendable {
public typealias ConfigureEncoder = @Sendable (_ encoder: JSONEncoder) -> Void
public typealias ConfigureDecoder = @Sendable (_ encoder: JSONDecoder) -> Void

private let configureEncoder: ConfigureEncoder?
private let configureDecoder: ConfigureDecoder?

public init(
configureEncoder: ConfigureEncoder? = nil,
configureDecoder: ConfigureDecoder? = nil
) {
self.configureEncoder = configureEncoder
self.configureDecoder = configureDecoder
}

public func transformInput(_ input: Input) throws -> Data {
let encoder = JSONEncoder()
configureEncoder?(encoder)
return try encoder.encode(input)
}

public func transformOutput(_ data: Data) throws -> Input {
let decoder = JSONDecoder()
configureDecoder?(decoder)
return try decoder.decode(Input.self, from: data)
}
}
Loading

0 comments on commit 4897ae3

Please sign in to comment.