diff --git a/src/classes/validationschema.gd b/src/classes/validationschema.gd index 9c24f30..2925522 100644 --- a/src/classes/validationschema.gd +++ b/src/classes/validationschema.gd @@ -40,22 +40,56 @@ func _init(core_new: Core, schema_new: Dictionary, data_new: Dictionary, parent_ data = data_new # Check Dictionary - for key in schema: - if typeof(key) != TYPE_STRING: logger.error(core.stringify_variables("Could not parse schema: Schema key %key% is not of type String", { "key": key })) - elif typeof(schema[key]) != TYPE_OBJECT: logger.error(core.stringify_variables("Could not parse schema: Schema value of %key% is not of type Object", { "key": key })) - elif schema[key].get_class() != "Node": logger.error(core.stringify_variables("Could not parse schema: Schema value of %key% is not of type Node", { "key": key })) + _check_dictionary_recursive(schema) + +func _check_dictionary_recursive(parent: Dictionary, path: String = "") -> bool: + var success: bool = false + for key in parent: + if typeof(key) != TYPE_STRING: + logger.error(core.stringify_variables("Could not parse schema: Schema key %key% is not of type String", { "key": path + "/" + key })) + success = false + continue + match(typeof(parent[key])): + TYPE_OBJECT: + if parent[key].get_class() != "Node": + logger.error(core.stringify_variables("Could not parse schema: Schema value of %key% is not of type Node", { "key": path + "/" + key })) + success = false + continue + TYPE_DICTIONARY: + _check_dictionary_recursive(parent[key], path + "/" + key) + _: + logger.error(core.stringify_variables("Could not parse schema: Schema value of %key% is not of type CoreValidationSingle or Dictionary", { "key": path + "/" + key })) + success = false + continue + + return success func evaluate() -> Array[String]: var random: String = str(randf()).repeat(50) var failed: Array[String] = [] - for key in schema: - if data.get(key, random) == random: - failed.append(core.stringify_variables("Key %key% is present in schema but missing in data", { "key": key })) - else: - schema[key].data = data[key] - if !schema[key].evaluate(): - logger.error(core.stringify_variables("Validation for key %key% failed", { "key": key })) - for failure in schema[key].failures: - failed.append(key + ": " + failure) + _evaluate_recursive(random, schema) + + return failed + +func _evaluate_recursive(random: String, parent: Dictionary, path: String = "") -> Array[String]: + var failed: Array[String] = [] + for key in parent: + # Check if key exists in data + if data.get(key, random) == random: + # Does not exist, append error + failed.append(core.stringify_variables("Key %key% is present in schema but missing in data", { "key": path + "/" + key })) + else: + # Exists in data + if typeof(schema[key]) == TYPE_DICTIONARY: + # Key is of type Dictionary, allow for recursion to happen + failed.append_array(_evaluate_recursive(random, schema[key], path + "/" + key)) + else: + # Key is not of type Dictionary, evaluate against data + schema[key].data = data[key] + if !schema[key].evaluate(): + logger.error(core.stringify_variables("Validation for key %key% failed", { "key": path + "/" + key })) + for failure in schema[key].failures: + # Append failures from single + failed.append(key + ": " + failure) return failed