Merge pull request #87 from TouchInstinct/feature/date-patterns

Feature/date patterns
This commit is contained in:
Malik Khiraev 2019-08-07 18:26:17 +03:00 committed by GitHub
commit 81e8ddcb87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 0 deletions

View File

@ -0,0 +1,44 @@
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonEncodingException
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import org.joda.time.format.DateTimeFormat
import org.joda.time.format.DateTimeFormatter
import java.util.Arrays
abstract class AbstractDateJsonAdapter<T>(
private val formats: Array<String>
) : JsonAdapter<T>() {
companion object {
private const val CANT_FIND_ANY_FORMATTERS = "Can't find any DateTimeFormatter"
}
private val formatters = formats.map(DateTimeFormat::forPattern)
override fun fromJson(reader: JsonReader): T? {
val dateTimeString = reader.nextString()
formatters.forEachIndexed { index, dateTimeFormatter ->
try {
return fromJsonInner(dateTimeString, dateTimeFormatter)
} catch (e: IllegalArgumentException) {
if (index == formatters.lastIndex) {
throw JsonEncodingException("$dateTimeString doesn't fit any of the formats ${Arrays.toString(formats)}")
}
}
}
throw IllegalArgumentException(CANT_FIND_ANY_FORMATTERS)
}
override fun toJson(writer: JsonWriter, value: T?) {
if (formatters.isEmpty()) throw IllegalArgumentException(CANT_FIND_ANY_FORMATTERS)
value?.let {
writer.value(toJsonInner(value, formatters.first()))
} ?: throw JsonEncodingException("Value can't be null")
}
abstract fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): T
abstract fun toJsonInner(value: T?, dateTimeFormatter: DateTimeFormatter) : String?
}

View File

@ -0,0 +1,23 @@
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import org.joda.time.DateTime
import org.joda.time.LocalDate
import java.lang.reflect.Type
class DateFactory : JsonAdapter.Factory {
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? {
return when (type.typeName) {
DateTime::class.java.typeName -> DateTimeJsonAdapter(getPatterns(annotations))
LocalDate::class.java.typeName -> LocalDateJsonAdapter(getPatterns(annotations))
else -> null
}
}
private fun getPatterns(annotations: MutableSet<out Annotation>) = annotations
.map { it as? Format }
.firstOrNull()
?.patterns
?: throw IllegalArgumentException("You should use Format annotation for DateTime and LocalDate fields")
}

View File

@ -0,0 +1,16 @@
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormatter
class DateTimeJsonAdapter(
formats: Array<String>
) : AbstractDateJsonAdapter<DateTime>(formats) {
override fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): DateTime {
return DateTime.parse(value, dateTimeFormatter)
}
override fun toJsonInner(value: DateTime?, dateTimeFormatter: DateTimeFormatter): String? {
return value?.toString(dateTimeFormatter)
}
}

View File

@ -0,0 +1,5 @@
import com.squareup.moshi.JsonQualifier
@JsonQualifier
@Target(AnnotationTarget.FIELD)
annotation class Format(val patterns: Array<String>)

View File

@ -0,0 +1,16 @@
import org.joda.time.LocalDate
import org.joda.time.format.DateTimeFormatter
class LocalDateJsonAdapter(
formats: Array<String>
) : AbstractDateJsonAdapter<LocalDate>(formats) {
override fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): LocalDate {
return LocalDate.parse(value, dateTimeFormatter)
}
override fun toJsonInner(value: LocalDate?, dateTimeFormatter: DateTimeFormatter): String? {
return value?.toString(dateTimeFormatter)
}
}