Skip to content

Commit cf3404a

Browse files
authored
Merge pull request #2 from SwiftRex/FileLogger
Add file logger
2 parents 6fdad87 + 88738ac commit cf3404a

File tree

1 file changed

+114
-43
lines changed

1 file changed

+114
-43
lines changed

Sources/LoggerMiddleware/LoggerMiddleware.swift

Lines changed: 114 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,10 @@ import SwiftRex
44

55
extension Middleware where StateType: Equatable {
66
public func logger(
7-
actionTransform: @escaping (InputActionType, ActionSource) -> String = {
8-
"\n🕹 \($0)\n🎪 \($1.file.split(separator: "/").last ?? ""):\($1.line) \($1.function)"
9-
},
10-
actionPrinter: @escaping (String) -> Void = { os_log(.debug, log: .default, "%{PUBLIC}@", $0) },
11-
stateDiffTransform: @escaping (StateType?, StateType) -> String? = {
12-
let stateBefore = dumpToString($0)
13-
let stateAfter = dumpToString($1)
14-
return Difference.diff(old: stateBefore, new: stateAfter, linesOfContext: 2, prefixLines: "🏛 ")
15-
},
16-
stateDiffPrinter: @escaping (String?) -> Void = { state in
17-
if let state = state {
18-
os_log(.debug, log: .default, "%{PUBLIC}@", state)
19-
} else {
20-
os_log(.debug, log: .default, "%{PUBLIC}@", "🏛 No state mutation")
21-
}
22-
},
7+
actionTransform: LoggerMiddleware<Self>.ActionTransform = .default(),
8+
actionPrinter: LoggerMiddleware<Self>.ActionLogger = .osLog,
9+
stateDiffTransform: LoggerMiddleware<Self>.StateDiffTransform = .diff(),
10+
stateDiffPrinter: LoggerMiddleware<Self>.StateLogger = .osLog,
2311
queue: DispatchQueue = .main
2412
) -> LoggerMiddleware<Self> {
2513
LoggerMiddleware(
@@ -40,17 +28,17 @@ public final class LoggerMiddleware<M: Middleware>: Middleware where M.StateType
4028
private let middleware: M
4129
private let queue: DispatchQueue
4230
private var getState: GetState<StateType>?
43-
private let actionTransform: (InputActionType, ActionSource) -> String
44-
private let actionPrinter: (String) -> Void
45-
private let stateDiffTransform: (StateType?, StateType) -> String?
46-
private let stateDiffPrinter: (String?) -> Void
31+
private let actionTransform: ActionTransform
32+
private let actionPrinter: ActionLogger
33+
private let stateDiffTransform: StateDiffTransform
34+
private let stateDiffPrinter: StateLogger
4735

4836
init(
4937
_ middleware: M,
50-
actionTransform: @escaping (InputActionType, ActionSource) -> String,
51-
actionPrinter: @escaping (String) -> Void,
52-
stateDiffTransform: @escaping (StateType?, StateType) -> String?,
53-
stateDiffPrinter: @escaping (String?) -> Void,
38+
actionTransform: ActionTransform,
39+
actionPrinter: ActionLogger,
40+
stateDiffTransform: StateDiffTransform,
41+
stateDiffPrinter: StateLogger,
5442
queue: DispatchQueue
5543
) {
5644
self.middleware = middleware
@@ -77,32 +65,20 @@ public final class LoggerMiddleware<M: Middleware>: Middleware where M.StateType
7765
let stateAfter = self.getState?() else { return }
7866

7967
self.queue.async {
80-
let actionMessage = self.actionTransform(action, dispatcher)
81-
self.actionPrinter(actionMessage)
82-
self.stateDiffPrinter(self.stateDiffTransform(stateBefore, stateAfter))
68+
let actionMessage = self.actionTransform.transform(action: action, source: dispatcher)
69+
self.actionPrinter.log(action: actionMessage)
70+
self.stateDiffPrinter.log(state: self.stateDiffTransform.transform(oldState: stateBefore, newState: stateAfter))
8371
}
8472
}
8573
}
8674
}
8775

8876
extension LoggerMiddleware {
8977
public static func `default`(
90-
actionTransform: @escaping (InputActionType, ActionSource) -> String = {
91-
"\n🕹 \($0)\n🎪 \($1.file.split(separator: "/").last ?? ""):\($1.line) \($1.function)"
92-
},
93-
actionPrinter: @escaping (String) -> Void = { os_log(.debug, log: .default, "%{PUBLIC}@", $0) },
94-
stateDiffTransform: @escaping (StateType?, StateType) -> String? = {
95-
let stateBefore = dumpToString($0)
96-
let stateAfter = dumpToString($1)
97-
return Difference.diff(old: stateBefore, new: stateAfter, linesOfContext: 2, prefixLines: "🏛 ")
98-
},
99-
stateDiffPrinter: @escaping (String?) -> Void = { state in
100-
if let state = state {
101-
os_log(.debug, log: .default, "%{PUBLIC}@", state)
102-
} else {
103-
os_log(.debug, log: .default, "%{PUBLIC}@", "🏛 No state mutation")
104-
}
105-
},
78+
actionTransform: LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>>.ActionTransform = .default(),
79+
actionPrinter: LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>>.ActionLogger = .osLog,
80+
stateDiffTransform: LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>>.StateDiffTransform = .diff(),
81+
stateDiffPrinter: LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>>.StateLogger = .osLog,
10682
queue: DispatchQueue = .main
10783
) -> LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>> {
10884
.init(
@@ -115,3 +91,98 @@ extension LoggerMiddleware {
11591
)
11692
}
11793
}
94+
95+
// MARK: - State
96+
// MARK: State Logger
97+
extension LoggerMiddleware {
98+
public enum StateLogger {
99+
case osLog
100+
case file(URL)
101+
case custom((String) -> Void)
102+
103+
func log(state: String) {
104+
switch self {
105+
case .osLog: LoggerMiddleware.osLog(state: state)
106+
case let .file(url): LoggerMiddleware.fileLog(state: state, to: url)
107+
case let .custom(closure): closure(state)
108+
}
109+
}
110+
}
111+
112+
private static func osLog(state: String) {
113+
os_log(.debug, log: .default, "%{PUBLIC}@", state)
114+
}
115+
116+
private static func fileLog(state: String, to fileURL: URL) {
117+
try? state.write(toFile: fileURL.absoluteString, atomically: false, encoding: .utf8)
118+
}
119+
}
120+
121+
// MARK: State Diff Transform
122+
extension LoggerMiddleware {
123+
public enum StateDiffTransform {
124+
case diff(linesOfContext: Int = 2, prefixLines: String = "🏛 ")
125+
case newStateOnly
126+
case custom((StateType?, StateType) -> String)
127+
128+
func transform(oldState: StateType?, newState: StateType) -> String {
129+
switch self {
130+
case let .diff(linesOfContext, prefixLines):
131+
let stateBefore = dumpToString(oldState)
132+
let stateAfter = dumpToString(newState)
133+
return Difference.diff(old: stateBefore, new: stateAfter, linesOfContext: linesOfContext, prefixLines: prefixLines)
134+
?? "\(prefixLines) No state mutation"
135+
case .newStateOnly:
136+
return dumpToString(newState)
137+
case let .custom(closure):
138+
return closure(oldState, newState)
139+
}
140+
}
141+
}
142+
}
143+
144+
// MARK: - Action
145+
// MARK: Action Logger
146+
extension LoggerMiddleware {
147+
public enum ActionLogger {
148+
case osLog
149+
case file(URL)
150+
case custom((String) -> Void)
151+
152+
func log(action: String) {
153+
switch self {
154+
case .osLog: LoggerMiddleware.osLog(action: action)
155+
case let .file(url): LoggerMiddleware.fileLog(action: action, to: url)
156+
case let .custom(closure): closure(action)
157+
}
158+
}
159+
}
160+
161+
private static func osLog(action: String) {
162+
os_log(.debug, log: .default, "%{PUBLIC}@", action)
163+
}
164+
165+
private static func fileLog(action: String, to fileURL: URL) -> Void {
166+
try? action.write(toFile: fileURL.absoluteString, atomically: false, encoding: .utf8)
167+
}
168+
}
169+
170+
// MARK: Action Transform
171+
extension LoggerMiddleware {
172+
public enum ActionTransform {
173+
case `default`(actionPrefix: String = "\n🕹 ", sourcePrefix: String = "\n🎪 ")
174+
case actionNameOnly
175+
case custom((InputActionType, ActionSource) -> String)
176+
177+
func transform(action: InputActionType, source: ActionSource) -> String {
178+
switch self {
179+
case let .default(actionPrefix, sourcePrefix):
180+
return "\(actionPrefix)\(action)\(sourcePrefix)\(source.file.split(separator: "/").last ?? ""):\(source.line) \(source.function)"
181+
case .actionNameOnly:
182+
return "\(action)"
183+
case let .custom(closure):
184+
return closure(action, source)
185+
}
186+
}
187+
}
188+
}

0 commit comments

Comments
 (0)