+{"identifier":{"url":"doc:\/\/dev.validator.ValidatorCore\/documentation\/ValidatorCore\/custom-validation-rule","interfaceLanguage":"swift"},"sections":[],"abstract":[{"text":"ValidatorCore is designed to be extensible. If the built-in validation rules do not meet your needs, you can create custom validation rules tailored to your application.","type":"text"}],"hierarchy":{"paths":[["doc:\/\/dev.validator.ValidatorCore\/documentation\/ValidatorCore"]]},"kind":"article","primaryContentSections":[{"content":[{"text":"Overview","anchor":"overview","type":"heading","level":2},{"type":"paragraph","inlineContent":[{"type":"text","text":"This guide will show you how to create, use, and test a custom rule."}]},{"text":"Step 1: Conform to IValidationRule","level":2,"type":"heading","anchor":"Step-1-Conform-to-IValidationRule"},{"inlineContent":[{"text":"All validation rules in ValidatorCore conform to the IValidationRule protocol. It requires specifying the input type and implementing a validate function.","type":"text"}],"type":"paragraph"},{"syntax":"swift","type":"codeListing","code":["import ValidatorCore","","struct ContainsDigitRule: IValidationRule<String> {"," let error: String",""," func validate(input: String) -> Bool {"," if input.rangeOfCharacter(from: .decimalDigits) != nil {"," return true"," } else {"," return false"," }"," }","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Explanation:"}]},{"items":[{"content":[{"inlineContent":[{"code":"IValidationRule<String>","type":"codeVoice"},{"text":" – our rule will validate strings.","type":"text"}],"type":"paragraph"}]},{"content":[{"type":"paragraph","inlineContent":[{"code":"error","type":"codeVoice"},{"type":"text","text":" – the message returned if validation fails."}]}]},{"content":[{"inlineContent":[{"code":"validate(input:)","type":"codeVoice"},{"type":"text","text":" – the core logic. Here, we check if the input contains at least one digit."}],"type":"paragraph"}]}],"type":"unorderedList"},{"anchor":"Step-2-Use-Your-Custom-Rule","level":2,"text":"Step 2: Use Your Custom Rule","type":"heading"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Once the rule is defined, you can use it with Validator just like any built-in rule:"}]},{"type":"codeListing","code":["let validator = Validator()","let password = \"Password123\"","","let result = validator.validate("," input: password,"," rule: ContainsDigitRule(error: \"Password must contain at least one number\")",")","","switch result {","case .success:"," print(\"Password is valid ✅\")","case .failure(let error):"," print(\"Password is invalid ❌: \\(error.description)\")","}"],"syntax":"swift"},{"inlineContent":[{"type":"text","text":"Explanation:"}],"type":"paragraph"},{"type":"unorderedList","items":[{"content":[{"inlineContent":[{"text":"The custom rule integrates seamlessly with the existing validation workflow.","type":"text"}],"type":"paragraph"}]},{"content":[{"type":"paragraph","inlineContent":[{"text":"Validation result handling remains the same as with built-in rules.","type":"text"}]}]}]},{"type":"heading","anchor":"Step-3-Combining-Custom-and-Built-in-Rules","level":2,"text":"Step 3: Combining Custom and Built-in Rules"},{"type":"paragraph","inlineContent":[{"type":"text","text":"You can combine custom rules with built-in rules for more complex validation logic:"}]},{"syntax":"swift","type":"codeListing","code":["let password = \"Password123\"","","let rules: [any IValidationRule<String>] = ["," NonEmptyValidationRule(error: \"Password cannot be empty\"),"," LengthValidationRule(min: 8, max: 20, error: \"Password must be 8-20 characters\"),"," ContainsDigitRule(error: \"Password must contain at least one number\")","]","","let validator = Validator()","","let result = validator.validate(input: password, rules: rules)"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Explanation:"}]},{"type":"unorderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Each rule validates one specific aspect of the input (e.g., non-empty, length, contains a digit)."}]}]},{"content":[{"inlineContent":[{"type":"text","text":"The Validator applies each rule independently."}],"type":"paragraph"}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"This approach keeps rules focused, reusable, and simple, while Validator handles iterating through multiple rules."}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"You can freely mix custom and built-in rules to create comprehensive validation logic without combining rules inside the rules themselves."}]}]}]},{"anchor":"Tips-for-Writing-Custom-Rules","level":2,"text":"Tips for Writing Custom Rules","type":"heading"},{"type":"orderedList","items":[{"content":[{"inlineContent":[{"type":"text","text":"Keep rules focused – one rule should check one condition."}],"type":"paragraph"}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Provide meaningful error messages – users should understand why input is invalid."}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Unit test your rules – write tests to ensure correct behavior under different input scenarios."}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Reuse rules – if a rule is useful in multiple places, keep it generic and reusable."}]}]}]},{"level":2,"text":"Next Steps","type":"heading","anchor":"Next-Steps"},{"inlineContent":[{"type":"text","text":"Experiment by creating rules for emails, passwords, usernames, or any custom format."}],"type":"paragraph"}],"kind":"content"}],"metadata":{"roleHeading":"Article","title":"Creating Custom Validation Rules","role":"article"},"schemaVersion":{"major":0,"patch":0,"minor":3},"references":{"doc://dev.validator.ValidatorCore/documentation/ValidatorCore":{"abstract":[],"url":"\/documentation\/validatorcore","identifier":"doc:\/\/dev.validator.ValidatorCore\/documentation\/ValidatorCore","kind":"article","type":"topic","title":"ValidatorCore","role":"collection"}}}
0 commit comments