Merge pull request #87 from TouchInstinct/feature/date-patterns
Feature/date patterns
This commit is contained in:
commit
81e8ddcb87
|
|
@ -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?
|
||||
|
||||
}
|
||||
|
|
@ -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")
|
||||
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import com.squareup.moshi.JsonQualifier
|
||||
|
||||
@JsonQualifier
|
||||
@Target(AnnotationTarget.FIELD)
|
||||
annotation class Format(val patterns: Array<String>)
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue