@@ -103,26 +103,21 @@ extension LoggerMiddleware {
103
103
// MARK: State Logger
104
104
extension LoggerMiddleware {
105
105
public enum StateLogger {
106
+ /// Logs using os_log.
106
107
case osLog
107
- case file( URL )
108
+ /// Appends the messages to a file. The file must exist!
109
+ case file( FileAppender )
110
+ /// A custom handler.
108
111
case custom( ( String ) -> Void )
109
112
110
113
func log( state: String ) {
111
114
switch self {
112
- case . osLog: LoggerMiddleware . osLog ( state: state )
113
- case let . file( url ) : LoggerMiddleware . fileLog ( state: state , to : url )
115
+ case . osLog: LoggerMiddleware . osLog ( state)
116
+ case let . file( fileAppender ) : fileAppender . write ( state)
114
117
case let . custom( closure) : closure ( state)
115
118
}
116
119
}
117
120
}
118
-
119
- private static func osLog( state: String ) {
120
- os_log ( . debug, log: . default, " %{PUBLIC}@ " , state)
121
- }
122
-
123
- private static func fileLog( state: String , to fileURL: URL ) {
124
- try ? state. write ( toFile: fileURL. absoluteString, atomically: false , encoding: String . Encoding. utf8)
125
- }
126
121
}
127
122
128
123
// MARK: State Diff Transform
@@ -243,32 +238,27 @@ extension LoggerMiddleware {
243
238
// MARK: Action Logger
244
239
extension LoggerMiddleware {
245
240
public enum ActionLogger {
241
+ /// Logs using os_log.
246
242
case osLog
247
- case file( URL )
243
+ /// Appends the messages to a file. The file must exist!
244
+ case file( FileAppender )
245
+ /// A custom handler.
248
246
case custom( ( String ) -> Void )
249
247
250
248
func log( action: String ) {
251
249
switch self {
252
- case . osLog: LoggerMiddleware . osLog ( action: action )
253
- case let . file( url ) : LoggerMiddleware . fileLog ( action: action , to : url )
250
+ case . osLog: LoggerMiddleware . osLog ( action)
251
+ case let . file( fileappender ) : fileappender . write ( action)
254
252
case let . custom( closure) : closure ( action)
255
253
}
256
254
}
257
255
}
258
-
259
- private static func osLog( action: String ) {
260
- os_log ( . debug, log: . default, " %{PUBLIC}@ " , action)
261
- }
262
-
263
- private static func fileLog( action: String , to fileURL: URL ) -> Void {
264
- try ? action. write ( toFile: fileURL. absoluteString, atomically: false , encoding: . utf8)
265
- }
266
256
}
267
257
268
258
// MARK: Action Transform
269
259
extension LoggerMiddleware {
270
260
public enum ActionTransform {
271
- case `default`( actionPrefix: String = " \n 🕹 " , sourcePrefix: String = " \n 🎪 " )
261
+ case `default`( actionPrefix: String = " 🕹 " , sourcePrefix: String = " 🎪 " )
272
262
case actionNameOnly
273
263
case custom( ( InputActionType , ActionSource ) -> String )
274
264
@@ -284,3 +274,49 @@ extension LoggerMiddleware {
284
274
}
285
275
}
286
276
}
277
+
278
+ // MARK: Log output
279
+
280
+ extension LoggerMiddleware {
281
+
282
+ fileprivate static func osLog( _ message: String ) {
283
+ os_log ( . debug, log: . default, " %{PUBLIC}@ " , message)
284
+ }
285
+
286
+ }
287
+
288
+ public struct FileAppender {
289
+ private let url : URL
290
+ private let date : ( ) -> Date
291
+ private let dateFormatter : DateFormatter
292
+ private let writer : ( URL , Data ) -> Void
293
+
294
+ public init ( url: URL , date: @escaping ( ) -> Date , dateFormatter: DateFormatter , writer: @escaping ( URL , Data ) -> Void ) {
295
+ self . url = url
296
+ self . date = date
297
+ self . dateFormatter = dateFormatter
298
+ self . writer = writer
299
+ }
300
+
301
+ public func write( _ message: String ) {
302
+ guard let data = ( dateFormatter. string ( from: date ( ) ) + " " + message + " \n " ) . data ( using: String . Encoding. utf8) else { return }
303
+ writer ( url, data)
304
+ }
305
+ }
306
+
307
+ extension FileAppender {
308
+ public static func live( url: URL , dateFormatter: DateFormatter = . init( ) , date: @escaping ( ) -> Date = Date . init, fileHandle: @escaping ( URL ) throws -> FileHandle = FileHandle . init ( forUpdating: ) ) -> FileAppender {
309
+ FileAppender (
310
+ url: url,
311
+ date: date,
312
+ dateFormatter: dateFormatter,
313
+ writer: { url, data in
314
+ guard let fileUpdater = try ? fileHandle ( url) else { return }
315
+ fileUpdater. seekToEndOfFile ( )
316
+ fileUpdater. write ( data)
317
+ fileUpdater. closeFile ( )
318
+ }
319
+ )
320
+ }
321
+ }
322
+
0 commit comments