 }
 
 
-struct Foo: Decodable {
-    let key: String
-    let key2: String
+private func parseToAnyObject(json: AnyObject, path: [String]) throws -> AnyObject {
     
-    static func decode(j: AnyObject) throws -> Foo {
-        return try Foo(key: j => "key", key2: j => "key2")
+    func objectForKey(dictionary: NSDictionary, key: String) throws -> AnyObject {
+        guard let result = dictionary[key] else {
+            let info = DecodingError.Info(object: dictionary)
+            throw DecodingError.MissingKey(key: key, info: info)
+        }
+        return result
+    }
+    
+    guard let lastKey = path.last else {
+        return json
+    }
+    var path = path
+    path.removeLast()
+    
+    var currentDict = try NSDictionary.decode(json)
+    for key in path {
+        currentDict = try NSDictionary.decode(objectForKey(currentDict, key: key))
+    }
+    
+    return try objectForKey(currentDict, key: lastKey)
+}
+
+
+func parse<T: Decodable>(json: AnyObject, path: String...) throws -> T {
+    return try T.decode(parseToAnyObject(json, path: path))
+}
+
+func parse<T: Decodable>(json: AnyObject, path: String...) throws -> T? {
+    return try T.decode(parseToAnyObject(json, path: path))
+}
+
+infix operator => { associativity right precedence 150 }
+
+func => <T: Decodable>(lhs: AnyObject, rhs: JSONPath) throws -> T {
+    return try T.decode(parseToAnyObject(lhs, path: rhs.path))
+}
+
+
+
+func => (lhs: String, rhs: JSONPath) throws -> JSONPath {
+    return JSONPath(path: [lhs] + rhs.path)
+}
+
+struct JSONPath: StringLiteralConvertible {
+    
+    let path: [String]
+    
+    typealias ExtendedGraphemeClusterLiteralType = String
+    typealias UnicodeScalarLiteralType = String
+    
+    init(path: [String]) {
+        self.path = path
+    }
+    
+    init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
+        self.path = [value]
+    }
+    
+    init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
+        self.path = [value]
+    }
+    
+    init(stringLiteral value: StringLiteralType) {
+        self.path = [value]
     }
 }
 
-do {
-    try _ = Foo.decode(<#T##j: AnyObject##AnyObject#>)
-}
-
+let a: AnyObject = ["test": ["key": 3]]
+try! parse(a, path: "test", "key") as Int?
+try! a => "test" => "key" as Int

//: Playground - noun: a place where people can play

//
//  Decodable.swift
//  Decodable
//
//  Created by Johannes Lund on 2015-07-07.
//  Copyright © 2015 anviking. All rights reserved.
//

import Foundation

public protocol Decodable {
    static func decode(json: AnyObject) throws -> Self

    }
}

extension Int: Castable {}

extension NSDictionary {
    public static func decode(j: AnyObject) throws -> NSDictionary {
