<commit_before>//
//  WebService.swift
//  CHFoundation
//
//  Created by 許郁棋 on 2016/7/5.
//  Copyright © 2016年 Tiny World. All rights reserved.
//

import Foundation

public struct WebService {
    
    public enum WebServiceError: ErrorProtocol {
        case InvalidResponse
        case NoResponseData
        case Server(statusCode: Int, message: String)
    }
    
    
    // Property
    
    public let urlRequest: URLRequest
    
    public typealias ErrorParser = (data: Data?, urlResponse: URLResponse?, error: NSError?) -> ErrorProtocol
    public typealias SuccessHandler = (jsonObject: AnyObject) -> Void
    public typealias FailHandler = (error: ErrorProtocol) -> Void
    
    
    // MARK: Request
    
    public func request(with urlSession: URLSession, errorParser: ErrorParser? = nil, successHandler: SuccessHandler, failHandler: FailHandler? = nil) -> URLSessionTask {
        
        let sessionTask = urlSession.dataTask(with: urlRequest) { data, response, error in
            
            if let parsedError = errorParser?(data: data, urlResponse: response, error: error) {
                
                failHandler?(error: parsedError)
                
                return
                
            }
                
            guard let response = response as? HTTPURLResponse else {
                
                failHandler?(error: WebServiceError.InvalidResponse)
                
                return
                
            }
            
            if let error = error {
                
                let message = error.localizedDescription
                let serverError: WebServiceError = .Server(statusCode: response.statusCode, message: message)
                
                failHandler?(error: serverError)
                
                return
            
            }
            
            guard let data = data else {
                
                failHandler?(error: WebServiceError.NoResponseData)
                
                return
                
            }
            
            do {
                
                let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
                
                successHandler(jsonObject: jsonObject)
                
            }
            catch { failHandler?(error: error) }
        
        }
        
        sessionTask.resume()
        
        return sessionTask
        
    }
    
}
<commit_msg>add validation<commit_after>//
//  WebService.swift
//  CHFoundation
//
//  Created by 許郁棋 on 2016/7/5.
//  Copyright © 2016年 Tiny World. All rights reserved.
//

import Foundation

public struct WebService {
    
    public enum WebServiceError: ErrorProtocol {
        case invalidResponse
        case message(String)
        case data(Data?)
    }
    
    public typealias ErrorParser = (data: Data?, urlResponse: URLResponse?, error: NSError?) -> ErrorProtocol
    public typealias SuccessHandler = (jsonObject: AnyObject) -> Void
    public typealias FailHandler = (statusCode: Int, error: ErrorProtocol) -> Void
    
    
    // Property
    
    public let urlRequest: URLRequest
    
    
    // MARK: Request
    
    public func request(with urlSession: URLSession, errorParser: ErrorParser? = nil, successHandler: SuccessHandler, failHandler: FailHandler? = nil) -> URLSessionTask {
        
        let sessionTask = urlSession.dataTask(with: urlRequest) { data, response, error in
            
            guard let response = response as? HTTPURLResponse else {
                
                assert(false, "The response should be a HTTPURLResponse.")
                
                failHandler?(statusCode: 500, error: WebServiceError.invalidResponse)
                
                return
                
            }
            
            let statusCode = response.statusCode
            
            if let parsedError = errorParser?(data: data, urlResponse: response, error: error) {
                
                failHandler?(statusCode: statusCode, error: parsedError)
                
                return
                
            }
            
            if let error = error {
                
                let serverError: WebServiceError = .message(error.localizedDescription)
                
                failHandler?(statusCode: statusCode, error: serverError)
                
                return
            
            }
            
            if !self.validate(withStatusCode: statusCode) {
             
                let serverError: WebServiceError = .message(NSLocalizedString("Unaccepted status code.", comment: ""))
                
                failHandler?(statusCode: statusCode, error: serverError)
                
                return
                
            }
            
            do {
                
                let data = data ?? Data()
                let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
                
                successHandler(jsonObject: jsonObject)
                
            }
            catch { failHandler?(statusCode: statusCode, error: error) }
        
        }
        
        sessionTask.resume()
        
        return sessionTask
        
    }
    
    
    // MARK: Validate
    
    private func validate(withStatusCode statusCode: Int) -> Bool {
        
        switch statusCode {
        case 200..<300: return true
        default: return false
        }
        
    }
    
}

{'fraction_non_alphanumeric': 0.06902782797253343, 'fraction_numerical': 0.005240332490061439, 'mean_word_length': 1.322702475870751, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 12, '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': '4856340', 'n_tokens_mistral': 1324, 'n_tokens_neox': 1284, 'n_words': 334}