<commit_before>//
//  MapperProtocols.swift
//  JsonMapper
//
//  Created by <NAME> on 03.12.16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

public protocol AtomaryMapable {
    associatedtype ConcreteType = Self
    static func concrete<T: AtomaryMapable>(from value: AnyObject,
                         formatting: ((_ value: ConcreteType) throws -> T)?) throws -> T
}

extension AtomaryMapable {
    public static func concrete<T : AtomaryMapable>(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> T)? = nil) throws -> T {
        if let concrete = value as? T.ConcreteType {
            return concrete as! T
        }
        throw MapperError.wrongFormat
    }
}

extension String: AtomaryMapable {}
extension Date: AtomaryMapable {
    public typealias ConcreteType = String
    public static func concrete<T : AtomaryMapable>(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> T)? = nil) throws -> T {
        guard let formatting = formatting else {
            throw MapperError.noFormatter
        }
        
        guard let value = value as? ConcreteType else {
            throw MapperError.wrongFormat
        }
        
        return try formatting(value)
    }
}

extension Double: AtomaryMapable {
    public static func concrete<T : AtomaryMapable>(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> T)? = nil) throws -> T {
        if let concrete = value as? T.ConcreteType {
            return concrete as! T
        }
        if let concrete = value.doubleValue {
            return concrete as! T
        }
        if let stringValue: String = try? String.concrete(from: value), let concrete = Double(stringValue) {
            return concrete as! T
        }
        throw MapperError.wrongFormat
    }
}

extension Float: AtomaryMapable {
    public static func concrete<T : AtomaryMapable>(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> T)? = nil) throws -> T {
        if let concrete = value as? T.ConcreteType {
            return concrete as! T
        }
        if let concrete = value.doubleValue {
            return concrete as! T
        }
        if let stringValue: String = try? String.concrete(from: value), let concrete = Float(stringValue) {
            return concrete as! T
        }
        throw MapperError.wrongFormat
    }
}

extension Bool: AtomaryMapable {
    public static func concrete<T : AtomaryMapable>(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> T)? = nil) throws -> T {
        if let concrete = value as? T.ConcreteType {
            return concrete as! T
        }
        if let concrete = value.doubleValue {
            return concrete as! T
        }
        if let stringValue: String = try? String.concrete(from: value), let concrete = Bool(stringValue) {
            return concrete as! T
        }
        throw MapperError.wrongFormat
    }
}

extension Int: AtomaryMapable {
    public static func concrete<T : AtomaryMapable>(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> T)? = nil) throws -> T {
        if let concrete = value as? T.ConcreteType {
            return concrete as! T
        }
        if let stringValue: String = try? String.concrete(from: value), let concrete = Int(stringValue) {
            return concrete as! T
        }
        throw MapperError.wrongFormat
    }
}

public protocol Mapable {
    static var helpingPath: [MapPathable] {get}<commit_msg>small changes<commit_after>//
//  MapperProtocols.swift
//  JsonMapper
//
//  Created by <NAME> on 03.12.16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

public protocol AtomaryMapable {
    associatedtype ConcreteType = Self
    static func concrete(from value: AnyObject,
                         formatting: ((_ value: ConcreteType) throws -> Self)?) throws -> Self
}

extension AtomaryMapable {
    public static func concrete(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> Self)? = nil) throws -> Self {
        guard let concrete = value as? Self.ConcreteType else {
            throw MapperError.wrongFormat
        }
        
        if let formatting = formatting {
            return try formatting(concrete)
        }
        
        return concrete as! Self
    }
}

extension String: AtomaryMapable { }
extension Date: AtomaryMapable {
    public typealias ConcreteType = String
}

extension Double: AtomaryMapable {
    public static func concrete(from value: AnyObject, formatting: ((_ value: Double) throws -> Double)? = nil) throws -> Double {
        if let concrete = value as? Double.ConcreteType {
            return concrete
        }
        
        if let concrete = value.doubleValue {
            return concrete
        }
        
        if let stringValue: String = try? String.concrete(from: value), let concrete = Double(stringValue) {
            return concrete
        }
        
        throw MapperError.wrongFormat
    }
}

extension Float: AtomaryMapable {
    public static func concrete(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> Float)? = nil) throws -> Float {
        if let concrete = value as? ConcreteType {
            return concrete
        }
        
        if let concrete = value.doubleValue {
            return Float(concrete)
        }
        
        if let stringValue: String = try? String.concrete(from: value), let concrete = Float(stringValue) {
            return concrete
        }
        
        throw MapperError.wrongFormat
    }
}

extension Bool: AtomaryMapable {
    public static func concrete(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> Bool)? = nil) throws -> Bool {
        if let concrete = value as? ConcreteType {
            return concrete
        }
        
        if let concrete = value.boolValue {
            return concrete
        }
        
        if let stringValue: String = try? String.concrete(from: value), let concrete = Bool(stringValue) {
            return concrete
        }
        
        throw MapperError.wrongFormat
    }
}

extension Int: AtomaryMapable {
    public static func concrete(from value: AnyObject, formatting: ((_ value: ConcreteType) throws -> Int)? = nil) throws -> Int {
        if let concrete = value as? ConcreteType {
            return concrete
        }
        
        if let stringValue: String = try? String.concrete(from: value), let concrete = Int(stringValue) {
            return concrete
        }
        
        throw MapperError.wrongFormat
    }
}

public protocol Mapable {
    static var helpingPath: [MapPathable] {get}
{'fraction_non_alphanumeric': 0.08693700433936855, 'fraction_numerical': 0.002992667963489451, 'mean_word_length': 2.2289855072463767, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 40, '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': '4037479', 'n_tokens_mistral': 1829, 'n_tokens_neox': 1769, 'n_words': 580}