Skip to content

Commit

Permalink
more organizing
Browse files Browse the repository at this point in the history
  • Loading branch information
leogdion committed Sep 9, 2024
1 parent e076b99 commit 57ca6c8
Show file tree
Hide file tree
Showing 54 changed files with 1,907 additions and 879 deletions.
135 changes: 135 additions & 0 deletions Sources/RadiantKit/BushelProgressUI/CopyOperation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
//
// CopyOperation.swift
// RadiantKit
//
// Created by Leo Dion.
// Copyright © 2024 BrightDigit.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

#if canImport(Observation) && (os(macOS) || os(iOS))
public import Foundation
import Observation

public import OSLog

@MainActor @Observable
public final class CopyOperation<ValueType: BinaryInteger & Sendable>: Identifiable {
private let sourceURL: URL
private let destinationURL: URL
public let totalValue: ValueType?
private let timeInterval: TimeInterval
private nonisolated let getSize: @Sendable (URL) throws -> ValueType?
private let copyFile: @Sendable (CopyPaths) async throws -> Void
public var currentValue = ValueType.zero

Check warning on line 44 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L44

Added line #L44 was not covered by tests
private var timer: Timer?
private let logger: Logger?

public nonisolated var id: URL { sourceURL }

Check warning on line 48 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L48

Added line #L48 was not covered by tests

public init(
sourceURL: URL,
destinationURL: URL,
totalValue: ValueType?,
timeInterval: TimeInterval,
logger: Logger?,
getSize: @escaping @Sendable (URL) throws -> ValueType?,
copyFile: @escaping @Sendable (CopyPaths) async throws -> Void
) {
self.sourceURL = sourceURL
self.destinationURL = destinationURL
self.totalValue = totalValue
self.timeInterval = timeInterval
self.getSize = getSize
self.copyFile = copyFile
self.logger = logger

Check warning on line 65 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L58-L65

Added lines #L58 - L65 were not covered by tests
}

private nonisolated func updateValue(_ currentValue: ValueType) {
Task { await self.updatingValue(currentValue) }

Check warning on line 69 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L68-L69

Added lines #L68 - L69 were not covered by tests
}

private func updatingValue(_ currentValue: ValueType) {
self.currentValue = currentValue
if let totalValue = self.totalValue {
guard self.currentValue < totalValue else {
self.logger?.debug("Copy is complete based on size. Quitting timer.")
self.killTimer()
return

Check warning on line 78 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L72-L78

Added lines #L72 - L78 were not covered by tests
}
}
else {
self.logger?.warning("Total size is missing")

Check warning on line 82 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L81-L82

Added lines #L81 - L82 were not covered by tests
}
}

private func starTimer() {
timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true) {
[weak self] timer in
guard let weakSelf = self else {
timer.invalidate()
return

Check warning on line 91 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L86-L91

Added lines #L86 - L91 were not covered by tests
}
weakSelf.logger?.debug("Timer On")
assert(weakSelf.logger != nil)
Task {
let currentValue: ValueType?
do { currentValue = try weakSelf.getSize(weakSelf.destinationURL) }
catch {
weakSelf.logger?.error("Unable to get size: \(error)")
assertionFailure("Unable to get size: \(error)")
currentValue = nil

Check warning on line 101 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L93-L101

Added lines #L93 - L101 were not covered by tests
}
if let currentValue {
weakSelf.updateValue(currentValue)
weakSelf.logger?.debug("Updating size to: \(currentValue)")

Check warning on line 105 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L103-L105

Added lines #L103 - L105 were not covered by tests
}
else {
weakSelf.logger?.warning("Unable to get size")

Check warning on line 108 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L107-L108

Added lines #L107 - L108 were not covered by tests
}
}
}
}

public func execute() async throws {
self.logger?.debug("Starting Copy operating")
await starTimer()
do { try await self.copyFile(.init(fromURL: sourceURL, toURL: destinationURL)) }
catch {
self.logger?.error("Error Copying: \(error)")
self.killTimer()
throw error

Check warning on line 121 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L114-L121

Added lines #L114 - L121 were not covered by tests
}
self.logger?.debug("Copy is done. Quitting timer.")
self.killTimer()

Check warning on line 124 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L123-L124

Added lines #L123 - L124 were not covered by tests
}

private func killTimer() {
timer?.invalidate()
timer = nil

Check warning on line 129 in Sources/RadiantKit/BushelProgressUI/CopyOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/CopyOperation.swift#L127-L129

Added lines #L127 - L129 were not covered by tests
}
}

extension CopyOperation: ProgressOperation {}

#endif
35 changes: 35 additions & 0 deletions Sources/RadiantKit/BushelProgressUI/CopyPaths.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// CopyPaths.swift
// RadiantKit
//
// Created by Leo Dion.
// Copyright © 2024 BrightDigit.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

public import Foundation

public struct CopyPaths {
public let fromURL: URL
public let toURL: URL
}
76 changes: 76 additions & 0 deletions Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// DownloadOperation.swift
// RadiantKit
//
// Created by Leo Dion.
// Copyright © 2024 BrightDigit.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

#if canImport(Observation) && (os(macOS) || os(iOS))
public import Foundation
import Observation

@MainActor @Observable
public final class DownloadOperation<ValueType: BinaryInteger & Sendable>:

Identifiable, ProgressOperation, Sendable
{
private let download: ObservableDownloader
private let sourceURL: URL
private let destinationURL: URL

public nonisolated var id: URL { sourceURL }

Check warning on line 43 in Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift#L43

Added line #L43 was not covered by tests

public var currentValue: ValueType { .init(download.totalBytesWritten) }

Check warning on line 45 in Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift#L45

Added line #L45 was not covered by tests

public var totalValue: ValueType? { download.totalBytesExpectedToWrite.map(ValueType.init(_:)) }

Check warning on line 47 in Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift#L47

Added line #L47 was not covered by tests

public init(
sourceURL: URL,
destinationURL: URL,
totalBytesExpectedToWrite: ValueType?,
configuration: URLSessionConfiguration? = nil,
queue: OperationQueue? = nil
) {
assert(!sourceURL.isFileURL)
assert(totalBytesExpectedToWrite != nil)
self.sourceURL = sourceURL
self.destinationURL = destinationURL
self.download = .init(
totalBytesExpectedToWrite: totalBytesExpectedToWrite,
configuration: configuration,
queue: queue
)

Check warning on line 64 in Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift#L55-L64

Added lines #L55 - L64 were not covered by tests
}

public func execute() async throws {
try await withCheckedThrowingContinuation { continuation in
self.download.begin(from: self.sourceURL, to: self.destinationURL) { result in
continuation.resume(with: result)

Check warning on line 70 in Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/DownloadOperation.swift#L67-L70

Added lines #L67 - L70 were not covered by tests
}
}
}
}

#endif
50 changes: 50 additions & 0 deletions Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// FileOperationProgress.swift
// RadiantKit
//
// Created by Leo Dion.
// Copyright © 2024 BrightDigit.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

#if canImport(Observation) && (os(macOS) || os(iOS))
public import Foundation
import Observation

@MainActor @Observable
public final class FileOperationProgress<ValueType: BinaryInteger>: Identifiable {
public let operation: any ProgressOperation<ValueType>

public nonisolated var id: URL { operation.id }

Check warning on line 38 in Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift#L38

Added line #L38 was not covered by tests

public var totalValueBytes: Int64? { operation.totalValue.map(Int64.init) }

Check warning on line 40 in Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift#L40

Added line #L40 was not covered by tests

public var currentValueBytes: Int64 { Int64(operation.currentValue) }

Check warning on line 42 in Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift#L42

Added line #L42 was not covered by tests

internal var currentValue: Double { Double(operation.currentValue) }

Check warning on line 44 in Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift#L44

Added line #L44 was not covered by tests

internal var totalValue: Double? { operation.totalValue.map(Double.init) }

Check warning on line 46 in Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift#L46

Added line #L46 was not covered by tests

public init(_ operation: any ProgressOperation<ValueType>) { self.operation = operation }

Check warning on line 48 in Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift

View check run for this annotation

Codecov / codecov/patch

Sources/RadiantKit/BushelProgressUI/FileOperationProgress.swift#L48

Added line #L48 was not covered by tests
}
#endif
Loading

0 comments on commit 57ca6c8

Please sign in to comment.