LottieLogger.swift 4.0 KB
Newer Older
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
// Created by eric_horacek on 12/9/20.
// Copyright © 2020 Airbnb Inc. All rights reserved.

// MARK: - LottieLogger

/// A shared logger that allows consumers to intercept Lottie assertions and warning messages to pipe
/// into their own logging systems.
public final class LottieLogger {

  // MARK: Lifecycle

  public init(
    assert: @escaping Assert = { condition, message, file, line in
      // If we default to `Swift.assert` directly with `assert: Assert = Swift.assert`,
      // the call will unexpectedly not respect the -O flag and will crash in release
      // https://github.com/apple/swift/issues/60249
      Swift.assert(condition(), message(), file: file, line: line)
    },
    assertionFailure: @escaping AssertionFailure = { message, file, line in
      // If we default to `Swift.assertionFailure` directly with
      // `assertionFailure: AssertionFailure = Swift.assertionFailure`,
      // the call will unexpectedly not respect the -O flag and will crash in release
      // https://github.com/apple/swift/issues/60249
      Swift.assertionFailure(message(), file: file, line: line)
    },
    warn: @escaping Warn = { message, _, _ in
      #if DEBUG
      // swiftlint:disable:next no_direct_standard_out_logs
      print(message())
      #endif
    },
    info: @escaping Info = { message in
      #if DEBUG
      // swiftlint:disable:next no_direct_standard_out_logs
      print(message())
      #endif
    })
  {
    _assert = assert
    _assertionFailure = assertionFailure
    _warn = warn
    _info = info
  }

  // MARK: Public

  /// Logs that an assertion occurred.
  public typealias Assert = (
    _ condition: @autoclosure () -> Bool,
    _ message: @autoclosure () -> String,
    _ fileID: StaticString,
    _ line: UInt)
    -> Void

  /// Logs that an assertion failure occurred.
  public typealias AssertionFailure = (
    _ message: @autoclosure () -> String,
    _ fileID: StaticString,
    _ line: UInt)
    -> Void

  /// Logs a warning message.
  public typealias Warn = (
    _ message: @autoclosure () -> String,
    _ fileID: StaticString,
    _ line: UInt)
    -> Void

  /// Prints a purely informational message.
  public typealias Info = (_ message: @autoclosure () -> String) -> Void

  /// The shared instance used to log Lottie assertions and warnings.
  ///
  /// Set this to a new logger instance to intercept assertions and warnings logged by Lottie.
  public static var shared = LottieLogger()

  /// Logs that an assertion occurred.
  public func assert(
    _ condition: @autoclosure () -> Bool,
    _ message: @autoclosure () -> String = String(),
    fileID: StaticString = #fileID,
    line: UInt = #line)
  {
    _assert(condition(), message(), fileID, line)
  }

  /// Logs that an assertion failure occurred.
  public func assertionFailure(
    _ message: @autoclosure () -> String = String(),
    fileID: StaticString = #fileID,
    line: UInt = #line)
  {
    _assertionFailure(message(), fileID, line)
  }

  /// Logs a warning message.
  public func warn(
    _ message: @autoclosure () -> String = String(),
    fileID: StaticString = #fileID,
    line: UInt = #line)
  {
    _warn(message(), fileID, line)
  }

  /// Logs a purely informational message.
  public func info(_ message: @autoclosure () -> String = String()) {
    _info(message())
  }

  // MARK: Private

  private let _assert: Assert
  private let _assertionFailure: AssertionFailure
  private let _warn: Warn
  private let _info: Info

}

// MARK: - LottieLogger + printToConsole

extension LottieLogger {
  /// A `LottieLogger` instance that always prints to the console (by calling `print`)
  /// instead of calling `assert` / `assertionFailure`, which halt execution in debug builds.
  public static var printToConsole: LottieLogger {
    LottieLogger(
      assert: { condition, message, _, _ in
        if !condition() {
          // swiftlint:disable:next no_direct_standard_out_logs
          print(message())
        }
      },
      assertionFailure: { message, _, _ in
        // swiftlint:disable:next no_direct_standard_out_logs
        print(message())
      })
  }
}