|
| 1 | +# ClassFieldEquality |
| 2 | +Kotlin library to validate equality of Kotlin classes between Clean Arch layers. |
| 3 | +Suitable for Android and Kotlin. |
| 4 | + |
| 5 | +## Motivation |
| 6 | + |
| 7 | +In Clean Architecture one has to create Kotlin-only library for domain layer. |
| 8 | + |
| 9 | +Other libraries, such as ORM, may require putting annotations onto your classes - but you are restricted to do so by Clean Arch. |
| 10 | + |
| 11 | +So you need to create copies. For regular classes you can get away with extension. |
| 12 | + |
| 13 | +However, if you use data classes or need to extend from Realm objects, you can only copy class definition completely. |
| 14 | + |
| 15 | +In this case, there are no compile-time guarantees that these classes are actually same. |
| 16 | + |
| 17 | +Here comes my ClassFieldEquality library. |
| 18 | + |
| 19 | +Relevant discussions/articles: |
| 20 | +- [SO: Extend data class in Kotlin](https://stackoverflow.com/questions/26444145/extend-data-class-in-kotlin) |
| 21 | +- [SO: Uncle Bob's clean architecture - An entity/model class for each layer?](https://softwareengineering.stackexchange.com/questions/303478/uncle-bobs-clean-architecture-an-entity-model-class-for-each-layer) |
| 22 | +- [See Change 1](https://www.toptal.com/android/benefits-of-clean-architecture-android) |
| 23 | + |
| 24 | +## How it works |
| 25 | + |
| 26 | +It basically checks that two classes have: same amount of fields, same field types, same field names + generates mapper. That's it. |
| 27 | + |
| 28 | +Both classes can be one of: class, data class. |
| 29 | + |
| 30 | +Library itself is comprised of 3 artifacts: |
| 31 | + |
| 32 | +- Android Lint module: Executes checks w/o compilation, shows results in IDE and aborts build in case of error. |
| 33 | +- Annotation Processor module: Generates mapper (extension function) from target class to origin class. |
| 34 | +You need to run Build first. Currently aborts silently if error is detected. |
| 35 | +- Annotation module: Plain annotations (currently `@FieldEquality` only). |
| 36 | + |
| 37 | +## Adding to your project |
| 38 | + |
| 39 | +In your `build.gradle`: |
| 40 | + |
| 41 | +```gradle |
| 42 | +repositories { |
| 43 | + jcenter() |
| 44 | +} |
| 45 | +
|
| 46 | +implementation "com.alexshafir.classfieldequality:annotations:1.0.0" |
| 47 | +kapt "com.alexshafir.classfieldequality:processor:1.0.0" |
| 48 | +lintChecks "com.alexshafir.classfieldequality:lint:1.0.0" // Only on Android |
| 49 | +``` |
| 50 | + |
| 51 | +## How to use |
| 52 | + |
| 53 | +For example below no error will be shown and mapper will be generated |
| 54 | +```kotlin |
| 55 | + |
| 56 | +package com.test.app |
| 57 | +import com.alexshafir.classfieldequality.annotations.FieldEquality |
| 58 | + |
| 59 | +data class Class1( |
| 60 | + val param1:String, |
| 61 | + val param2:String |
| 62 | +) |
| 63 | + |
| 64 | +@FieldEquality(Class1::class) |
| 65 | +data class Class2( |
| 66 | + val param1:String, |
| 67 | + val param2:String |
| 68 | +) |
| 69 | + |
| 70 | +val t:Class2 = Class2("a", "b") |
| 71 | +fun test() { |
| 72 | + t.mapToOrigin() // Generated after you run Build |
| 73 | +} |
| 74 | + |
| 75 | +``` |
| 76 | + |
| 77 | +## Contributing |
| 78 | +I will gladly take both PR and issues. |
| 79 | + |
| 80 | +Both Lint and Annotation Processor are covered with tests (tested in isolation). |
| 81 | + |
| 82 | +Tests are regular JUnit. Inside project Android app module is present too, so you can test all modules together. |
| 83 | + |
| 84 | +## Roadmap |
| 85 | +- Currently Annotation Processor (AP) fails silently as it assumes Android Lint will take care of signalling errors. |
| 86 | +However, on Kotlin Multiplatform Lint is not supported, so AP should have setting like silentMode on/off. |
| 87 | + |
| 88 | +## License |
| 89 | +Licensed under MIT - see [LICENSE](/LICENSE) file. |
| 90 | + |
0 commit comments