{"id":29829904,"url":"https://github.com/chrynan/validator","last_synced_at":"2025-07-29T09:41:57.227Z","repository":{"id":88169492,"uuid":"283900572","full_name":"chRyNaN/validator","owner":"chRyNaN","description":"A Kotlin multi-platform validation library. Simple, flexible, and not tied to any framework.","archived":false,"fork":false,"pushed_at":"2024-01-20T01:57:30.000Z","size":305,"stargazers_count":13,"open_issues_count":0,"forks_count":3,"subscribers_count":0,"default_branch":"master","last_synced_at":"2024-01-21T02:56:00.618Z","etag":null,"topics":["kotlin","kotlin-library","kotlin-multi-platform","kotlin-multiplatform","kotlin-multiplatform-library","validation","validation-library","validator"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chRyNaN.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-07-30T23:56:34.000Z","updated_at":"2024-01-05T16:24:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"a5a8be1b-724c-49f3-89a5-0ddfbd66525d","html_url":"https://github.com/chRyNaN/validator","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/chRyNaN/validator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fvalidator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fvalidator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fvalidator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fvalidator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chRyNaN","download_url":"https://codeload.github.com/chRyNaN/validator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fvalidator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267665427,"owners_count":24124533,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin","kotlin-library","kotlin-multi-platform","kotlin-multiplatform","kotlin-multiplatform-library","validation","validation-library","validator"],"created_at":"2025-07-29T09:41:34.921Z","updated_at":"2025-07-29T09:41:57.218Z","avatar_url":"https://github.com/chRyNaN.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# validator\n\nA Kotlin Multi-platform Validation Library. Simple, flexible, and not tied to any particular framework. \u003cbr/\u003e\n\u003cimg alt=\"GitHub tag (latest by date)\" src=\"https://img.shields.io/github/v/tag/chRyNaN/validator\"\u003e\n\n```kotlin\nval result = validateEmail(\"example@example.com\")\n\nif (result.isValid) {\n    // ...\n}\n```\n\n## Introduction\n\nThis library has two fundamental pieces: `Validator` and `ValidationResult`. The `validator-core` module is the base\nmodule and contains everything necessary for creating and working with `Validators`, including the `Validator`\nand `ValidationResult` types.\n\n### Validator\n\nThe `Validator` type is a simple interface that takes in a type `T`, performs validation on that type, and returns\na `ValidationResult` of type `R`:\n\n```kotlin\ninterface Validator\u003cT, R\u003e {\n\n    fun validate(input: T): ValidationResult\u003cR\u003e\n}\n```\n\nSo a `Validator` can be used like so:\n\n```kotlin\nval result = validator.validate(\"exampleInput\")\n```\n\nThe `Validator` interface also provides the following operator function which just delegates to the `validate` function:\n\n```kotlin\noperator fun invoke(input: T): ValidationResult\u003cR\u003e = validate(input)\n```\n\nThis way, a `Validator` can also be used like so:\n\n```kotlin\nval result = validator(\"exampleInput\")\n```\n\n#### Generic Types\n\nThe `Validator` interface takes two generic type parameters `\u003cT, R\u003e`. This allows `Validators` to return a different\nvalue than they take in as their input and can be especially useful for `Validators` that take in nullable types for\ntheir input and wish to return a non-null type for their output. This works because the returned value is only available\nfor a `ValidationResult.Success` result.\n\nFor example, consider the following `Validator` that takes in a nullable type of `String?` and returns a non-null type\nof `String`:\n\n```kotlin\nclass NonNullStringValidator : Validator\u003cString?, String\u003e {\n\n    override fun validate(input: String?) = if (input == null) Invalid() else Valid(input)\n}\n```\n\n### ValidationResult\n\nThe `ValidationResult` type is a sealed class with two sub-classes: `Valid` and `Invalid`. Obviously, the `Valid` type\nshould be returned from a `Validator` when the validation succeeded, and the `Invalid` when the validation failed.\n\nChecking for the `ValidationResult` type is as simple as using Kotlin's `is` keyword:\n\n```kotlin\nval result = validator(input)\n\nif (result is ValidationResult.Valid) {\n}\nif (result is ValidationResult.Invalid) {\n}\n```\n\nOr if only the condition is required, then the `isValid` and `isInvalid` convenience functions can be used:\n\n```kotlin\nval result = validator(input)\n\nif (result.isValid) {\n}\nif (result.isInvalid) {\n}\n```\n\n#### Valid\n\nThe `Valid` class has a single `value` property which contains the successfully validated input to a `Validator`.\n\n```kotlin\nval result = validateNonNullString(\"nonNullStringInput\")\n\nwhen (result) {\n    is ValidationResult.Valid -\u003e performSuccessAction(result.value)\n}\n```\n\nTo create a `Valid` object instance, simply call the constructor function with the return value:\n\n```kotlin\nValid(validatedInput)\n```\n\n#### Invalid\n\nThe `Invalid` class has an `errors` property which is a Kotlin `Collection` of `ValidationError`. Accessing these errors\nis just as simple as accessing a `Valid.value` property:\n\n```kotlin\nval result = validateNonNullString(null)\n\nwhen (result) {\n    is ValidationResult.Invalid -\u003e performFailedAction(result.errors)\n}\n```\n\nTo create an `Invalid` object instance, simply call one of the constructor functions with the errors encountered:\n\n```kotlin\nInvalid(errorOne, errorTwo)\n// Or\nInvalid(listOf(errorOne, errorTwo))\n```\n\n#### ValidationError\n\nThe `ValidationError` type is a simple interface with an optional `details` property:\n\n```kotlin\ninterface ValidationError {\n\n    val details: String?\n}\n```\n\n**Note:** `ValidationError` implementations can be\nKotlin [Exceptions](https://kotlinlang.org/docs/tutorials/kotlin-for-py/exceptions.html) but they are not thrown from\na `Validator` and instead are wrapped in a `ValidationResult.Invalid` class and returned.\n\nA `ValidationError` implementation can be whatever is required, but a common pattern is to use sealed classes:\n\n```kotlin\nsealed class ExampleError(override val details: String? = null) : ValidationError {\n\n    object Null : ExampleError()\n\n    object TooShort : ExampleError()\n\n    object TooLong : ExampleError()\n\n    data class InvalidCharacters(val characters: List\u003cChar\u003e) : ExampleError()\n}\n```\n\nThere's a convenience operator function on the `ValidationResult` class to determine if it is an `Invalid` instance and\ncontains the provided `ValidationError`:\n\n```kotlin\nval result = validate(input)\n\nif (result.contains(ExampleError.Null)) {\n}\n```\n\n## Common Validators\n\nThe `validator-core` module contains everything necessary to create and work with validation logic. But sometimes more\nspecific functionality is required. That's why this library contains separate modules for extra functionality and\nspecific use cases. With this approach, the User can choose which functionality they utilize.\n\nCurrently, the following modules are available:\n\n* `validator-core` - The common code and base for the whole library.\n* `validator-dynamic-string` - A Kotlin DSL approach for creating a Validator for `String` input.\n* `validator-email` - Provides validation for determining whether a `String` is in a valid Email format.\n* `validator-field` - An extension on the `validator-core` module, providing a `FieldValidationError` which associates a\n  Kotlin property on a class.\n* `validator-mac` - Provides validation for determining whether a `String` is in a valid MAC Address format.\n* `validator-phone` - Provides validation for determining whether a `String` is in a valid Phone Number format.\n* `validator-web` - Provides `Validators` for web-based `String` formats, such as, URLs, URIs, and IP Addresses.\n\n## Building the library\n\nThe library is provided through [Repsy.io](https://repsy.io). Checkout\nthe [releases page](https://github.com/chRyNaN/validator/releases) to get the latest version. \u003cbr/\u003e\n\u003cimg alt=\"GitHub tag (latest by date)\" src=\"https://img.shields.io/github/v/tag/chRyNaN/validator\"\u003e\n\n### Repository\n\n```kotlin\nrepositories {\n    maven { url = uri(\"https://repo.repsy.io/mvn/chrynan/public\") }\n}\n```\n\n### Dependencies\n\n**Core:**\n\n```kotlin\nimplementation(\"com.chrynan.validator:validator-core:$VERSION\")\n```\n\n**Dynamic String:**\n\n```kotlin\nimplementation(\"com.chrynan.validator:validator-dynamic-string:$VERSION\")\n```\n\n**Email:**\n\n```groovy\nimplementation \"com.chrynan.validator:validator-email:$VERSION\"\n```\n\n**Field:**\n\n```kotlin\nimplementation(\"com.chrynan.validator:validator-field:$VERSION\")\n```\n\n**Mac Address:**\n\n```kotlin\nimplementation(\"com.chrynan.validator:validator-mac:$VERSION\")\n```\n\n**Phone Number:**\n\n```kotlin\nimplementation(\"com.chrynan.validator:validator-phone:$VERSION\")\n```\n\n**Web:**\n\n```kotlin\nimplementation(\"com.chrynan.validator:validator-web:$VERSION\")\n```\n\n## Documentation\n\nMore detailed documentation is available in the [docs](docs) folder. The entry point to the documentation can be\nfound [here](docs/index.md).\n\n## Contributing\n\nContributions are welcome and encouraged! Please consider the following when contributing code:\n\n* All validation code must be written in the `commonMain` source set. If this is not possible, then each target platform\n  must have an actual implementation.\n* All public facing code must have detailed KDoc comments.\n* All code must have corresponding tests written in the `commonTest` source set.\n* Follow existing coding conventions for this repository.\n* If submitting a new `Validator`, make sure it is a common use case.\n* Code reviews must maintain a productive, courteous, and respectful atmosphere.\n* Self review code before submitting a PR.\n* All CI builds must pass for a PR to be merged.\n* All submitted code will be subject to this repository's [license](LICENSE).\n\n## Why this library?\n\nIt's true, there are many Kotlin validation libraries. However, I found myself unsatisfied with the current\nimplementations for the following reasons:\n\n* Tied to a framework.\n    * Most of the available validation libraries were built around UI Components from frameworks like Android.\n* Not multi-platform.\n    * The available validation libraries typically are for either a framework, like Android, or specifically for the\n      JVM.\n    * There's no reason why the code can't be written for Kotlin Multi-platform, so that it can be used anywhere.\n* No flexibility.\n    * The current libraries are all or nothing. Including functionality that might not be required.\n    * Forced to conform to a particular DSL approach without the ability to extend the functionality.\n\nThis library aims to resolve the issues with the other libraries by:\n\n* Not being tied to a framework.\n* Supporting Kotlin Multi-platform.\n* Providing flexibility to choose functionality.\n* Being extensible.\n* Providing commonly used `Validators`.\n\n## License\n\n```\nCopyright 2021 chRyNaN\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrynan%2Fvalidator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrynan%2Fvalidator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrynan%2Fvalidator/lists"}