         
         return Rule.simple(evaluator: ruleFactory)
     }
-    
 }
 
 extension Sequence where Iterator.Element == (key: String, value: Any) {

    /// - Throws: `JSONFactoryError` when a mandatory key is missing. For more information on
    /// the mandatory keys, check the JSON schema documentation 
    public func component(from json: JSONObject) throws -> Component? {
        guard let structure = json[Key.structure] as? JSONObject else {
            throw JSONFactoryError.missing(json, Key.structure)
        }
        
        return try component(fromStructure: structure)
    }
    
    private func component(fromStructure json: JSONObject) throws -> Component? {
        guard let type = json[Key.type] as? String else {
            throw JSONFactoryError.missing(json, Key.type)
        }
        
        let meta = json[Key.meta] as? JSONObject
        let children = json[Key.children] as? [JSONObject] ?? []
        let componentChildren = try children.flatMap { try component(fromStructure: $0) }
        let componentResult = component(from: type, meta: meta, children: componentChildren)
        
        if let rule = JSONFactory.rule(from: json[Key.rule] as Any, using: ruleFactory),
           let componentResult = componentResult {
            return Component.rule(rule: rule, component: componentResult)
        }

    case missing(JSONObject, String)
}

fileprivate enum DocumentKey {
    static let structure = "structure"
}

fileprivate enum ComponentKey {
    static let type = "type"
    static let meta = "meta"
    static let children = "children"
    static let rule = "rule"
}

fileprivate enum RuleKey {
    static let and = "AND"
    static let or = "OR"
    static let not = "NOT"
}

/// A factory that wraps `Component` builder closures (ViewFactoryBuilder, `WrapperFactoryBuilder`,
/// `ClusterFactoryBuilder` & `RuleFactoryBuilder`) and uses them to produce `Component`s
public final class JSONFactory {
    
    /// A factory closure to build a view `Component`
    public typealias ViewFactoryBuilder = (ComponentMeta?) -> Component
    
