<commit_before>//
//  Dictionary+Optional.swift
//  clangParser
//
//  Created by <NAME> on 28.04.17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation

extension Dictionary {

    @discardableResult
    mutating func updateOptionalValue(_ value: Dictionary.Value?, forKey key: Dictionary.Key?) -> Dictionary.Value? {
        guard let key = key else { return nil }
        let oldValue = self[key]
        guard let value = value else { return oldValue }

        self[key] = value

        return oldValue
    }

    subscript(optional key: Dictionary.Key?) -> Dictionary.Value? {
        get {
            guard let key = key else { return nil }
            return self[key]
        }
        set {
            self.updateOptionalValue(newValue, forKey: key)
        }
    }
}

extension Dictionary where Key: StringProtocol {

    subscript(keyPath keyPath: KeyPath) -> Any? {
        get {
            switch keyPath.headAndTail() {
            case nil:
                // key path is empty.
                return nil
            case let (head, remainingKeyPath)? where remainingKeyPath.isEmpty:
                // Reached the end of the key path.
                let key = Key(string: head)
                return self[key]
            case let (head, remainingKeyPath)?:
                // Key path has a tail we need to traverse.
                let key = Key(string: head)
                switch self[key] {
                case let nestedDict as [Key: Any]:
                    // Next nest level is a dictionary.
                    // Start over with remaining key path.
                    return nestedDict[keyPath: remainingKeyPath]
                default:
                    // Next nest level isn't a dictionary.
                    // Invalid key path, abort.
                    return nil
                }
            default:
                return nil
            }
        }
    }
}

// Needed because Swift 3.0 doesn't support extensions with concrete
// same-type requirements (extension Dictionary where Key == String).
protocol StringProtocol {
    init(string s: String)
}

extension String: StringProtocol {
    init(string s: String) {
        self = s
    }
}

struct KeyPath {
    var segments: [String]

    var isEmpty: Bool { return segments.isEmpty }
    var path: String {
        return segments.joined(separator: ".")
    }

    /// Strips off the first segment and returns a pair
    /// consisting of the first segment and the remaining key path.
    /// Returns nil if the key path has no segments.<commit_msg>remove default case from switch<commit_after>//
//  Dictionary+Optional.swift
//  clangParser
//
//  Created by <NAME> on 28.04.17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation

extension Dictionary {

    @discardableResult
    mutating func updateOptionalValue(_ value: Dictionary.Value?, forKey key: Dictionary.Key?) -> Dictionary.Value? {
        guard let key = key else { return nil }
        let oldValue = self[key]
        guard let value = value else { return oldValue }

        self[key] = value

        return oldValue
    }

    subscript(optional key: Dictionary.Key?) -> Dictionary.Value? {
        get {
            guard let key = key else { return nil }
            return self[key]
        }
        set {
            self.updateOptionalValue(newValue, forKey: key)
        }
    }
}

extension Dictionary where Key: StringProtocol {

    subscript(keyPath keyPath: KeyPath) -> Any? {
        get {
            switch keyPath.headAndTail() {
            case nil:
                // key path is empty.
                return nil
            case let (head, remainingKeyPath)? where remainingKeyPath.isEmpty:
                // Reached the end of the key path.
                let key = Key(string: head)
                return self[key]
            case let (head, remainingKeyPath)?:
                // Key path has a tail we need to traverse.
                let key = Key(string: head)
                switch self[key] {
                case let nestedDict as [Key: Any]:
                    // Next nest level is a dictionary.
                    // Start over with remaining key path.
                    return nestedDict[keyPath: remainingKeyPath]
                default:
                    // Next nest level isn't a dictionary.
                    // Invalid key path, abort.
                    return nil
                }
            }
        }
    }
}

// Needed because Swift 3.0 doesn't support extensions with concrete
// same-type requirements (extension Dictionary where Key == String).
protocol StringProtocol {
    init(string s: String)
}

extension String: StringProtocol {
    init(string s: String) {
        self = s
    }
}

struct KeyPath {
    var segments: [String]

    var isEmpty: Bool { return segments.isEmpty }
    var path: String {
        return segments.joined(separator: ".")
    }

    /// Strips off the first segment and returns a pair
    /// consisting of the first segment and the remaining key path.
    /// Returns nil if the key path has no segments.
{'fraction_non_alphanumeric': 0.08362573099415205, 'fraction_numerical': 0.004678362573099415, 'mean_word_length': 1.6421215242018539, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, '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': '6867794', 'n_tokens_mistral': 1345, 'n_tokens_neox': 1261, 'n_words': 470}