import Foundation

protocol JSONSerializable {
    func serializable() -> AnyObject
}

extension JSONSerializable {
    func serializable() -> AnyObject {
        return self as AnyObject
    }
}

extension Int:JSONSerializable {}
extension String:JSONSerializable {}

struct JSONArray:JSONSerializable {
    let array:[JSONSerializable]
    
    func serializable() -> AnyObject {
        return array.map{ $0.serializable() } as AnyObject
    }
}

struct JSONDictionary:JSONSerializable {
    let dictionary:[String:JSONSerializable]
    
    func serializable() -> AnyObject {
        var res:[String:AnyObject] = [:]
        dictionary.forEach { (k,v) in
            res[k] = v.serializable()
        }
        return res as AnyObject
    }
}

//example 

let params = JSONDictionary(
    dictionary:[
        "string" : "foo",
        "number:": 1,
        "array": JSONArray(
            array: [
                1,
                2,
                3
            ]
        ),
        //"date": Date() // error
    ]
)

let res = params.serializable()
let json = try! JSONSerialization.data(withJSONObject: res, options: [])
print(String(data: json, encoding: .utf8)!)