nashysolutions/files
**Files** is a lightweight, protocol-oriented Swift library for working with file system resources. It supports modular, composable types for files and directories, and provides testable, injectable logic for reading, writing, and deleting data.
Features
- Protocols for
StoredItem(file) andDirectorymodelling FileSystemContextabstraction for injecting logic or mockingFileSystemFolderStorefor Codable storage and file management- Log friendly and user friendly Localized errors
- Built-in support for testability and mocking
- Strong preference for
~Copyableto preserve resource identity
Quick Start
1. Implement a FileSystemContext
struct LiveAgent: FileSystemContext {
private let liveContext = FileManager.default
func fileExists(at url: URL) -> Bool {
liveContext.fileExists(atPath: url.path())
}
func folderExists(at url: URL) -> Bool {
var isDir: ObjCBool = false
let exists = liveContext.fileExists(atPath: url.path(), isDirectory: &isDir)
return exists && isDir.boolValue
}
func url(for directory: FileSystemDirectory) throws -> URL {
if let path = directory.searchPath {
guard let resolved = liveContext.urls(for: path, in: .userDomainMask).first else {
throw LiveAgentError.unableToResolveSearchPath(path)
}
return resolved
}
return liveContext.temporaryDirectory
}
func write(_ data: Data, to url: URL, options: NSData.WritingOptions) throws {
try data.write(to: url, options: options)
}
func read(from url: URL) throws -> Data {
try Data(contentsOf: url)
}
// etc
}
enum LiveAgentError: Error {
case unableToResolveSearchPath(FileManager.SearchPathDirectory)
}2. Use FileSystemFolderStore
let folder = Folder(location: "./Whatever")
let agent = LiveAgent()
try agent.moveResource(from: xURL, to: yURL)
let store = FileSystemFolderStore(agent: agent, folder: folder, kind: .caches)
struct Greeting: Codable { let message: String }
try store.saveResource(Greeting(message: "Hello!"), filename: "greeting.json")
let greeting: Greeting = try store.loadResource(filename: "greeting.json")3. Test With a Mock Context
let mock = MockContext(fileExistsHandler: { _ in true })Notes on `~Copyable`
While not enforced, ~Copyable is strongly recommended for all StoredItem and Directory conformers:
- Prevents duplicate identity for the same file system location
- Ensures mutation methods like
move,deleteapply consistently - Promotes safe and predictable resource handling
Package Metadata
Repository: nashysolutions/files
Default branch: main
README: README.md