diff --git a/Sources/Disk+Helpers.swift b/Sources/Disk+Helpers.swift index 27438aa..8d38180 100644 --- a/Sources/Disk+Helpers.swift +++ b/Sources/Disk+Helpers.swift @@ -223,6 +223,40 @@ public extension Disk { throw error } } + + /// Copy file to a new directory + /// + /// - Parameters: + /// - path: path of file relative to directory + /// - directory: directory the file is currently in + /// - newFilePath: path to the new copy + /// - newDirectory: new directory to copy file in + /// - Throws: Error if file could not be copied + static func copy(_ path: String, from directory: Directory, to newFilePath: String, in newDirectory: Directory) throws { + do { + let currentUrl = try getExistingFileURL(for: path, in: directory) + let newUrl = try createURL(for: newFilePath, in: newDirectory) + try createSubfoldersBeforeCreatingFile(at: newUrl) + try FileManager.default.copyItem(at: currentUrl, to: newUrl) + } catch { + throw error + } + } + + /// Copy file to a new directory + /// + /// - Parameters: + /// - originalURL: url of file + /// - newURL: new url for the copy + /// - Throws: Error if file could not be moved + static func copy(_ originalURL: URL, to newURL: URL) throws { + do { + try createSubfoldersBeforeCreatingFile(at: newURL) + try FileManager.default.copyItem(at: originalURL, to: newURL) + } catch { + throw error + } + } /// Rename a file /// diff --git a/Tests/DiskTests.swift b/Tests/DiskTests.swift index 5eedb72..abb62cd 100644 --- a/Tests/DiskTests.swift +++ b/Tests/DiskTests.swift @@ -880,4 +880,34 @@ class DiskTests: XCTestCase { fatalError(convertErrorToString(error)) } } + + func testCopy() { + do { + try Disk.save(messages[0], to: .caches, as: "message.json") + XCTAssert(Disk.exists("message.json", in: .caches)) + try Disk.copy("message.json", from: .caches, to: "message-copy.json", in: .documents) + XCTAssert(Disk.exists("message-copy.json", in: .documents)) + + let existingFileUrl = try Disk.url(for: "message.json", in: .caches) + let newFileUrl = try Disk.url(for: "message-copy.json", in: .temporary) + try Disk.copy(existingFileUrl, to: newFileUrl) + XCTAssert(Disk.exists("message.json", in: .caches)) + XCTAssert(Disk.exists("message-copy.json", in: .temporary)) + + // ... in folder hierarchy + try Disk.save(messages[0], to: .caches, as: "Messages/Bob/message.json") + XCTAssert(Disk.exists("Messages/Bob/message.json", in: .caches)) + try Disk.copy("Messages/Bob/message.json", from: .caches, to: "Messages/Joe/message.json", in: .caches) + XCTAssert(Disk.exists("Messages/Joe/message.json", in: .caches)) + + // Array of structs + try Disk.save(messages, to: .caches, as: "messages.json") + XCTAssert(Disk.exists("messages.json", in: .caches)) + try Disk.copy("messages.json", from: .caches, to: "messages.json", in: .documents) + XCTAssert(Disk.exists("messages.json", in: .documents)) + + } catch { + fatalError(convertErrorToString(error)) + } + } }