Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency cleanup #63

Merged
merged 26 commits into from
Feb 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@ import PackageDescription

let package = Package(
name: "Vapor",
dependencies: [
.Package(url: "https://github.com/gfx/Swift-PureJsonSerializer.git", majorVersion: 1)
]
dependencies: []
)
153 changes: 153 additions & 0 deletions Sources/Application+Route.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
//
// Application+Route.swift
// Vapor
//
// Created by Tanner Nelson on 2/23/16.
// Copyright © 2016 Tanner Nelson. All rights reserved.
//

import Foundation

extension Application {

public class Route: CustomStringConvertible {
static var scopedHost: String?
static var scopedMiddleware: [Middleware.Type] = []


let method: Request.Method
let path: String
let handler: Request.Handler
var hostname: String?

public typealias Handler = Request throws -> ResponseConvertible

init(method: Request.Method, path: String, handler: Request.Handler) {
self.method = method
self.path = path
self.handler = handler
}

public var description: String {
return "\(self.method) \(self.path) \(self.hostname)"
}

}

public final func get(path: String, handler: Route.Handler) {
self.add(.Get, path: path, handler: handler)
}

public final func post(path: String, handler: Route.Handler) {
self.add(.Post, path: path, handler: handler)
}

public final func put(path: String, handler: Route.Handler) {
self.add(.Put, path: path, handler: handler)
}

public final func patch(path: String, handler: Route.Handler) {
self.add(.Patch, path: path, handler: handler)
}

public final func delete(path: String, handler: Route.Handler) {
self.add(.Delete, path: path, handler: handler)
}

public final func options(path: String, handler: Route.Handler) {
self.add(.Options, path: path, handler: handler)
}

public final func any(path: String, handler: Route.Handler) {
self.get(path, handler: handler)
self.post(path, handler: handler)
self.put(path, handler: handler)
self.patch(path, handler: handler)
self.delete(path, handler: handler)
}



/**
Creates standard Create, Read, Update, Delete routes
using the Handlers from a supplied `Controller`.

The `path` supports nested resources, like `users.photos`.
users/:user_id/photos/:id

Note: You are responsible for pluralizing your endpoints.
*/
public final func resource(path: String, controller: Controller) {

let last = "/:id"

let shortPath = path.componentsSeparatedByString(".")
.flatMap { component in
return [component, "/:\(component)_id/"]
}
.dropLast()
.joinWithSeparator("")

let fullPath = shortPath + last

// ie: /users
self.get(shortPath, handler: controller.index)
self.post(shortPath, handler: controller.store)

// ie: /users/:id
self.get(fullPath, handler: controller.show)
self.put(fullPath, handler: controller.update)
self.delete(fullPath, handler: controller.destroy)
}



public final func add(method: Request.Method, path: String, handler: Route.Handler) {

//Convert Route.Handler to Request.Handler
var handler = { request in
return try handler(request).response()
}

// //Apply any scoped middlewares
// for middleware in Route.scopedMiddleware {
// handler = middleware.handle(handler)
// }

//Store the route for registering with Router later
let route = Route(method: method, path: path, handler: handler)

//Add scoped hostname if we have one
if let hostname = Route.scopedHost {
route.hostname = hostname
}

self.routes.append(route)
}

// /**
// Applies the middleware to the routes defined
// inside the closure. This method can be nested within
// itself safely.
// */
// public func middleware(middleware: Middleware.Type, handler: () -> ()) {
// self.middleware([middleware], handler: handler)
// }

// public func middleware(middleware: [Middleware.Type], handler: () -> ()) {
// let original = Route.scopedMiddleware
// Route.scopedMiddleware += middleware
//
// handler()
//
// Route.scopedMiddleware = original
// }

public final func host(host: String, handler: () -> Void) {
Route.scopedHost = host

handler()

Route.scopedHost = nil
}
}
13 changes: 10 additions & 3 deletions Sources/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Foundation
#endif

public class Application {
public static let VERSION = "0.2.2"
public static let VERSION = "0.2.3"

/**
The router driver is responsible
Expand Down Expand Up @@ -52,7 +52,7 @@ public class Application {
}
}

internal var host: String = "*"
var routes: [Route] = []

/**
Initialize the Application.
Expand All @@ -73,6 +73,12 @@ public class Application {
provider.boot(self)
}
}

func bootRoutes() {
for route in self.routes {
self.router.register(hostname: route.hostname, method: route.method, path: route.path, handler: route.handler)
}
}


/**
Expand All @@ -81,8 +87,9 @@ public class Application {
*/
public func start(port inPort: Int = 80) {
self.bootProviders()

self.server.delegate = self

self.bootRoutes()

var port = inPort

Expand Down
52 changes: 31 additions & 21 deletions Sources/Branch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,59 +7,68 @@
//

/**
When routing requests, different branches will be established, in a linked list style stemming from their host and request method. It can be represented as
When routing requests, different branches will be established,
in a linked list style stemming from their host and request method.
It can be represented as:

| host | request.method | branch -> branch -> branch
*/
internal final class Branch {

/**
The name of the branch, ie if we have a path hello/:name, the branch structure will be
The name of the branch, ie if we have a path hello/:name,
the branch structure will be:
Branch('hello') (connected to) Branch('name')

In cases where a slug is used, ie ':name' the slug will be used as the name and passed as a key in matching
In cases where a slug is used, ie ':name' the slug
will be used as the name and passed as a key in matching.
*/
let name: String

/**
There are two types of branches, those that support a handler, and those that are a linker between branches, for example /users/messages/:id will have 3 connected branches, only one of which supports a handler
There are two types of branches, those that support a handler,
and those that are a linker between branches,
for example /users/messages/:id will have 3 connected branches,
only one of which supports a handler.

Branch('users') -> Branch('messages') -> *Branches('id')
*indicates a supported branch

*indicates a supported branch.
*/
private var handler: Request.Handler?

/**
key or *
key or *

if it is a `key`, then it connects to an additional branch
if it is `*`, it is a slug point and the name represents a key for a dynamic value
If it is a `key`, then it connects to an additional branch.

If it is `*`, it is a slug point and the name
represents a key for a dynamic value.
*/
private(set) var subBranches: [String : Branch] = [:]

/**
Used to create a new branch
Used to create a new branch

- parameter name: the name associated with the branch, or the key when dealing with a slug
- parameter handler: the handler to be called if its a valid endpoint, or `nil` if this is a bridging branch
- parameter name: The name associated with the branch, or the key when dealing with a slug
- parameter handler: The handler to be called if its a valid endpoint, or `nil` if this is a bridging branch

- returns: an initialized request Branch
- returns: an initialized request Branch
*/
init(name: String, handler: Request.Handler? = nil) {
self.name = name
self.handler = handler
}

/**
This function will recursively traverse the branch until the path is fulfilled or the branch ends
This function will recursively traverse the branch
until the path is fulfilled or the branch ends

- parameter request: the request to use in matching
- parameter comps: ordered pathway components generator
- parameter request: the request to use in matching
- parameter comps: ordered pathway components generator

- returns: a request handler or nil if not supported
- returns: a request handler or nil if not supported
*/
@warn_unused_result
func handle(request: Request, comps: CompatibilityGenerator<String>) -> Request.Handler? {
guard let key = comps.next() else {
return handler
Expand All @@ -76,14 +85,14 @@ internal final class Branch {
}

/**
If a branch exists that is linked as:
If a branch exists that is linked as:

Branch('one') -> Branch('two')

This branch will be extended with the given value
This branch will be extended with the given value

- parameter generator: the generator that will be used to match the path components. /users/messages/:id will return a generator that is 'users' <- 'messages' <- '*id'
- parameter handler: the handler to assign to the end path component
- parameter generator: the generator that will be used to match the path components. /users/messages/:id will return a generator that is 'users' <- 'messages' <- '*id'
- parameter handler: the handler to assign to the end path component
*/
func extendBranch(generator: CompatibilityGenerator<String>, handler: Request.Handler) {
guard let key = generator.next() else {
Expand All @@ -96,6 +105,7 @@ internal final class Branch {
let indexOne = chars.startIndex.advancedBy(1)
let sub = key.characters.suffixFrom(indexOne)
let substring = String(sub)

let next = subBranches["*"] ?? Branch(name: substring)
next.extendBranch(generator, handler: handler)
subBranches["*"] = next
Expand Down