@@ -3,31 +3,57 @@ import Foundation
33public typealias SimpleRouter = Router < Void >
44
55public final class Router < UserInfo> {
6- private let scheme : String
6+ private enum Prefix {
7+ case scheme( String )
8+ case url( URL )
9+ }
10+ private let prefix : Prefix
711 private var routes : [ Route < UserInfo > ] = [ ]
812
913 public init ( scheme: String ) {
10- self . scheme = scheme
14+ prefix = . scheme( scheme)
15+ }
16+
17+ public init ( url: URL ) {
18+ prefix = . url( url)
19+ }
20+
21+ private func isValidURLPattern( _ patternURL: PatternURL ) -> Bool {
22+ switch prefix {
23+ case . scheme( let scheme) :
24+ return scheme == patternURL. scheme
25+ case . url( let url) :
26+ return patternURL. hasPrefix ( url: url)
27+ }
28+ }
29+
30+ private func canRespond( to url: URL ) -> Bool {
31+ switch prefix {
32+ case . scheme( let scheme) :
33+ return scheme == url. scheme
34+ case . url( let prefixURL) :
35+ return url. absoluteString. hasPrefix ( prefixURL. absoluteString)
36+ }
1137 }
1238
1339 internal func register( _ route: Route < UserInfo > ) {
14- if scheme != route. patternURL. scheme {
15- assertionFailure ( " Router and pattern must have the same schemes. expect: \( scheme) , actual: \( route. patternURL. scheme) " )
16- } else {
40+ if isValidURLPattern ( route. patternURL) {
1741 routes. append ( route)
42+ } else {
43+ assertionFailure ( " Unexpected URL Pattern " )
1844 }
1945 }
2046
2147 @discardableResult
2248 public func openIfPossible( _ url: URL , userInfo: UserInfo ) -> Bool {
23- if scheme != url. scheme {
49+ if !canRespond ( to : url) {
2450 return false
2551 }
2652 return routes. first { $0. openIfPossible ( url, userInfo: userInfo) } != nil
2753 }
2854
2955 public func responds( to url: URL , userInfo: UserInfo ) -> Bool {
30- if scheme != url. scheme {
56+ if !canRespond ( to : url) {
3157 return false
3258 }
3359 return routes. first { $0. responds ( to: url, userInfo: userInfo) } != nil
@@ -36,10 +62,19 @@ public final class Router<UserInfo> {
3662 public func register( _ routes: [ ( String , Route < UserInfo > . Handler ) ] ) {
3763 for (pattern, handler) in routes {
3864 let patternURLString : String
39- if pattern. hasPrefix ( " \( scheme) :// " ) {
40- patternURLString = pattern
41- } else {
42- patternURLString = " \( scheme) :// \( pattern) "
65+ switch prefix {
66+ case . scheme( let scheme) :
67+ if pattern. hasPrefix ( " \( scheme) :// " ) {
68+ patternURLString = pattern
69+ } else {
70+ patternURLString = " \( scheme) :// \( pattern) "
71+ }
72+ case . url( let url) :
73+ if pattern. hasPrefix ( url. absoluteString) {
74+ patternURLString = pattern
75+ } else {
76+ patternURLString = url. appendingPathComponent ( pattern) . absoluteString
77+ }
4378 }
4479 guard let patternURL = PatternURL ( string: patternURLString) else {
4580 assertionFailure ( " \( pattern) is invalid " )
0 commit comments