2016-08-30 21:44:58 +03:00
|
|
|
/**
|
|
|
|
* Tae Won Ha - http://taewon.de - @hataewon
|
|
|
|
* See LICENSE
|
|
|
|
*/
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
2016-11-27 00:12:41 +03:00
|
|
|
class FileItem : CustomStringConvertible, Hashable, Comparable, Copyable {
|
2016-11-24 23:07:50 +03:00
|
|
|
|
|
|
|
typealias InstanceType = FileItem
|
2016-08-30 21:44:58 +03:00
|
|
|
|
2016-11-24 22:06:56 +03:00
|
|
|
static func ==(left: FileItem, right: FileItem) -> Bool {
|
|
|
|
return left.url == right.url
|
|
|
|
}
|
|
|
|
|
2016-11-27 00:12:41 +03:00
|
|
|
static func <(left: FileItem, right: FileItem) -> Bool {
|
|
|
|
return left.url.lastPathComponent < right.url.lastPathComponent
|
|
|
|
}
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
let url: URL
|
2016-11-12 18:42:10 +03:00
|
|
|
let isDir: Bool
|
|
|
|
let isHidden: Bool
|
|
|
|
let isPackage: Bool
|
2016-08-30 21:44:58 +03:00
|
|
|
|
2016-10-05 22:45:52 +03:00
|
|
|
var hashValue: Int {
|
|
|
|
return url.hashValue
|
|
|
|
}
|
|
|
|
|
2016-08-30 21:44:58 +03:00
|
|
|
/// When nil, then it has never been fnmatch'ed.
|
|
|
|
weak var ignoreToken: Token?
|
|
|
|
var ignore = false
|
|
|
|
|
|
|
|
var needsScanChildren = false
|
|
|
|
var childrenScanned = false
|
2016-11-24 22:06:56 +03:00
|
|
|
|
2016-08-30 21:44:58 +03:00
|
|
|
var children: [FileItem] = []
|
|
|
|
|
|
|
|
var description: String {
|
2016-11-12 18:42:10 +03:00
|
|
|
return "<FileItem: \(self.url), dir=\(self.isDir), hidden=\(self.isHidden), package=\(self.isPackage), "
|
2016-08-30 21:44:58 +03:00
|
|
|
+ "needsScan=\(self.needsScanChildren), childrenScanned=\(self.childrenScanned), "
|
2017-04-24 21:36:34 +03:00
|
|
|
+ "ignore=\(self.ignore), ignoreToken=\(String(describing: self.ignoreToken)), "
|
2016-08-30 21:44:58 +03:00
|
|
|
+ "children=\(self.children.count)>"
|
|
|
|
}
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
init(_ url: URL) {
|
2016-08-30 21:44:58 +03:00
|
|
|
self.url = url
|
2016-11-12 18:42:10 +03:00
|
|
|
self.isDir = url.isDir
|
|
|
|
self.isHidden = url.isHidden
|
|
|
|
self.isPackage = url.isPackage
|
2016-08-30 21:44:58 +03:00
|
|
|
}
|
2016-09-07 21:12:18 +03:00
|
|
|
|
2016-11-24 23:07:50 +03:00
|
|
|
fileprivate init(url: URL, dir: Bool, hidden: Bool, package: Bool) {
|
|
|
|
self.url = url
|
|
|
|
self.isDir = dir
|
|
|
|
self.isHidden = hidden
|
|
|
|
self.isPackage = package
|
|
|
|
}
|
|
|
|
|
|
|
|
func copy() -> FileItem {
|
2016-11-25 14:02:55 +03:00
|
|
|
let item = FileItem(url: self.url, dir: self.isDir, hidden: self.isHidden, package: self.isPackage)
|
|
|
|
item.needsScanChildren = self.needsScanChildren
|
|
|
|
item.childrenScanned = self.childrenScanned
|
|
|
|
item.children = self.children
|
|
|
|
|
|
|
|
return item
|
2016-11-24 23:07:50 +03:00
|
|
|
}
|
|
|
|
|
2016-11-25 01:49:53 +03:00
|
|
|
func child(with url: URL) -> FileItem? {
|
|
|
|
guard let idx = self.children.index(where: { $0.url == url }) else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return self.children[idx]
|
|
|
|
}
|
|
|
|
|
|
|
|
func deepChild(with url: URL) -> FileItem? {
|
|
|
|
let pathComps = self.url.pathComponents
|
|
|
|
let childPathComps = url.pathComponents
|
|
|
|
|
|
|
|
guard childPathComps.count > pathComps.count else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return childPathComps[pathComps.count..<childPathComps.count].reduce(self) { (result, pathComp) -> FileItem? in
|
|
|
|
guard let parent = result else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent.child(with: parent.url.appendingPathComponent(pathComp))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func remove(childWith url: URL) {
|
2016-09-25 18:50:33 +03:00
|
|
|
guard let idx = self.children.index(where: { $0.url == url }) else {
|
2016-09-07 21:12:18 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
self.children.remove(at: idx)
|
2016-09-07 21:12:18 +03:00
|
|
|
}
|
2016-08-30 21:44:58 +03:00
|
|
|
}
|