{"id":26945591,"url":"https://github.com/tynn-xyz/astring","last_synced_at":"2025-07-28T12:03:15.824Z","repository":{"id":45020939,"uuid":"319101606","full_name":"tynn-xyz/AString","owner":"tynn-xyz","description":"A context aware string abstraction for Android - implemented with Kotlin for Java","archived":false,"fork":false,"pushed_at":"2024-04-18T07:15:44.000Z","size":608,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-28T12:02:57.495Z","etag":null,"topics":["android","androidx","appcompat","java","kotlin","material","strings"],"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/tynn-xyz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2020-12-06T18:23:06.000Z","updated_at":"2025-06-25T17:06:05.000Z","dependencies_parsed_at":"2022-09-08T11:30:27.925Z","dependency_job_id":"735877d7-feb7-4822-9690-eb88cac2c0f6","html_url":"https://github.com/tynn-xyz/AString","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/tynn-xyz/AString","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tynn-xyz%2FAString","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tynn-xyz%2FAString/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tynn-xyz%2FAString/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tynn-xyz%2FAString/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tynn-xyz","download_url":"https://codeload.github.com/tynn-xyz/AString/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tynn-xyz%2FAString/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267512942,"owners_count":24099628,"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-28T02:00:09.689Z","response_time":68,"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":["android","androidx","appcompat","java","kotlin","material","strings"],"created_at":"2025-04-02T19:15:24.009Z","updated_at":"2025-07-28T12:03:15.803Z","avatar_url":"https://github.com/tynn-xyz.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AString\n[![Build][build-shield]][build]\n[![Download][download-shield]][download]\n[![API][api-shield]][api]\n###### A context aware parcelable string abstraction for _Android_\n\n    interface AString : Parcelable {\n        fun invoke(context: Context): CharSequence?\n    }\n\nThe main use-case is to provide a generic string data type for\ninter-layer communication and state management. Therefore every\nimplementation should provide meaningful `equals` and `hashCode`\nimplementations to be efficient.\n\nIf an API does not guaranty this efficiency, it is be annotated with\nthe `@InefficientAStringApi` opt-in marker.\n\n## Installation\n\nAll packages are available in _Maven Central_.\nOnce a single dependency is declared with a specific version,\nthe version for every other dependency is provided implicitly with a BOM.\n\n    dependencies {\n        implementation \"xyz.tynn.astring:astring:$astringVersion\"\n    }\n\n## Usage\n\n    val Context.string by AString(\"value\")\n\nThe `AString` itself should be used in place of a `CharSequence`,\njust like string resource would be used by the framework.\n\n    textView.setText(aString)\n\nIf `null`, `ID_NULL` or `0` are used to create an `AString` instance,\nthe `AString.Null` singleton is returned.\n\n### `AString` Resources and Providers\n\nProbably the most common use-case is providing string resources to the UI.\nSo there are equivalents for `getString()` and `getText()` provided by\n\n    StringResource(R.string.res_id)\n    StringResource(R.string.res_id, \"arg\")\n    TextResource(R.string.res_id)\n\nand equivalents for `getQuantityString()` and `getQuantityText()` provided by\n\n    QuantityStringResource(R.plurals.res_id, 0)\n    QuantityStringResource(R.plurals.res_id, 1, \"arg\")\n    QuantityTextResource(R.plurals.res_id, 2)\n\nWhile `AppId` or `AppVersion` just provide the data from the `Context` itself.\n\n### `AString` Transformers\n\nSince the `AString` represent any generic `CharSequence`, it might be useful\nto transform the value before its use.\n\n    aString.format(\"arg\", AppId)\n    aString.ifNull(\"value\")\n    aString.nullIfBlank()\n    aString.mapToString()\n    aString.trim()\n\n### `AString` Reducers\n\nIf multiple instances of `AString` are provided, it is also possible to reduce\nthese to a single and single `AString`.\n\n    aStrings.firstNonBlank()\n    aStrings.joinNonNull(',')\n\nThe provided values of the `Iterable` are provided lazily.\n\n### `@InefficientAStringApi AString` usages\n\nGeneric `AString.Provider`, `AString.Transformer` and `AString.Reducer` are\nsupported but do not provide comparability or readable string representations. \n\n    AString { it.packageName }\n    aString.map { it?.toString() }\n    aStrings.reduce { it.singleOrNull() }\n\n### _Jetpack_ Compose extension functions\n[![API][compose-shield]][compose]\n\nWithin a `@Composable` function the `asString()` extension functions\nautomatically converts an `AString` to a `String`.\n\n    Text(text = aString.asString())\n\nThe `@ExperimentalTextApi asAnnotatedString()` extension functions converts\nan `AString` to an `AnnotatedString`, including as many built-in spans as\npossible.\n\n    Text(text = aString.asAnnotatedString())\n\n#### Artifact\n\n    dependencies {\n        implementation 'xyz.tynn.astring:compose'\n    }\n\n### _Android_ `View` widget extension functions\n\nThere are several extension functions for widget methods taking a\n`CharSequence?` as an argument.\n_Core_, _AppCompat_ and _Material_ components should be fully covered.\n\n#### Artifacts\n\n    dependencies {\n        implementation 'xyz.tynn.astring:core'\n        implementation 'xyz.tynn.astring:appcompat'\n        implementation 'xyz.tynn.astring:material'\n    }\n\n### _Android_ Data Binding\n\nSome of the core extension functions are annotated with `@BindingAdapter`\nand therefore provide simple setters for one-way data binding.\n\n    android:text=\"@{aString}\"\n\nSince `AString` is not directly intended for input methods, these functions\nare not optimized for two-way data binding and should not be used in that context.\nTo support two-way data binding use the `AStringBinding` utility instead.\n\n    android:text=\"@={AStringBinding.load(context, aString)}\"\n\n#### Artifact\n\n    dependencies {\n        implementation 'xyz.tynn.astring:binding'\n    }\n\n### Testing\n\nCustom `AString` implementations require an efficient `Parcelable`\nimplementation. To simplify testing these, the `AStringAssert` provides\nstatic assertions for different levels of efficiency.\n\n    assertParcelableAStringIdentity(aString)\n    assertParcelableAStringEquality(aString)\n    assertParcelableAStringInvocation(aString)\n\nWhile testing for equality or identity ensures that both instances are equal or\nthe same, `assertParcelableAStringInvocation()` ensures that at least the\nresult of the recovered `AString` is equal to the original result.\n\n#### Artifact\n\n    dependencies {\n        androidTestImplementation textFixtures('xyz.tynn.astring:astring')\n    }\n\n## License\n\n    Copyright (C) 2020-2024 Christian Schmitz\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n        http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n\n  [api]: https://asapi.gigalixirapp.com/xyz.tynn.astring/astring\n  [api-shield]: https://img.shields.io/endpoint?url=https://asapi.gigalixirapp.com/xyz.tynn.astring/astring@json\n  [build]: https://github.com/tynn-xyz/AString/actions\n  [build-shield]: https://img.shields.io/github/actions/workflow/status/tynn-xyz/AString/build.yml\n  [compose]: https://asapi.gigalixirapp.com/xyz.tynn.astring/compose\n  [compose-shield]: https://img.shields.io/endpoint?url=https://asapi.gigalixirapp.com/xyz.tynn.astring/compose@json\n  [download]: https://search.maven.org/search?q=xyz.tynn.astring\n  [download-shield]: https://img.shields.io/maven-central/v/xyz.tynn.astring/core\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftynn-xyz%2Fastring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftynn-xyz%2Fastring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftynn-xyz%2Fastring/lists"}