Skip to content

Commit

Permalink
Refined Filemanager.stat API
Browse files Browse the repository at this point in the history
  • Loading branch information
Alkenso committed Apr 11, 2022
1 parent 9d59c36 commit 624b263
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,30 +68,36 @@ extension FileManager {
.forEach { try copyItem(at: $0, to: $1) }
}

public func statItem(at url: URL) throws -> stat {
try statItem(atPath: url.path)
/// stat file at given URL
/// - Parameters:
/// - url: URL to stat
/// - followSymlinks: if true, stat is used, otherwise lstat
/// - returns: 'stat' structure
/// - throws: if URL is not a file URL or file can't be stat'ed
public func statItem(at url: URL, followSymlinks: Bool = true) throws -> stat {
try url.ensureFileURL()
return try statItem(atPath: url.path, followSymlinks: followSymlinks)
}

public func statItem(atPath path: String) throws -> stat {
/// stat file at given path
/// - Parameters:
/// - url: path to stat
/// - followSymlinks: if true, stat is used, otherwise lstat
/// - returns: 'stat' structure
/// - throws: if file can't be stat'ed
public func statItem(atPath path: String, followSymlinks: Bool = true) throws -> stat {
var st = stat()
try NSError.posix
.debugDescription("stat failed")
.debugDescription("\(followSymlinks ? "stat" : "lstat") failed")
.userInfo(path, for: NSFilePathErrorKey)
.try(path.withCString { stat($0, &st) } == 0)
.try(path.withCString { followSymlinks ? stat($0, &st) : lstat($0, &st) } == 0)
return st
}

public func lstatItem(at url: URL) throws -> stat {
try lstatItem(atPath: url.path)
}

public func lstatItem(atPath path: String) throws -> stat {
var st = stat()
try NSError.posix
.debugDescription("lstat failed")
.userInfo(path, for: NSFilePathErrorKey)
.try(path.withCString { lstat($0, &st) } == 0)
return st
}

extension stat {
public var fileType: FileManager.FileType? {
FileManager.FileType(mode: st_mode)
}
}

Expand All @@ -105,33 +111,6 @@ extension FileManager {
case symbolicLink
case socket
}

/// Determines file type of given URL.
/// - Parameters:
/// - url: URL to examine
/// - resolveSymlinks: if true, stat is used, otherwise lstat
/// - returns: the type of file
/// - throws: if URL is not a file URL, or file can't be stat'ed, or file type cannot be determined
public func typeOfItem(at url: URL, resolveSymlinks: Bool = false) throws -> FileType {
try url.ensureFileURL()
return try typeOfItem(atPath: url.path)
}

/// Determines file type at given path
/// - Parameters:
/// - url: path to examine
/// - resolveSymlinks: if true, stat is used, otherwise lstat
/// - returns: the type of file
/// - throws: if file can't be stat'ed or file type cannot be determined
public func typeOfItem(atPath path: String, resolveSymlinks: Bool = false) throws -> FileType {
let fn = resolveSymlinks ? FileManager.default.lstatItem(atPath:) : FileManager.default.statItem(atPath:)
let st = try fn(path)
if let type = FileType(mode: st.st_mode) {
return type
} else {
throw CommonError.unexpected("Unknown mode = \(st.st_mode) of file at path = \(path)")
}
}
}

extension FileManager.FileType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ private extension FileEnumerator.Filter {
return isIncluded(url)

case .types(let types):
guard let fileType = try? FileManager.default.typeOfItem(at: url) else { return false }
guard let fileType = try? FileManager.default.statItem(at: url).fileType else { return false }
return types.contains(fileType)
}
}
Expand Down

0 comments on commit 624b263

Please sign in to comment.