-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFilterable.swift
More file actions
61 lines (49 loc) · 1.73 KB
/
Filterable.swift
File metadata and controls
61 lines (49 loc) · 1.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//
// Filterable.swift
//
//
// Copyright © 2022 Unlock Agency. All rights reserved.
//
import Foundation
public protocol Unknownable {
var isUnknown: Bool { get }
}
public protocol FilterStrategy: Sendable {
associatedtype Value: Codable & Sendable
static func filter(_ element: Value) -> Bool
}
public struct UnknownEnumFilterableStrategy<T>: FilterStrategy where T: UnknownableEnum & Codable & Sendable, T.RawValue == String {
public static func filter(_ element: T) -> Bool {
return element != T.unknown
}
}
public typealias UnknownEnumFilterable<T> = Filterable<UnknownEnumFilterableStrategy<T>> where T: UnknownableEnum & Codable, T.RawValue == String
public struct UnknownFilterableStrategy<T>: FilterStrategy where T: Unknownable & Codable & Sendable {
public static func filter(_ element: T) -> Bool {
return !element.isUnknown
}
}
public typealias UnknownFilterable<T> = Filterable<UnknownFilterableStrategy<T>> where T: Unknownable & Codable & Sendable
@propertyWrapper
public struct Filterable<Strategy: FilterStrategy>: Codable, Sendable {
private(set) var value: [Strategy.Value]
public var wrappedValue: [Strategy.Value] {
get {
value.filter { Strategy.filter($0) }
}
set {
value = newValue
}
}
public init(wrappedValue: [Strategy.Value]) {
self.value = wrappedValue
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
value = try container.decode([Strategy.Value].self)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(wrappedValue)
}
}