Skip to content

Instantly share code, notes, and snippets.

@sora0077
Last active October 25, 2015 07:44
Show Gist options
  • Save sora0077/aaccf78424e59e156151 to your computer and use it in GitHub Desktop.
Save sora0077/aaccf78424e59e156151 to your computer and use it in GitHub Desktop.
import UIKit
import XCPlayground
enum Path: Equatable {
case Current
case Parent
case Root
case Letter(String)
}
extension Path: CustomStringConvertible {
var description: String {
switch self {
case .Current:
return "./"
case .Parent:
return "../"
case .Root:
return "/"
case let .Letter(p):
return p + "/"
}
}
}
func ==(lhs: Path, rhs: Path) -> Bool {
switch lhs {
case .Root:
switch rhs {
case .Root:
return true
default:
return false
}
case .Parent:
switch rhs {
case .Parent:
return true
default:
return false
}
case .Current:
switch rhs {
case .Current:
return true
default:
return false
}
case let .Letter(letter):
switch rhs {
case let .Letter(retter):
return letter == retter
default:
return false
}
}
}
struct URLExpression {
private(set) var paths: [Path] = []
init(path: String) {
if path[path.startIndex] == "/" {
self.paths.append(.Root)
}
for p in (path.characters.split { $0 == "/" }) {
let p = String(p)
switch p {
case ".":
if self.paths.count == 0 {
self.paths.append(.Current)
}
case "..":
if let last = self.paths.last {
switch last {
case .Parent:
self.paths.append(.Parent)
default:
self.paths.removeLast()
}
} else {
self.paths.append(.Parent)
}
default:
self.paths.append(.Letter(p))
}
}
if self.paths.count == 0 {
self.paths.append(.Current)
}
}
init(url: NSURL) {
if let path = url.path {
let host = url.host ?? ""
self.init(path: host + path)
} else {
self.init(path: "/")
}
}
init() {
}
}
extension URLExpression: SequenceType {
var count: Int {
return self.paths.count
}
var first: Path? {
return self.paths.first
}
var last: Path? {
return self.paths.last
}
subscript(idx: Int) -> Path {
return self.paths[idx]
}
func generate() -> IndexingGenerator<[Path]> {
return self.paths.generate()
}
}
extension URLExpression {
func traverseTo(to: URLExpression) -> URLExpression {
var ret = URLExpression()
if to[0] == .Root {
var idx = 0
for (i, (l, r)) in zip(self, to).enumerate() {
print(i)
if l == r {
idx++
} else {
idx = i
break
}
}
print(idx)
for _ in self.paths[idx..<self.count] {
ret.paths.append(.Parent)
}
if self.count == idx {
ret.paths.append(.Current)
}
for p in to.paths[idx..<to.count] {
switch p {
case .Current:
break
case .Root:
break
default:
ret.paths.append(p)
}
}
} else {
ret.paths = self.paths
for p in to {
switch p {
case .Parent:
if ret.last != .Root {
ret.paths.removeLast()
}
case .Current:
break
default:
ret.paths.append(p)
}
}
}
return ret
}
}
extension URLExpression: CustomStringConvertible {
var description: String {
return self.paths.reduce("", combine: { i, p in
i + p.description
})
}
}
let url = "ddd://dd/../../../../pp/./c/../.."
let uuu = NSURL(string: url)
uuu?.URLByStandardizingPath
uuu?.host
uuu?.path
let ex = URLExpression(url: NSURL(string: url)!)
ex.description
let from = URLExpression(path: "/Users/user/../Documents")
let to = URLExpression(path: "../../Users/user/../Documents")
let ret = from.traverseTo(to)
ret.description
to.traverseTo(from)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment