Skip to content

Commit

Permalink
Feature/extensions (#4)
Browse files Browse the repository at this point in the history
* Add dictionary extensions and Cacheable

* Ignore .swiftpm
  • Loading branch information
0xLeif authored Jun 10, 2023
1 parent a1ad092 commit 538f770
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 247 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.swiftpm/
.netrc
24 changes: 0 additions & 24 deletions .swiftpm/Cache.xctestplan

This file was deleted.

This file was deleted.

66 changes: 0 additions & 66 deletions .swiftpm/xcode/xcshareddata/xcschemes/Cache-Package.xcscheme

This file was deleted.

97 changes: 0 additions & 97 deletions .swiftpm/xcode/xcshareddata/xcschemes/Cache.xcscheme

This file was deleted.

23 changes: 0 additions & 23 deletions Sources/Cache/Cache/Cache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,6 @@ open class Cache<Key: Hashable, Value>: Cacheable, ObservableObject {
return cache.get(key, as: Output.self)
}

/**
Gets a value from the cache for a given key.

- Parameters:
- key: The key to retrieve the value for.
- Returns: The value stored in cache for the given key, or `nil` if it doesn't exist.
*/
open func get(_ key: Key) -> Value? {
get(key, as: Value.self)
}

/**
Resolves a value from the cache for a given key.

Expand All @@ -81,18 +70,6 @@ open class Cache<Key: Hashable, Value>: Cacheable, ObservableObject {
return value
}

/**
Resolves a value from the cache for a given key.

- Parameters:
- key: The key to retrieve the value for.
- Returns: The value stored in cache for the given key.
- Throws: `MissingRequiredKeysError` if the key is missing, or `InvalidTypeError` if the value type is not compatible with the expected type.
*/
open func resolve(_ key: Key) throws -> Value {
try resolve(key, as: Value.self)
}

/**
Sets a value in the cache for a given key.

Expand Down
18 changes: 8 additions & 10 deletions Sources/Cache/Cache/ExpiringCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,14 @@ public class ExpiringCache<Key: Hashable, Value>: Cacheable {
duration: ExpirationDuration,
initialValues: [Key: Value] = [:]
) {
var initialExpirationValues: [Key: ExpiringValue] = [:]

initialValues.forEach { key, value in
initialExpirationValues[key] = ExpiringValue(
expriation: Date().addingTimeInterval(duration.timeInterval),
value: value
)
}

self.cache = Cache(initialValues: initialExpirationValues)
self.cache = Cache(
initialValues: initialValues.mapValues { value in
ExpiringValue(
expriation: Date().addingTimeInterval(duration.timeInterval),
value: value
)
}
)
self.duration = duration
}

Expand Down
23 changes: 23 additions & 0 deletions Sources/Cache/Cacheable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,27 @@ public extension Cacheable {
var allValues: [Key: Value] {
values(ofType: Value.self)
}

/**
Gets a value from the cache for a given key.

- Parameters:
- key: The key to retrieve the value for.
- Returns: The value stored in cache for the given key, or `nil` if it doesn't exist.
*/
func get(_ key: Key) -> Value? {
get(key, as: Value.self)
}

/**
Resolves a value from the cache for a given key.

- Parameters:
- key: The key to retrieve the value for.
- Returns: The value stored in cache for the given key.
- Throws: `MissingRequiredKeysError` if the key is missing, or `InvalidTypeError` if the value type is not compatible with the expected type.
*/
func resolve(_ key: Key) throws -> Value {
try resolve(key, as: Value.self)
}
}
36 changes: 36 additions & 0 deletions Sources/Cache/Dictionary/Dictionary+Cacheable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,40 @@ extension Dictionary: Cacheable {
) -> [Key: Item] {
compactMapValues { $0 as? Item }
}

/**
Returns a new dictionary containing the keys and values resulting from applying the given transformation to each element in the original dictionary.

- Parameters:
- transform: A closure that takes a key-value pair from the dictionary as its argument and returns a tuple containing a new key and a new value. The returned tuple must have two elements of the same type as the expected output for this method.

- Returns: A new dictionary containing the transformed keys and values.
*/
public func mapDictionary<NewKey: Hashable, NewValue>(
_ transform: (Key, Value) -> (NewKey, NewValue)
) -> [NewKey: NewValue] {
compactMapDictionary(transform)
}

/**
Returns a new dictionary containing only the key-value pairs that have non-nil values resulting from applying the given transformation to each element in the original dictionary.

- Parameters:
- transform: A closure that takes a key-value pair from the dictionary as its argument and returns an optional tuple containing a new key and a new value. Each non-nil key-value pair will be included in the returned dictionary.

- Returns: A new dictionary containing the non-nil transformed keys and values.
*/
public func compactMapDictionary<NewKey: Hashable, NewValue>(
_ transform: (Key, Value) -> (NewKey, NewValue)?
) -> [NewKey: NewValue] {
var dictionary: [NewKey: NewValue] = [:]

for (key, value) in self {
if let (newKey, newValue) = transform(key, value) {
dictionary[newKey] = newValue
}
}

return dictionary
}
}
30 changes: 13 additions & 17 deletions Sources/Cache/JSON/JSON.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,10 @@ public struct JSON<Key: RawRepresentable & Hashable>: Cacheable where Key.RawVal
///
/// - Throws: Errors are from `JSONSerialization.data(withJSONObject:)`
public func data() throws -> Data {
var stringKeyedValues: [String: Any] = [:]

for (key, value) in allValues {
stringKeyedValues[key.rawValue] = value
}

return try JSONSerialization.data(
withJSONObject: stringKeyedValues
try JSONSerialization.data(
withJSONObject: allValues.mapDictionary { key, value in
(key.rawValue, value)
}
)
}

Expand All @@ -104,15 +100,15 @@ public struct JSON<Key: RawRepresentable & Hashable>: Cacheable where Key.RawVal
if let data = value as? Data {
jsonDictionary = JSON<JSONKey>(data: data)
} else if let dictionary = value as? [String: Any] {
var initialValues: [JSONKey: Any] = [:]

dictionary.forEach { jsonKey, jsonValue in
guard let key = JSONKey(rawValue: jsonKey) else { return }

initialValues[key] = jsonValue
}

jsonDictionary = JSON<JSONKey>(initialValues: initialValues)
jsonDictionary = JSON<JSONKey>(
initialValues: dictionary.compactMapDictionary { key, value in
guard let key = JSONKey(rawValue: key) else {
return nil
}

return (key, value)
}
)
} else if let dictionary = value as? [JSONKey: Any] {
jsonDictionary = JSON<JSONKey>(initialValues: dictionary)
} else if let json = value as? JSON<JSONKey> {
Expand Down

0 comments on commit 538f770

Please sign in to comment.