Repository: apple/swift-nio
File: Sources/NIOPosix/NonBlockingFileIO.swift (Swift)

Code before:

    public struct DirectoryEntry {
        // File number of entry
        var ino: UInt64
        // File type
        var type: UInt8
        // File name
        var name: String
    }

    /// List contents of the directory at `path` on a private thread pool which is separate from any `EventLoop` thread.
    ///
    /// - parameters:
    ///     - path: The path of the directory to list the content of.
    ///     - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire.
    /// - returns: An `EventLoopFuture` containing the file list.
    public func listDirectory(path: String, eventLoop: EventLoop) -> EventLoopFuture<[DirectoryEntry]> {
        return self.threadPool.runIfActive(eventLoop: eventLoop) {
            let dir = try Posix.opendir(pathname: path)
            var entries: [DirectoryEntry] = []
            do {
                while let entry = try Posix.readdir(dir: dir) {
                    let name = withUnsafeBytes(of: entry.pointee.d_name) { pointer -> String in
                        // Per man readdir(3):
                        // struct dirent {
                        //  char d_name[256]; /* Null-terminated filename */
                        #if os(Linux)
                        let ptr = pointer.baseAddress!.assumingMemoryBound(to: CChar.self)
                        return String(cString: ptr)
                        #else
                        String(decoding: pointer.prefix(Int(entry.pointee.d_namlen)), as: UTF8.self)
                        #endif
                    }
                    entries.append(DirectoryEntry(ino: UInt64(entry.pointee.d_ino), type: entry.pointee.d_type, name: name))
                }
                try? Posix.closedir(dir: dir)
            } catch {
                try? Posix.closedir(dir: dir)
                throw error
            }
            return entries
        }
    }

    /// Renames the file at `path` to `newName` on a private thread pool which is separate from any `EventLoop` thread.
    ///
    /// - parameters:
    ///     - path: The path of the file to be renamed.
    ///     - newName: New file name.
    ///     - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire.
    /// - returns: An `EventLoopFuture` which is fulfilled if the rename was successful or fails on error.

Review comment (refactor):
Can you move this comment into the `os(Linux)` block and then an equivalent manual page comment from macOS into the other block?

Code after:

    /// List contents of the directory at `path` on a private thread pool which is separate from any `EventLoop` thread.
    ///
    /// - parameters:
    ///     - path: The path of the directory to list the content of.
    ///     - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire.
    /// - returns: An `EventLoopFuture` containing the directory entries.
    public func listDirectory(path: String, eventLoop: EventLoop) -> EventLoopFuture<[NIODirectoryEntry]> {
        return self.threadPool.runIfActive(eventLoop: eventLoop) {
            let dir = try Posix.opendir(pathname: path)
            var entries: [NIODirectoryEntry] = []
            do {
                while let entry = try Posix.readdir(dir: dir) {
                    let name = withUnsafeBytes(of: entry.pointee.d_name) { pointer -> String in
                        let ptr = pointer.baseAddress!.assumingMemoryBound(to: CChar.self)
                        return String(cString: ptr)
                    }
                    entries.append(NIODirectoryEntry(ino: UInt64(entry.pointee.d_ino), type: entry.pointee.d_type, name: name))
                }
                try? Posix.closedir(dir: dir)
            } catch {
                try? Posix.closedir(dir: dir)
                throw error
            }
            return entries
        }
    }

    /// Renames the file at `path` to `newName` on a private thread pool which is separate from any `EventLoop` thread.
    ///
    /// - parameters:
    ///     - path: The path of the file to be renamed.
    ///     - newName: New file name.
    ///     - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire.
    /// - returns: An `EventLoopFuture` which is fulfilled if the rename was successful or fails on error.
    public func rename(path: String, newName: String, eventLoop: EventLoop) -> EventLoopFuture<Void> {
        return self.threadPool.runIfActive(eventLoop: eventLoop) {
            try Posix.rename(pathname: path, newName: newName)
        }
    }

    /// Removes the file at `path` on a private thread pool which is separate from any `EventLoop` thread.
    ///
    /// - parameters:
    ///     - path: The path of the file to be removed.
    ///     - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire.
    /// - returns: An `EventLoopFuture` which is fulfilled if the remove was successful or fails on error.
    public func remove(path: String, eventLoop: EventLoop) -> EventLoopFuture<Void> {
        return self.threadPool.runIfActive(eventLoop: eventLoop) {
            try Posix.remove(pathname: path)
        }