{"id":13537006,"url":"https://github.com/05nelsonm/component-value-clazz","last_synced_at":"2026-03-02T00:31:35.846Z","repository":{"id":65509304,"uuid":"587277274","full_name":"05nelsonm/component-value-clazz","owner":"05nelsonm","description":"Kotlin Multiplatform abstraction functionally equivalent to a Kotlin value class but will compile to platform specific code","archived":false,"fork":false,"pushed_at":"2023-01-17T11:11:17.000Z","size":93,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-26T18:38:10.327Z","etag":null,"topics":["android","android-lib","android-library","android-libs","kotlin","kotlin-android","kotlin-library","kotlin-multiplatform","kotlin-multiplatform-library","kotlin-multiplatform-mobile"],"latest_commit_sha":null,"homepage":"https://kotlin-components.matthewnelson.io","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/05nelsonm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2023-01-10T11:31:01.000Z","updated_at":"2023-08-18T20:11:41.000Z","dependencies_parsed_at":"2023-02-10T09:16:04.329Z","dependency_job_id":null,"html_url":"https://github.com/05nelsonm/component-value-clazz","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/05nelsonm/component-value-clazz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/05nelsonm%2Fcomponent-value-clazz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/05nelsonm%2Fcomponent-value-clazz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/05nelsonm%2Fcomponent-value-clazz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/05nelsonm%2Fcomponent-value-clazz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/05nelsonm","download_url":"https://codeload.github.com/05nelsonm/component-value-clazz/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/05nelsonm%2Fcomponent-value-clazz/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29988040,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T22:42:38.399Z","status":"ssl_error","status_checked_at":"2026-03-01T22:41:51.863Z","response_time":124,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["android","android-lib","android-library","android-libs","kotlin","kotlin-android","kotlin-library","kotlin-multiplatform","kotlin-multiplatform-library","kotlin-multiplatform-mobile"],"created_at":"2024-08-01T09:00:53.406Z","updated_at":"2026-03-02T00:31:35.817Z","avatar_url":"https://github.com/05nelsonm.png","language":"Kotlin","funding_links":[],"categories":["Libraries"],"sub_categories":["Utility"],"readme":"# component-value-clazz\n[![badge-license]][url-license]\n[![badge-latest-release]][url-latest-release]\n\n[![badge-kotlin]][url-kotlin]\n\n![badge-platform-android]\n![badge-platform-jvm]\n![badge-platform-js]\n![badge-platform-js-node]\n![badge-platform-linux]\n![badge-platform-macos]\n![badge-platform-ios]\n![badge-platform-tvos]\n![badge-platform-watchos]\n![badge-platform-wasm]\n![badge-platform-windows]\n![badge-support-android-native]\n![badge-support-apple-silicon]\n![badge-support-js-ir]\n![badge-support-linux-arm]\n![badge-support-linux-mips]\n\nA small library that provides a functionally equivalent alternative to Kotlin's \n`value class` via inheritance.\n\nKotlin's `value class` is powerful and I use them pervasively, but there are some caveats \nto using them.\n - Kotlin `value class` does not compile to other languages (e.g. Java or Js). Instead, \n   the underlying type of the `value class` is what consumers from those languages see. If \n   you wish to retain the type and expose/accept it in your public API(s), this becomes \n   problematic for non-Kotlin consumers of your code.\n - If your Kotlin `value class` inherits from an `interface` or `sealed interface`, it\n   loses the boxing/unboxing properties that make them so amazing! They become equivalant\n   to a regular `class`, with the downside of them not compiling to platform specific\n   code (as mentioned above).\n     - If you're using Kotlin `value class`es that implement `interface`es, especially if they\n       are a part of your public API(s), this library is for you!\n\nAs a library creator, I've learned that using Kotlin's `value class` in your public API(s) \n(such as `kotlin.Result`) comes with challenges; I've begun limiting their usage to `internal`\nonly.\n\nEnsuring that consumers of your code have a plesant experience, whether they are using Kotlin \nor not, was the motivation for creating this. **Enjoy!**\n\nA full list of `kotlin-components` projects can be found [HERE][url-kotlin-components]\n\n### Example Usages\n\n```kotlin\nfun main() {\n    val id = \"123456789\"\n    val userId = UserId(id)\n\n    println(userId) // \u003e\u003e UserId(value=123456789)\n    println(UserId.equals(id)) // \u003e\u003e false\n    println(id.hashCode()) // \u003e\u003e -1867378635\n    println(userId.hashCode()) // \u003e\u003e -1867378635\n}\n\nclass UserId(val id: String): ValueClazz(id)\n```\n\nUsage in sealed classes\n```kotlin\nfun main() {\n    println(Data.Loading) // \u003e\u003e Loading\n    println(Data.UserId(\"5\")) // \u003e\u003e UserId(value=5)\n    println(Data.UserNames(listOf(\"matthew\", \"nelson\"))) // \u003e\u003e UserNames(value=[matthew, nelson])\n}\n\nsealed class Data(value: Any): ValueClazz(value) {\n    object Loading: Data(NoValue())\n    class UserId(val id: String): Data(id)\n    class UserNames(val names: List\u003cString\u003e): Data(names)\n}\n```\n\nObjects objects objects!\n\n```kotlin\nfun main() {\n    println(Objects.Loading.hashCode()) // \u003e\u003e 1859374258\n    println(Objects.Success.hashCode()) // \u003e\u003e 807752428\n    println(Objects.Loading.equals(Objects.Success)) // \u003e\u003e false\n    println(Objects.Loading) // \u003e\u003e Loading\n    println(Objects.Success) // \u003e\u003e Success\n    println(Objects.Failure) // \u003e\u003e Failure\n}\n\nsealed class Objects: ValueClazz(NoValue()) {\n    object Loading: Objects()\n    object Success: Objects()\n    object Failure: Objects()\n}\n```\n\nReal world\n```kotlin\nsealed class Address(@JvmField val value: String): ValueClazz(value) {\n    abstract fun canonicalHostname(): String\n}\n\nsealed class IpAddress(value: String): Address(value)\n\nclass IpV4Address\n@Throws(IllegalArgumentException::class)\nconstructor(value: String): IpAddress(value) {\n\n    init {\n        require(value.matches(IPV4_REGEX)) {\n            \"$value is not a valid IPv4 address\"\n        }\n    }\n\n    override fun canonicalHostname(): String = value\n}\n\nclass IpV6Address\n@Throws(IllegalArgumentException::class)\nconstructor(value: String): IpAddress(value) {\n\n    init {\n        require(value.matches(IPV6_REGEX)) {\n            \"$value is not a valid IPv6 address\"\n        }\n    }\n\n    override fun canonicalHostname(): String = \"[$value]\"\n}\n```\n\n### Get Started\n\n\u003c!-- TAG_VERSION --\u003e\n\n```kotlin\n// build.gradle.kts\ndependencies {\n    // if ValueClazz will be a part of your public API (library devs),\n    // use api instead of implementation.\n    implementation(\"io.matthewnelson.kotlin-components:value-clazz:0.1.0\")\n}\n```\n\n\u003c!-- TAG_VERSION --\u003e\n\n```groovy\n// build.gradle\ndependencies {\n    // if ValueClazz will be a part of your public API (library devs),\n    // use api instead of implementation.\n    implementation \"io.matthewnelson.kotlin-components:value-clazz:0.1.0\"\n}\n```\n\n### Kotlin Version Compatibility\n\n\u003c!-- TAG_VERSION --\u003e\n\n| value-clazz | kotlin |\n|:-----------:|:------:|\n|    0.1.0    | 1.8.0  |\n\n### Git\n\nThis project utilizes git submodules. You will need to initialize them when\ncloning the repository via:\n\n```bash\n$ git clone --recursive https://github.com/05nelsonm/component-value-clazz.git\n```\n\nIf you've already cloned the repository, run:\n```bash\n$ git checkout master\n$ git pull\n$ git submodule update --init\n```\n\nIn order to keep submodules updated when pulling the latest code, run:\n```bash\n$ git pull --recurse-submodules\n```\n\n\u003c!-- TAG_VERSION --\u003e\n[badge-latest-release]: https://img.shields.io/badge/latest--release-0.1.0-blue.svg?style=flat\n[badge-license]: https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat\n\n\u003c!-- TAG_DEPENDENCIES --\u003e\n[badge-kotlin]: https://img.shields.io/badge/kotlin-1.8.0-blue.svg?logo=kotlin\n\n\u003c!-- TAG_PLATFORMS --\u003e\n[badge-platform-android]: http://img.shields.io/badge/-android-6EDB8D.svg?style=flat\n[badge-platform-jvm]: http://img.shields.io/badge/-jvm-DB413D.svg?style=flat\n[badge-platform-js]: http://img.shields.io/badge/-js-F8DB5D.svg?style=flat\n[badge-platform-js-node]: https://img.shields.io/badge/-nodejs-68a063.svg?style=flat\n[badge-platform-linux]: http://img.shields.io/badge/-linux-2D3F6C.svg?style=flat\n[badge-platform-macos]: http://img.shields.io/badge/-macos-111111.svg?style=flat\n[badge-platform-ios]: http://img.shields.io/badge/-ios-CDCDCD.svg?style=flat\n[badge-platform-tvos]: http://img.shields.io/badge/-tvos-808080.svg?style=flat\n[badge-platform-watchos]: http://img.shields.io/badge/-watchos-C0C0C0.svg?style=flat\n[badge-platform-wasm]: https://img.shields.io/badge/-wasm-624FE8.svg?style=flat\n[badge-platform-windows]: http://img.shields.io/badge/-windows-4D76CD.svg?style=flat\n[badge-support-android-native]: http://img.shields.io/badge/support-[AndroidNative]-6EDB8D.svg?style=flat\n[badge-support-apple-silicon]: http://img.shields.io/badge/support-[AppleSilicon]-43BBFF.svg?style=flat\n[badge-support-js-ir]: https://img.shields.io/badge/support-[js--IR]-AAC4E0.svg?style=flat\n[badge-support-linux-arm]: http://img.shields.io/badge/support-[LinuxArm]-2D3F6C.svg?style=flat\n[badge-support-linux-mips]: http://img.shields.io/badge/support-[LinuxMIPS]-2D3F6C.svg?style=flat\n\n[url-latest-release]: https://github.com/05nelsonm/component-value-clazz/releases/latest\n[url-license]: https://www.apache.org/licenses/LICENSE-2.0.txt\n[url-kotlin]: https://kotlinlang.org\n[url-kotlin-components]: https://kotlin-components.matthewnelson.io\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F05nelsonm%2Fcomponent-value-clazz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F05nelsonm%2Fcomponent-value-clazz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F05nelsonm%2Fcomponent-value-clazz/lists"}