2025-01-28 00:07:24 +00:00
|
|
|
import Foundation
|
|
|
|
|
2025-02-17 22:11:05 +00:00
|
|
|
public struct FileService {
|
|
|
|
|
2025-01-28 00:07:24 +00:00
|
|
|
// MARK: Properties
|
|
|
|
|
|
|
|
private let fileManager: FileManager
|
|
|
|
|
|
|
|
// MARK: Initialisers
|
|
|
|
|
|
|
|
public init(fileManager: FileManager = .default) {
|
|
|
|
self.fileManager = fileManager
|
|
|
|
}
|
|
|
|
|
2025-02-17 22:11:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - FileServicing
|
|
|
|
|
|
|
|
extension FileService: FileServicing {
|
|
|
|
|
2025-01-28 00:07:24 +00:00
|
|
|
// MARK: Computed
|
|
|
|
|
|
|
|
public var currentFolder: URL {
|
|
|
|
get async {
|
|
|
|
.init(at: fileManager.currentDirectoryPath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: Functions
|
|
|
|
|
|
|
|
public func copyFile(from source: URL, to destination: URL) async throws (FileServiceError) {
|
|
|
|
guard try await !isItemExists(at: destination) else {
|
2025-02-17 22:11:05 +00:00
|
|
|
throw .itemAlreadyExists
|
2025-01-28 00:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var itemData: Data?
|
|
|
|
|
|
|
|
do {
|
|
|
|
itemData = try Data(contentsOf: source)
|
|
|
|
} catch {
|
2025-02-17 22:11:05 +00:00
|
|
|
throw .itemEmptyData
|
2025-01-28 00:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
try itemData?.write(to: destination, options: .atomic)
|
|
|
|
} catch {
|
2025-02-17 22:11:05 +00:00
|
|
|
throw .itemNotCopied
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public func createFile(at location: URL, with data: Data) async throws (FileServiceError) {
|
|
|
|
guard try await !isItemExists(at: location) else {
|
|
|
|
throw .itemAlreadyExists
|
|
|
|
}
|
|
|
|
|
|
|
|
guard !data.isEmpty else {
|
|
|
|
throw .fileDataIsEmpty
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
try data.write(to: location, options: .atomic)
|
|
|
|
} catch {
|
|
|
|
throw .fileNotCreated
|
2025-01-28 00:07:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public func createFolder(at location: URL) async throws (FileServiceError) {
|
|
|
|
guard try await !isItemExists(at: location) else {
|
2025-02-17 22:11:05 +00:00
|
|
|
throw .itemAlreadyExists
|
2025-01-28 00:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
try fileManager.createDirectory(at: location, withIntermediateDirectories: true)
|
|
|
|
} catch {
|
2025-02-17 22:11:05 +00:00
|
|
|
throw .folderNotCreated
|
2025-01-28 00:07:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public func deleteItem(at location: URL) async throws (FileServiceError) {
|
|
|
|
guard try await isItemExists(at: location) else {
|
2025-02-17 22:11:05 +00:00
|
|
|
throw .itemNotExists
|
2025-01-28 00:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
try fileManager.removeItem(at: location)
|
|
|
|
} catch {
|
2025-02-17 22:11:05 +00:00
|
|
|
throw .itemNotDeleted
|
2025-01-28 00:07:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public func isItemExists(at location: URL) async throws (FileServiceError) -> Bool {
|
|
|
|
guard location.isFileURL else {
|
2025-02-17 22:11:05 +00:00
|
|
|
throw .itemNotFileURL
|
2025-01-28 00:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let filePath = location.pathString
|
|
|
|
|
|
|
|
return fileManager.fileExists(atPath: filePath)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|