14
14
15
15
/// Associates cache control values with filename
16
16
public struct CacheControl : Sendable {
17
+ /// Cache control directive
18
+ ///
19
+ /// Original CacheControl directive value was a fixed enum. This has been replaced
20
+ /// with CacheControl.CacheControlValue which is more extensible
21
+ @_documentation ( visibility: internal)
17
22
public enum Value : CustomStringConvertible , Sendable {
18
23
case noStore
19
24
case noCache
@@ -38,12 +43,118 @@ public struct CacheControl: Sendable {
38
43
return " must-revalidate "
39
44
}
40
45
}
46
+
47
+ var cacheControlValue : CacheControlValue {
48
+ switch self {
49
+ case . noStore: . noStore
50
+ case . noCache: . noCache
51
+ case . private: . private
52
+ case . public: . public
53
+ case . maxAge( let value) : . maxAge( value)
54
+ case . mustRevalidate: . mustRevalidate
55
+ }
56
+ }
57
+ }
58
+
59
+ /// Cache control directive
60
+ public struct CacheControlValue : CustomStringConvertible , Sendable {
61
+ private enum Value : CustomStringConvertible , Sendable {
62
+ case noStore
63
+ case noCache
64
+ case `private`
65
+ case `public`
66
+ case maxAge( Int )
67
+ case mustRevalidate
68
+ case mustUnderstand
69
+ case noTransform
70
+ case immutable
71
+ case custom( String )
72
+
73
+ public var description : String {
74
+ switch self {
75
+ case . noStore:
76
+ return " no-store "
77
+ case . noCache:
78
+ return " no-cache "
79
+ case . private:
80
+ return " private "
81
+ case . public:
82
+ return " public "
83
+ case . maxAge( let amount) :
84
+ return " max-age= \( amount) "
85
+ case . mustRevalidate:
86
+ return " must-revalidate "
87
+ case . mustUnderstand:
88
+ return " must-understand "
89
+ case . noTransform:
90
+ return " no-transform "
91
+ case . immutable:
92
+ return " immutable "
93
+ case . custom( let string) :
94
+ return string
95
+ }
96
+ }
97
+ }
98
+ private let value : Value
99
+
100
+ /// The no-store response directive indicates that any caches of any kind (private or shared) should not
101
+ /// store this response.
102
+ public static var noStore : Self { . init( value: . noStore) }
103
+ /// The no-cache response directive indicates that the response can be stored in caches, but the response
104
+ /// must be validated with the origin server before each reuse, even when the cache is disconnected from
105
+ /// the origin server.
106
+ public static var noCache : Self { . init( value: . noCache) }
107
+ /// The private response directive indicates that the response can be stored only in a private cache (e.g.
108
+ /// local caches in browsers).
109
+ public static var `private` : Self { . init( value: . private) }
110
+ /// The public response directive indicates that the response can be stored in a shared cache. Responses
111
+ /// for requests with Authorization header fields must not be stored in a shared cache; however, the public
112
+ /// directive will cause such responses to be stored in a shared cache.
113
+ public static var `public` : Self { . init( value: . public) }
114
+ /// The max-age=N response directive indicates that the response remains fresh until N seconds after the
115
+ /// response is generated.
116
+ public static func maxAge( _ amount: Int ) -> Self { . init( value: . maxAge( amount) ) }
117
+ /// The must-revalidate response directive indicates that the response can be stored in caches and can be
118
+ /// reused while fresh. If the response becomes stale, it must be validated with the origin server before reuse.
119
+ public static var mustRevalidate : Self { . init( value: . mustRevalidate) }
120
+ /// The must-understand response directive indicates that a cache should store the response only if it
121
+ /// understands the requirements for caching based on status code.
122
+ public static var mustUnderstand : Self { . init( value: . mustUnderstand) }
123
+ /// Some intermediaries transform content for various reasons. For example, some convert images to reduce
124
+ /// transfer size. In some cases, this is undesirable for the content provider.
125
+ ///
126
+ /// no-transform indicates that any intermediary (regardless of whether it implements a cache) shouldn't transform
127
+ /// the response contents.
128
+ public static var noTransform : Self { . init( value: . noTransform) }
129
+ /// The immutable response directive indicates that the response will not be updated while it's fresh.
130
+ public static var immutable : Self { . init( value: . immutable) }
131
+ /// Custom directive
132
+ public static func custom( _ string: String ) -> Self { . init( value: . custom( string) ) }
133
+
134
+ public var description : String { value. description }
41
135
}
42
136
43
137
/// Initialize cache control
44
138
/// - Parameter entries: cache control entries
139
+ @_disfavoredOverload
45
140
public init ( _ entries: [ ( MediaType , [ Value ] ) ] ) {
46
- self . entries = entries. map { . init( mediaType: $0. 0 , cacheControl: $0. 1 ) }
141
+ self . entries = entries. map {
142
+ . init(
143
+ mediaType: $0. 0 ,
144
+ cacheControl: $0. 1 . map { $0. cacheControlValue }
145
+ )
146
+ }
147
+ }
148
+
149
+ /// Initialize cache control
150
+ /// - Parameter entries: cache control entries
151
+ public init ( _ entries: [ ( MediaType , [ CacheControlValue ] ) ] ) {
152
+ self . entries = entries. map {
153
+ . init(
154
+ mediaType: $0. 0 ,
155
+ cacheControl: $0. 1 . map { $0 }
156
+ )
157
+ }
47
158
}
48
159
49
160
/// Get the Cache-Control header for a file
@@ -62,7 +173,7 @@ public struct CacheControl: Sendable {
62
173
63
174
private struct Entry : Sendable {
64
175
let mediaType : MediaType
65
- let cacheControl : [ Value ]
176
+ let cacheControl : [ CacheControlValue ]
66
177
}
67
178
68
179
private let entries : [ Entry ]
0 commit comments