{"id":16773768,"url":"https://github.com/amir1376/kotlin-validator","last_synced_at":"2025-04-10T20:04:06.376Z","repository":{"id":42512702,"uuid":"462953343","full_name":"amir1376/kotlin-validator","owner":"amir1376","description":"A validator library written in kotlin","archived":false,"fork":false,"pushed_at":"2023-04-18T10:07:39.000Z","size":121,"stargazers_count":17,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T17:51:55.109Z","etag":null,"topics":["android","dsl","kotlin","kotlin-android","kotlin-dsl","kotlin-jvm","kotlin-library","translation","typesafe","validation","validation-library","validation-tool","validations","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/amir1376.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-24T00:31:09.000Z","updated_at":"2025-02-28T09:14:24.000Z","dependencies_parsed_at":"2025-02-17T23:32:53.090Z","dependency_job_id":"9f2d27cc-a3b1-4f02-bdb8-72d9407852ad","html_url":"https://github.com/amir1376/kotlin-validator","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amir1376%2Fkotlin-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amir1376%2Fkotlin-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amir1376%2Fkotlin-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amir1376%2Fkotlin-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amir1376","download_url":"https://codeload.github.com/amir1376/kotlin-validator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248287929,"owners_count":21078811,"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","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":["android","dsl","kotlin","kotlin-android","kotlin-dsl","kotlin-jvm","kotlin-library","translation","typesafe","validation","validation-library","validation-tool","validations","validator"],"created_at":"2024-10-13T06:46:56.680Z","updated_at":"2025-04-10T20:04:06.353Z","avatar_url":"https://github.com/amir1376.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp style=\"text-align:center\"\u003e\n\u003cimg width=\"75\" alt=\"logo\" src=\"static/logo.svg\"\u003e\n\u003ch1 style=\"text-align:center\"\u003eKotlin Validator\u003c/h1\u003e\n\u003c/p\u003e\n\u003cp style=\"text-align:center;color\"\u003e\nvalidate your inputs or objects with power of the kotlin typesafe builders\n\u003cbr\u003e\u003cbr\u003e\n\u003ca href=\"https://jitpack.io/#amir1376/kotlin-validator\"\u003e\n\u003cimg alt=\"Kotlin Validator Jitpack\" src=\"https://jitpack.io/v/amir1376/kotlin-validator.svg\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n## Usage\nquick introduction\n```kotlin\nval result=email.validate(\"yourEmail@gmail.com\")\nif(result.isValid){\n    println(\"provided email is valid ,user:${result.user},host:${result.host}\")\n}else{\n    println(result.reason!!.translate())\n}\n```\nor\n```kotlin\nval result=compositeRule\u003cUser\u003e{\n    User::email mustBe email\n    User::password mustBe inRange(8..64)\n}.validate(user)\nif(!result.isValid){\n    println(result[User::email]?.translate())\n    println(result[User::password]?.translate())\n}\n```\n\n\n# Setup\n## Dependency\nput this into your gradle script\n```groovy\nrepositories {\n    //...\n    maven { url \"https://jitpack.io\" }\n}\ndependencies {\n    //...\n    //android usage\n    implementation 'com.github.amir1376.kotlin-validator:android:$version'\n    \n    //core (jvm)\n    implementation 'com.github.amir1376.kotlin-validator:core:$version'\n}\n```\n\n\n\n## Android\nin your app entry point initialize validator translation\n```kotlin\nValidatedTranslation.initDefaultAndroidAdapter(context)\n    //include default translations\n    .applyDefaultTranslations()\n    \n```\n\n\n## JVM\n\nbefore any use of translation provide a TranslationAdapter\nhere is the default adapter\n```kotlin\nValidatedTranslation.initWithDefault()\n```\n\n\n# Features\n\n## Combining rules together\nyou can validate your input by multiple rules\n### Here is an example\n```kotlin\nval result=(email or empty).validate(input)\n```\n\n## Validate nested objects\nsometimes you want to validate a model\nthe library has support this too\nfor example you have the following models\n```kotlin\n    data class User(\n        val login:String,\n        val name:Name,\n        val password:String,\n        val confirmPassword:String,\n        val gender:String\n    )\n    data class Name(\n        val first:String,\n        val last:String,\n    )\n    enum class Gender{\n        Male,Female\n    }\n```\nyou can validate this with this rule\n```kotlin\n//inside a suspend function\nval userValidation=compositeRule\u003cUser\u003e{\n    User::login mustBe (startWithEnglishCharacter and inRange(6..64)) \n    User::name mustBe compositeRule\u003cName\u003e{\n        Name::first mustBe notEmpty\n        Name::last mustBe notEmpty\n    }\n    User::password mustBe (\n            containsAtLeastLowerCase(1) and\n            containsAtLeastUpperCase(1) and \n            (containsAtLeastNumber(1)) and \n            inRange(8..64)\n            )\n    User::confirmPassword mustBe sameAs(User::password)\n    User::gender mustBe oneOf\u003cGender\u003e()\n}\n//user input\nval user:User/*retrieve user object*/\nval result=userValidation.validate(user)\nif(!result.isValid){\n//    you can get reason for each property\n    result[User::login] \n}\n```\nas you can see in the above code, user password has a complex rule ,\nbut you can extract it to a variable\nand because these rules are stateless (they don't store any reference of input)\nyou can safely use this combination multiple times\n```kotlin\nval strongPassword = containsAtLeastLowerCase(1) and\n        containsAtLeastUpperCase(1) and\n        (containsAtLeastNumber(1)) and\n        inRange(8..64)\n            //.... then replace\n        User::password mustBe strongPassword\n```\n# Customization\n## Creating your own rules\nOf course, you can create your own rules with ease\nhere is an example\n```kotlin\nval phone get() = rule\u003cString\u003e{ input-\u003e\n    if(phonePattern.matchEntire(input)){\n        thenValid()\n    }else{\n        because(\"your provided phone number is not valid\")\n    }\n}\n```\n## Localization\nif your app has support of multiple language\nwhen building your rules ,you have to provide `Reason`\ninstead of raw string\n```kotlin\nobject PhoneInvalidReason:SingleReason\nval phone get() = rule\u003cString\u003e{ input-\u003e\n    if(phonePattern.matchEntire(input)){\n        thenValid()\n    }else{\n        because(PhoneInvalidReason)\n    }\n}\n```\nthen you have to provide PhoneInvalidReason translation to the adapter\n```kotlin\nValidatedTranslation.adapter.apply{\n    //declare translation here\n    //this is up to you that how you want to translate that message\n    PhoneInvalidReason::class providedBy {\n        \"your provided phone number is not valid\"\n    }\n}\n```\n\notherwise, if you are not interested on default translation approach,\nthen you can create your own translation by implementing `ValidatedTranslationAdapter`\n\n\n\n## Android support\nat the moment ,we have separated android module \nthat contains an Android translation adapter,\nit has some useful extensions to provide translation\nfrom string resources\n```kotlin\nValidator.android().apply{\n    //declare translation here\n    //this is up to you that how you want to translate that message\n    PhoneInvalidReason::class providedByResource (R.string.my_validation_phone_invalid)\n}\n```\n\nif you use this library for android, you can use default translation provided \nby the android module.\n\n\ncurrently supported languages are \n* English (default)\n* Persian\n\n\n### Coroutines support\nthe `validate` method is a suspend function\naccordingly, rules are all suspend functions too,\nso you can have suspended calls on them\nand because of that, you have to call `validate` only in a coroutine scope\nthe core artifact doesn't have any suspend calls\nthis aproach is choosen for support coroutines\n# Attention\nthis library is still under beta\nso that may have bugs\n\n## Contribution\nyou can consider a pull request,\nif you see unexpected behaviors in the library\nor write more common plugins\n\notherwise, if you have suggestions or have seen something weird out there (😁),\nplease submit an issue\n \n### TODOS\n* write tests\n* write more plugins\n* support kotlin multiplatform\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famir1376%2Fkotlin-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famir1376%2Fkotlin-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famir1376%2Fkotlin-validator/lists"}