<commit_before>//
//  PrimitiveType.swift
//  JSONDecodeKit
//
//  Created by Yume on 2017/11/17.
//  Copyright © 2017年 Yume. All rights reserved.
//

import Foundation

public protocol PrimitiveType {
    static func decode(any: Any?) -> Self?
    static func decode(json: JSON) -> Self?
    //    static func decode(this: Self) -> Self
    init?(_ description: String)
}

public extension PrimitiveType {
    static func decode(any: Any?) -> Self? {
        if let result = any as? Self {
            return result
        }
        
        
        if let result = any as? String {
            return Self(result)
        }
        
        return nil
    }
    
    //    static func decode(this: Self) -> Self {
    //        return this
    //    }
    
    // !!!!!!!!
    static func decode(json: JSON) -> Self? {
        return decode(any: json.data)
    }
}

// MARK: Int
extension Int:PrimitiveType {}
extension Int8:PrimitiveType {}
extension Int16:PrimitiveType {}
extension Int32:PrimitiveType {}
extension Int64:PrimitiveType {}

// MARK: UInt
extension UInt:PrimitiveType {}
extension UInt8:PrimitiveType {}
extension UInt16:PrimitiveType {}
extension UInt32:PrimitiveType {}
extension UInt64:PrimitiveType {}

// MARK: Float
extension Float:PrimitiveType {}
extension Double:PrimitiveType {}

// Mark: Bool
extension Bool:PrimitiveType {}

// MARK: String
extension String:PrimitiveType {
    public static func decode(any: Any?) -> String? {
        if let result = any as? String {
            return result
        }
        
        guard let _any = any else { return nil }
        if _any is NSNull {
            return nil
        }
        
        return String(describing: _any)
    }
    public init?(_ description: String) {
        self = description
    }
}

extension URL:PrimitiveType {
    public init?(_ description: String) {
        guard let result = URL(string: description) else { return nil }
        self = result
    }
}

//extension Array where Element: ValueType {<commit_msg>Add PrimtiveType to JSONDecodable PrimtiveType use NSNumber to parse numbers remove URL PrimtiveType extension<commit_after>//
//  PrimitiveType.swift
//  JSONDecodeKit
//
//  Created by Yume on 2017/11/17.
//  Copyright © 2017年 Yume. All rights reserved.
//

import Foundation

public protocol PrimitiveType:JSONDecodable {
    static func decode(any: Any?) throws -> Self
    static func number(number: NSNumber) -> Self
    init?(_ description: String)
}

public extension PrimitiveType {
    static func decode(any: Any?) throws -> Self {
        if let number = any as? NSNumber {
            return Self.number(number: number)
        }
        
        guard let string = any as? String, let result = Self(string) else {
            throw JSONDecodeError.specialCase(reason: "...")
        }
        
        return result
    }
    
    static func decode(json: JSON) throws -> Self {
        return try decode(any: json.data)
    }
}

// MARK: Int
extension Int:PrimitiveType {
    public static func number(number: NSNumber) -> Int {
        return number.intValue
    }
}
extension Int8:PrimitiveType {
    public static func number(number: NSNumber) -> Int8 {
        return number.int8Value
    }
}
extension Int16:PrimitiveType {
    public static func number(number: NSNumber) -> Int16 {
        return number.int16Value
    }
}
extension Int32:PrimitiveType {
    public static func number(number: NSNumber) -> Int32 {
        return number.int32Value
    }
}
extension Int64:PrimitiveType {
    public static func number(number: NSNumber) -> Int64 {
        return number.int64Value
    }
}

// MARK: UInt
extension UInt:PrimitiveType {
    public static func number(number: NSNumber) -> UInt {
        return number.uintValue
    }
}
extension UInt8:PrimitiveType {
    public static func number(number: NSNumber) -> UInt8 {
        return number.uint8Value
    }
}
extension UInt16:PrimitiveType {
    public static func number(number: NSNumber) -> UInt16 {
        return number.uint16Value
    }
}
extension UInt32:PrimitiveType {
    public static func number(number: NSNumber) -> UInt32 {
        return number.uint32Value
    }
}
extension UInt64:PrimitiveType {
    public static func number(number: NSNumber) -> UInt64 {
        return number.uint64Value
    }
}

// MARK: Float
extension Float:PrimitiveType {
    public static func number(number: NSNumber) -> Float {
        return number.floatValue
    }
}
extension Double:PrimitiveType {
    public static func number(number: NSNumber) -> Double {
        return number.doubleValue
    }
}

// Mark: Bool
extension Bool:PrimitiveType {
    public static func number(number: NSNumber) -> Bool {
        return number.boolValue
    }
}

// MARK: String
extension String:PrimitiveType {
//    public static func decode(any: Any?) -> String? {
    public static func decode(any: Any?) throws -> String {
        if let result = any as? String { return result }
        guard let any = any else { throw JSONDecodeError.specialCase(reason: "...") }
        if any is NSNull { throw JSONDecodeError.specialCase(reason: "...") }
        return String(describing: any)
    }
    public init?(_ description: String) {
        self = description
    }
    public static func number(number: NSNumber) -> String {
        return number.stringValue
    }
}

//extension URL:PrimitiveType {
//    public init?(_ description: String) {
//        guard let result = URL(string: description) else { return nil }
//        self = result
//    }
//}

//extension Array where Element: ValueType {
{'fraction_non_alphanumeric': 0.09949802796701326, 'fraction_numerical': 0.014342058085335245, 'mean_word_length': 2.497805642633229, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3724677', 'n_tokens_mistral': 1611, 'n_tokens_neox': 1579, 'n_words': 477}