diff --git a/Package.swift b/Package.swift index 336c0b5..e8093e6 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 5.9 +// swift-tools-version: 6.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription diff --git a/Sources/OversizeCore/Extensions/Image/NSImage+Extension.swift b/Sources/OversizeCore/Extensions/Image/NSImage+Extension.swift index b45ade6..ef19d26 100644 --- a/Sources/OversizeCore/Extensions/Image/NSImage+Extension.swift +++ b/Sources/OversizeCore/Extensions/Image/NSImage+Extension.swift @@ -38,4 +38,10 @@ return bitmapRepresentation.representation(using: .jpeg, properties: [:]) } } + + public extension NSImage { + var cgImage: CGImage? { + cgImage(forProposedRect: nil, context: nil, hints: nil) + } + } #endif diff --git a/Sources/OversizeCore/Extensions/Swift/Date+Extension.swift b/Sources/OversizeCore/Extensions/Swift/Date+Extension.swift index 0f7920d..173db25 100644 --- a/Sources/OversizeCore/Extensions/Swift/Date+Extension.swift +++ b/Sources/OversizeCore/Extensions/Swift/Date+Extension.swift @@ -132,14 +132,14 @@ public extension Date { } extension Date: @retroactive RawRepresentable { - private static let formatter: ISO8601DateFormatter = .init() - public var rawValue: String { - Date.formatter.string(from: self) + let formatter = ISO8601DateFormatter() + return formatter.string(from: self) } public init?(rawValue: String) { - self = Date.formatter.date(from: rawValue) ?? Date() + let formatter = ISO8601DateFormatter() + self = formatter.date(from: rawValue) ?? Date() } } diff --git a/Sources/OversizeCore/Extensions/Swift/Optional+Extension.swift b/Sources/OversizeCore/Extensions/Swift/Optional+Extension.swift index f0263a1..272fbc5 100644 --- a/Sources/OversizeCore/Extensions/Swift/Optional+Extension.swift +++ b/Sources/OversizeCore/Extensions/Swift/Optional+Extension.swift @@ -48,4 +48,11 @@ public extension Bool? { } return unwrapped } + + var valueOrTrue: Bool { + guard let unwrapped = self else { + return true + } + return unwrapped + } } diff --git a/Sources/OversizeCore/Extensions/Swift/Sequence+Extension.swift b/Sources/OversizeCore/Extensions/Swift/Sequence+Extension.swift new file mode 100644 index 0000000..c6885a8 --- /dev/null +++ b/Sources/OversizeCore/Extensions/Swift/Sequence+Extension.swift @@ -0,0 +1,13 @@ +// +// Copyright Š 2024 Alexander Romanov +// Sequence+Extension.swift, created on 24.10.2024 +// + +import Foundation + +public extension Sequence where Element: Hashable { + func removingDuplicates(by keyPath: KeyPath) -> [Element] { + var seen = Set() + return filter { seen.insert($0[keyPath: keyPath]).inserted } + } +} diff --git a/Sources/OversizeCore/Extensions/SwiftData/SortOrder+Extension.swift b/Sources/OversizeCore/Extensions/SwiftData/SortOrder+Extension.swift index d0f49dc..f04bacc 100644 --- a/Sources/OversizeCore/Extensions/SwiftData/SortOrder+Extension.swift +++ b/Sources/OversizeCore/Extensions/SwiftData/SortOrder+Extension.swift @@ -6,7 +6,9 @@ import Foundation extension SortOrder: @retroactive CaseIterable, @retroactive Identifiable { - public static var allCases: [SortOrder] = [.forward, .reverse] + public static var allCases: [SortOrder] { + [.forward, .reverse] + } public var title: String { switch self { diff --git a/Sources/OversizeCore/Global/Delay.swift b/Sources/OversizeCore/Global/Delay.swift index 363c3eb..d79d13f 100644 --- a/Sources/OversizeCore/Global/Delay.swift +++ b/Sources/OversizeCore/Global/Delay.swift @@ -5,6 +5,6 @@ import Foundation -public func delay(time: TimeInterval, execute: @escaping () -> Void) { +public func delay(time: TimeInterval, execute: @Sendable @escaping () -> Void) { DispatchQueue.main.asyncAfter(deadline: .now() + time, execute: execute) } diff --git a/Sources/OversizeCore/Global/Log.swift b/Sources/OversizeCore/Global/Log.swift index 3b687a5..52d7996 100644 --- a/Sources/OversizeCore/Global/Log.swift +++ b/Sources/OversizeCore/Global/Log.swift @@ -30,7 +30,89 @@ public func log(_ object: Any?) { public func logWithTime(_ text: String, terminator: String? = nil) { #if DEBUG let textTime: String = Date().formatted(.dateTime) - let textWithTime = "\(textTime): \(text)" + let textWithTime = "🕓 [\(textTime)] \(text)" terminator == nil ? print(textWithTime) : print(textWithTime, terminator: terminator!) #endif } + +@inlinable public func logDebug(_ text: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("âšĒ [DEBUG] \(text)") : print("âšĒ [DEBUG] \(text)", terminator: terminator!) + #endif +} + +@inlinable public func logNotice(_ text: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("🛎ī¸ [NOTICE] \(text)") : print("🛎ī¸ [NOTICE] \(text)", terminator: terminator!) + #endif +} + +@inlinable public func logInfo(_ text: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("ℹī¸ [INFO] \(text)") : print("ℹī¸ [INFO] \(text)", terminator: terminator!) + #endif +} + +@_disfavoredOverload +@inlinable public func logSuccess(_ text: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("✅ [SUCCESS] \(text)") : print("✅ [SUCCESS] \(text)", terminator: terminator!) + #endif +} + +public func logSuccess(_ text: String, object: Any?) { + #if DEBUG + print("✅ [SUCCESS] \(text), object:\n") + log(object) + #endif +} + +@inlinable public func logWarning(_ text: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("⚠ī¸ [WARNING] \(text)") : print("⚠ī¸ [WARNING] \(text)", terminator: terminator!) + #endif +} + +@inlinable public func logError(_ text: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("🔴 [ERROR] \(text)") : print("🔴 [ERROR] \(text)", terminator: terminator!) + #endif +} + +@inlinable public func logError(_ text: String, error: Error, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("🔴 [ERROR] \(text):\n\(error.localizedDescription)") : print("🔴 [ERROR] \(text):\n\(error.localizedDescription)", terminator: terminator!) + #endif +} + +@inlinable public func logError(_ text: String, error: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("🔴 [ERROR] \(text):\n\(error)") : print("🔴 [ERROR] \(text):\n\(error)", terminator: terminator!) + #endif +} + +@inlinable public func logDeleted(_ text: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("🗑ī¸ [DELETED] \(text)") : print("🗑ī¸ [DELETED] \(text)", terminator: terminator!) + #endif +} + +@inlinable public func logData(_ text: String, terminator: String? = nil) { + #if DEBUG + terminator == nil ? print("đŸ’Ŋ [DATA] \(text)") : print("đŸ’Ŋ [DATA] \(text)", terminator: terminator!) + #endif +} + +@inlinable public func logUrl(_ text: String? = nil, url: URL?, terminator: String? = nil) { + #if DEBUG + guard let url else { + log("🔗 [URL] Nil or not valid URL", terminator: terminator) + return + } + if let text { + url.isFileURL ? log("📁 [URL] \(text):\n\(url.path)", terminator: terminator) : log("🌐 [URL] \(text):\n\(url.absoluteString)", terminator: terminator) + } else { + url.isFileURL ? log("📁 [URL] \(url.path)", terminator: terminator) : log("🌐 [URL] \(url.absoluteString)", terminator: terminator) + } + #endif +}