// ignore: import_of_legacy_library_into_null_safe import 'dart:ffi'; import 'package:ffi/ffi.dart' as ffi; import 'package:flutter/foundation.dart'; import 'package:logger/logger.dart'; import 'ffi.dart'; class Log { static final shared = Log(); // ignore: unused_field late Logger _logger; bool _enabled = false; // used to disable log in tests @visibleForTesting bool disableLog = false; Log() { _logger = Logger( printer: PrettyPrinter( methodCount: 2, // Number of method calls to be displayed errorMethodCount: 8, // Number of method calls if stacktrace is provided lineLength: 120, // Width of the output colors: true, // Colorful log messages printEmojis: true, // Print an emoji for each log message ), level: kDebugMode ? Level.trace : Level.info, ); } static void enableFlutterLog() { shared._enabled = true; } // Generic internal logging function to reduce code duplication static void _log(Level level, int rustLevel, dynamic msg, [dynamic error, StackTrace? stackTrace]) { if (shared._enabled) { switch (level) { case Level.info: shared._logger.i(msg, stackTrace: stackTrace); break; case Level.debug: shared._logger.d(msg, stackTrace: stackTrace); break; case Level.warning: shared._logger.w(msg, stackTrace: stackTrace); break; case Level.error: shared._logger.e(msg, stackTrace: stackTrace); break; case Level.trace: shared._logger.t(msg, stackTrace: stackTrace); break; default: shared._logger.log(level, msg, stackTrace: stackTrace); } } String formattedMessage = _formatMessageWithStackTrace(msg, stackTrace); rust_log(rustLevel, toNativeUtf8(formattedMessage)); } static void info(dynamic msg, [dynamic error, StackTrace? stackTrace]) { if (shared.disableLog) { return; } _log(Level.info, 0, msg, error, stackTrace); } static void debug(dynamic msg, [dynamic error, StackTrace? stackTrace]) { if (shared.disableLog) { return; } _log(Level.debug, 1, msg, error, stackTrace); } static void warn(dynamic msg, [dynamic error, StackTrace? stackTrace]) { if (shared.disableLog) { return; } _log(Level.warning, 3, msg, error, stackTrace); } static void trace(dynamic msg, [dynamic error, StackTrace? stackTrace]) { if (shared.disableLog) { return; } _log(Level.trace, 2, msg, error, stackTrace); } static void error(dynamic msg, [dynamic error, StackTrace? stackTrace]) { if (shared.disableLog) { return; } _log(Level.error, 4, msg, error, stackTrace); } } bool isReleaseVersion() { return kReleaseMode; } // Utility to convert a message to native Utf8 (used in rust_log) Pointer toNativeUtf8(dynamic msg) { return "$msg".toNativeUtf8(); } String _formatMessageWithStackTrace(dynamic msg, StackTrace? stackTrace) { if (stackTrace != null) { return "$msg\nStackTrace:\n$stackTrace"; // Append the stack trace to the message } return msg.toString(); }