mirror of
https://github.com/fankes/moshi.git
synced 2025-10-18 23:49:21 +08:00
Convert JsonAdapter
to Kotlin (#1475)
* Rename .java to .kt * Convert JsonAdapter to Kotlin Note that there's more to be done here I think, namely exploring removing the NonNull adapter and making the nullSafe() adapter public so that nullability is directly in the API. Saving that for another day though * Update a couple usages * Fix override * Add exclusion for open * Add `@Language` annotation for json strings Allows the IDE to automatically make this pretty * Spotless * Nullable Co-authored-by: Egor Andreevich <egor@squareup.com> * When Co-authored-by: Parth Padgaonkar <1294660+JvmName@users.noreply.github.com> * Another when * Spotless Co-authored-by: Egor Andreevich <egor@squareup.com> Co-authored-by: Parth Padgaonkar <1294660+JvmName@users.noreply.github.com>
This commit is contained in:
@@ -167,7 +167,7 @@ public class PolymorphicJsonAdapterFactory<T> internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun create(type: Type, annotations: Set<Annotation?>, moshi: Moshi): JsonAdapter<*>? {
|
||||
override fun create(type: Type, annotations: Set<Annotation>, moshi: Moshi): JsonAdapter<*>? {
|
||||
if (type.rawType != baseType || annotations.isNotEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
@@ -190,7 +190,7 @@ internal class KotlinJsonAdapter<T>(
|
||||
}
|
||||
|
||||
public class KotlinJsonAdapterFactory : JsonAdapter.Factory {
|
||||
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi):
|
||||
override fun create(type: Type, annotations: Set<Annotation>, moshi: Moshi):
|
||||
JsonAdapter<*>? {
|
||||
if (annotations.isNotEmpty()) return null
|
||||
|
||||
|
@@ -30,6 +30,9 @@ val japicmp = tasks.register<JapicmpTask>("japicmp") {
|
||||
"com.squareup.moshi.internal.NullSafeJsonAdapter", // Internal.
|
||||
"com.squareup.moshi.internal.Util" // Internal.
|
||||
)
|
||||
methodExcludes = listOf(
|
||||
"com.squareup.moshi.JsonAdapter#indent(java.lang.String)" // Was unintentionally open before
|
||||
)
|
||||
fieldExcludes = listOf(
|
||||
"com.squareup.moshi.CollectionJsonAdapter#FACTORY" // False-positive, class is not public anyway
|
||||
)
|
||||
|
@@ -1,332 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.squareup.moshi;
|
||||
|
||||
import com.squareup.moshi.internal.NonNullJsonAdapter;
|
||||
import com.squareup.moshi.internal.NullSafeJsonAdapter;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSink;
|
||||
import okio.BufferedSource;
|
||||
|
||||
/**
|
||||
* Converts Java values to JSON, and JSON values to Java.
|
||||
*
|
||||
* <p>JsonAdapter instances provided by Moshi are thread-safe, meaning multiple threads can safely
|
||||
* use a single instance concurrently.
|
||||
*
|
||||
* <p>Custom JsonAdapter implementations should be designed to be thread-safe.
|
||||
*/
|
||||
public abstract class JsonAdapter<T> {
|
||||
|
||||
/**
|
||||
* Decodes a nullable instance of type {@link T} from the given {@code reader}.
|
||||
*
|
||||
* @throws JsonDataException when the data in a JSON document doesn't match the data expected by
|
||||
* the caller.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public abstract @Nullable T fromJson(JsonReader reader) throws IOException;
|
||||
|
||||
/**
|
||||
* Decodes a nullable instance of type {@link T} from the given {@code source}.
|
||||
*
|
||||
* @throws JsonDataException when the data in a JSON document doesn't match the data expected by
|
||||
* the caller.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public final @Nullable T fromJson(BufferedSource source) throws IOException {
|
||||
return fromJson(JsonReader.of(source));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a nullable instance of type {@link T} from the given {@code string}.
|
||||
*
|
||||
* @throws JsonDataException when the data in a JSON document doesn't match the data expected by
|
||||
* the caller.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public final @Nullable T fromJson(String string) throws IOException {
|
||||
JsonReader reader = JsonReader.of(new Buffer().writeUtf8(string));
|
||||
T result = fromJson(reader);
|
||||
if (!isLenient() && reader.peek() != JsonReader.Token.END_DOCUMENT) {
|
||||
throw new JsonDataException("JSON document was not fully consumed.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Encodes the given {@code value} with the given {@code writer}. */
|
||||
public abstract void toJson(JsonWriter writer, @Nullable T value) throws IOException;
|
||||
|
||||
public final void toJson(BufferedSink sink, @Nullable T value) throws IOException {
|
||||
JsonWriter writer = JsonWriter.of(sink);
|
||||
toJson(writer, value);
|
||||
}
|
||||
|
||||
/** Encodes the given {@code value} into a String and returns it. */
|
||||
@CheckReturnValue
|
||||
public final String toJson(@Nullable T value) {
|
||||
Buffer buffer = new Buffer();
|
||||
try {
|
||||
toJson(buffer, value);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e); // No I/O writing to a Buffer.
|
||||
}
|
||||
return buffer.readUtf8();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes {@code value} as a Java value object comprised of maps, lists, strings, numbers,
|
||||
* booleans, and nulls.
|
||||
*
|
||||
* <p>Values encoded using {@code value(double)} or {@code value(long)} are modeled with the
|
||||
* corresponding boxed type. Values encoded using {@code value(Number)} are modeled as a {@link
|
||||
* Long} for boxed integer types ({@link Byte}, {@link Short}, {@link Integer}, and {@link Long}),
|
||||
* as a {@link Double} for boxed floating point types ({@link Float} and {@link Double}), and as a
|
||||
* {@link BigDecimal} for all other types.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public final @Nullable Object toJsonValue(@Nullable T value) {
|
||||
JsonValueWriter writer = new JsonValueWriter();
|
||||
try {
|
||||
toJson(writer, value);
|
||||
return writer.root();
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e); // No I/O writing to an object.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a Java value object from {@code value}, which must be comprised of maps, lists,
|
||||
* strings, numbers, booleans and nulls.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public final @Nullable T fromJsonValue(@Nullable Object value) {
|
||||
JsonValueReader reader = new JsonValueReader(value);
|
||||
try {
|
||||
return fromJson(reader);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e); // No I/O reading from an object.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON adapter equal to this JSON adapter, but that serializes nulls when encoding
|
||||
* JSON.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public final JsonAdapter<T> serializeNulls() {
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override
|
||||
public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
return delegate.fromJson(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
boolean serializeNulls = writer.getSerializeNulls();
|
||||
writer.setSerializeNulls(true);
|
||||
try {
|
||||
delegate.toJson(writer, value);
|
||||
} finally {
|
||||
writer.setSerializeNulls(serializeNulls);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isLenient() {
|
||||
return delegate.isLenient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate + ".serializeNulls()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON adapter equal to this JSON adapter, but with support for reading and writing
|
||||
* nulls.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public final JsonAdapter<T> nullSafe() {
|
||||
if (this instanceof NullSafeJsonAdapter) {
|
||||
return this;
|
||||
}
|
||||
return new NullSafeJsonAdapter<>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON adapter equal to this JSON adapter, but that refuses null values. If null is
|
||||
* read or written this will throw a {@link JsonDataException}.
|
||||
*
|
||||
* <p>Note that this adapter will not usually be invoked for absent values and so those must be
|
||||
* handled elsewhere. This should only be used to fail on explicit nulls.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public final JsonAdapter<T> nonNull() {
|
||||
if (this instanceof NonNullJsonAdapter) {
|
||||
return this;
|
||||
}
|
||||
return new NonNullJsonAdapter<>(this);
|
||||
}
|
||||
|
||||
/** Returns a JSON adapter equal to this, but is lenient when reading and writing. */
|
||||
@CheckReturnValue
|
||||
public final JsonAdapter<T> lenient() {
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override
|
||||
public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
boolean lenient = reader.isLenient();
|
||||
reader.setLenient(true);
|
||||
try {
|
||||
return delegate.fromJson(reader);
|
||||
} finally {
|
||||
reader.setLenient(lenient);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
boolean lenient = writer.isLenient();
|
||||
writer.setLenient(true);
|
||||
try {
|
||||
delegate.toJson(writer, value);
|
||||
} finally {
|
||||
writer.setLenient(lenient);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isLenient() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate + ".lenient()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON adapter equal to this, but that throws a {@link JsonDataException} when
|
||||
* {@linkplain JsonReader#setFailOnUnknown(boolean) unknown names and values} are encountered.
|
||||
* This constraint applies to both the top-level message handled by this type adapter as well as
|
||||
* to nested messages.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public final JsonAdapter<T> failOnUnknown() {
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override
|
||||
public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
boolean skipForbidden = reader.failOnUnknown();
|
||||
reader.setFailOnUnknown(true);
|
||||
try {
|
||||
return delegate.fromJson(reader);
|
||||
} finally {
|
||||
reader.setFailOnUnknown(skipForbidden);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
delegate.toJson(writer, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isLenient() {
|
||||
return delegate.isLenient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate + ".failOnUnknown()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a JSON adapter equal to this, but using {@code indent} to control how the result is
|
||||
* formatted. The {@code indent} string to be repeated for each level of indentation in the
|
||||
* encoded document. If {@code indent.isEmpty()} the encoded document will be compact. Otherwise
|
||||
* the encoded document will be more human-readable.
|
||||
*
|
||||
* @param indent a string containing only whitespace.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public JsonAdapter<T> indent(final String indent) {
|
||||
if (indent == null) {
|
||||
throw new NullPointerException("indent == null");
|
||||
}
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override
|
||||
public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
return delegate.fromJson(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
String originalIndent = writer.getIndent();
|
||||
writer.setIndent(indent);
|
||||
try {
|
||||
delegate.toJson(writer, value);
|
||||
} finally {
|
||||
writer.setIndent(originalIndent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isLenient() {
|
||||
return delegate.isLenient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate + ".indent(\"" + indent + "\")";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
boolean isLenient() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface Factory {
|
||||
/**
|
||||
* Attempts to create an adapter for {@code type} annotated with {@code annotations}. This
|
||||
* returns the adapter if one was created, or null if this factory isn't capable of creating
|
||||
* such an adapter.
|
||||
*
|
||||
* <p>Implementations may use {@link Moshi#adapter} to compose adapters of other types, or
|
||||
* {@link Moshi#nextAdapter} to delegate to the underlying adapter of the same type.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
@Nullable
|
||||
JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi);
|
||||
}
|
||||
}
|
296
moshi/src/main/java/com/squareup/moshi/JsonAdapter.kt
Normal file
296
moshi/src/main/java/com/squareup/moshi/JsonAdapter.kt
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.squareup.moshi
|
||||
|
||||
import com.squareup.moshi.internal.NonNullJsonAdapter
|
||||
import com.squareup.moshi.internal.NullSafeJsonAdapter
|
||||
import okio.Buffer
|
||||
import okio.BufferedSink
|
||||
import okio.BufferedSource
|
||||
import okio.IOException
|
||||
import org.intellij.lang.annotations.Language
|
||||
import java.lang.reflect.Type
|
||||
import javax.annotation.CheckReturnValue
|
||||
import kotlin.Throws
|
||||
|
||||
/**
|
||||
* Converts Java values to JSON, and JSON values to Java.
|
||||
*
|
||||
* JsonAdapter instances provided by Moshi are thread-safe, meaning multiple threads can safely
|
||||
* use a single instance concurrently.
|
||||
*
|
||||
* Custom JsonAdapter implementations should be designed to be thread-safe.
|
||||
*/
|
||||
public abstract class JsonAdapter<T> {
|
||||
/**
|
||||
* Decodes a nullable instance of type [T] from the given [reader].
|
||||
*
|
||||
* @throws JsonDataException when the data in a JSON document doesn't match the data expected by
|
||||
* the caller.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
@Throws(IOException::class)
|
||||
public abstract fun fromJson(reader: JsonReader): T?
|
||||
|
||||
/**
|
||||
* Decodes a nullable instance of type [T] from the given [source].
|
||||
*
|
||||
* @throws JsonDataException when the data in a JSON document doesn't match the data expected by
|
||||
* the caller.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
@Throws(IOException::class)
|
||||
public fun fromJson(source: BufferedSource): T? = fromJson(JsonReader.of(source))
|
||||
|
||||
/**
|
||||
* Decodes a nullable instance of type [T] from the given `string`.
|
||||
*
|
||||
* @throws JsonDataException when the data in a JSON document doesn't match the data expected by
|
||||
* the caller.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
@Throws(IOException::class)
|
||||
public fun fromJson(@Language("JSON") string: String): T? {
|
||||
val reader = JsonReader.of(Buffer().writeUtf8(string))
|
||||
val result = fromJson(reader)
|
||||
if (!isLenient && reader.peek() != JsonReader.Token.END_DOCUMENT) {
|
||||
throw JsonDataException("JSON document was not fully consumed.")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Encodes the given [value] with the given [writer]. */
|
||||
@Throws(IOException::class)
|
||||
public abstract fun toJson(writer: JsonWriter, value: T?)
|
||||
|
||||
@Throws(IOException::class)
|
||||
public fun toJson(sink: BufferedSink, value: T?) {
|
||||
val writer = JsonWriter.of(sink)
|
||||
toJson(writer, value)
|
||||
}
|
||||
|
||||
/** Encodes the given [value] into a String and returns it. */
|
||||
@CheckReturnValue
|
||||
public fun toJson(value: T?): String {
|
||||
val buffer = Buffer()
|
||||
try {
|
||||
toJson(buffer, value)
|
||||
} catch (e: IOException) {
|
||||
throw AssertionError(e) // No I/O writing to a Buffer.
|
||||
}
|
||||
return buffer.readUtf8()
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes [value] as a Java value object comprised of maps, lists, strings, numbers,
|
||||
* booleans, and nulls.
|
||||
*
|
||||
* Values encoded using `value(double)` or `value(long)` are modeled with the
|
||||
* corresponding boxed type. Values encoded using `value(Number)` are modeled as a [Long] for boxed integer types
|
||||
* ([Byte], [Short], [Integer], and [Long]), as a [Double] for boxed floating point types ([Float] and [Double]),
|
||||
* and as a [java.math.BigDecimal] for all other types.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public fun toJsonValue(value: T?): Any? {
|
||||
val writer = JsonValueWriter()
|
||||
return try {
|
||||
toJson(writer, value)
|
||||
writer.root()
|
||||
} catch (e: IOException) {
|
||||
throw AssertionError(e) // No I/O writing to an object.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a Java value object from [value], which must be comprised of maps, lists,
|
||||
* strings, numbers, booleans and nulls.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public fun fromJsonValue(value: Any?): T? {
|
||||
val reader = JsonValueReader(value)
|
||||
return try {
|
||||
fromJson(reader)
|
||||
} catch (e: IOException) {
|
||||
throw AssertionError(e) // No I/O reading from an object.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON adapter equal to this JSON adapter, but that serializes nulls when encoding
|
||||
* JSON.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public fun serializeNulls(): JsonAdapter<T> {
|
||||
val delegate: JsonAdapter<T> = this
|
||||
return object : JsonAdapter<T>() {
|
||||
override fun fromJson(reader: JsonReader) = delegate.fromJson(reader)
|
||||
|
||||
override fun toJson(writer: JsonWriter, value: T?) {
|
||||
val serializeNulls = writer.getSerializeNulls()
|
||||
writer.setSerializeNulls(true)
|
||||
try {
|
||||
delegate.toJson(writer, value)
|
||||
} finally {
|
||||
writer.setSerializeNulls(serializeNulls)
|
||||
}
|
||||
}
|
||||
|
||||
override val isLenient: Boolean
|
||||
get() = delegate.isLenient
|
||||
|
||||
override fun toString() = "$delegate.serializeNulls()"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON adapter equal to this JSON adapter, but with support for reading and writing
|
||||
* nulls.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public fun nullSafe(): JsonAdapter<T> {
|
||||
return when (this) {
|
||||
is NullSafeJsonAdapter<*> -> this
|
||||
else -> NullSafeJsonAdapter(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON adapter equal to this JSON adapter, but that refuses null values. If null is
|
||||
* read or written this will throw a [JsonDataException].
|
||||
*
|
||||
* Note that this adapter will not usually be invoked for absent values and so those must be
|
||||
* handled elsewhere. This should only be used to fail on explicit nulls.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public fun nonNull(): JsonAdapter<T> {
|
||||
return when (this) {
|
||||
is NonNullJsonAdapter<*> -> this
|
||||
else -> NonNullJsonAdapter(this)
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a JSON adapter equal to this, but is lenient when reading and writing. */
|
||||
@CheckReturnValue
|
||||
public fun lenient(): JsonAdapter<T> {
|
||||
val delegate: JsonAdapter<T> = this
|
||||
return object : JsonAdapter<T>() {
|
||||
override fun fromJson(reader: JsonReader): T? {
|
||||
val lenient = reader.isLenient
|
||||
reader.isLenient = true
|
||||
return try {
|
||||
delegate.fromJson(reader)
|
||||
} finally {
|
||||
reader.isLenient = lenient
|
||||
}
|
||||
}
|
||||
|
||||
override fun toJson(writer: JsonWriter, value: T?) {
|
||||
val lenient = writer.isLenient
|
||||
writer.isLenient = true
|
||||
try {
|
||||
delegate.toJson(writer, value)
|
||||
} finally {
|
||||
writer.isLenient = lenient
|
||||
}
|
||||
}
|
||||
|
||||
override val isLenient: Boolean
|
||||
get() = true
|
||||
|
||||
override fun toString() = "$delegate.lenient()"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON adapter equal to this, but that throws a [JsonDataException] when
|
||||
* [unknown names and values][JsonReader.setFailOnUnknown] are encountered.
|
||||
* This constraint applies to both the top-level message handled by this type adapter as well as
|
||||
* to nested messages.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public fun failOnUnknown(): JsonAdapter<T> {
|
||||
val delegate: JsonAdapter<T> = this
|
||||
return object : JsonAdapter<T>() {
|
||||
override fun fromJson(reader: JsonReader): T? {
|
||||
val skipForbidden = reader.failOnUnknown()
|
||||
reader.setFailOnUnknown(true)
|
||||
return try {
|
||||
delegate.fromJson(reader)
|
||||
} finally {
|
||||
reader.setFailOnUnknown(skipForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toJson(writer: JsonWriter, value: T?) {
|
||||
delegate.toJson(writer, value)
|
||||
}
|
||||
|
||||
override val isLenient: Boolean
|
||||
get() = delegate.isLenient
|
||||
|
||||
override fun toString() = "$delegate.failOnUnknown()"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a JSON adapter equal to this, but using `indent` to control how the result is
|
||||
* formatted. The `indent` string to be repeated for each level of indentation in the
|
||||
* encoded document. If `indent.isEmpty()` the encoded document will be compact. Otherwise
|
||||
* the encoded document will be more human-readable.
|
||||
*
|
||||
* @param indent a string containing only whitespace.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public fun indent(indent: String): JsonAdapter<T> {
|
||||
val delegate: JsonAdapter<T> = this
|
||||
return object : JsonAdapter<T>() {
|
||||
override fun fromJson(reader: JsonReader): T? {
|
||||
return delegate.fromJson(reader)
|
||||
}
|
||||
|
||||
override fun toJson(writer: JsonWriter, value: T?) {
|
||||
val originalIndent = writer.getIndent()
|
||||
writer.setIndent(indent)
|
||||
try {
|
||||
delegate.toJson(writer, value)
|
||||
} finally {
|
||||
writer.setIndent(originalIndent)
|
||||
}
|
||||
}
|
||||
|
||||
override val isLenient: Boolean
|
||||
get() = delegate.isLenient
|
||||
|
||||
override fun toString() = "$delegate.indent(\"$indent\")"
|
||||
}
|
||||
}
|
||||
|
||||
public open val isLenient: Boolean
|
||||
get() = false
|
||||
|
||||
public fun interface Factory {
|
||||
/**
|
||||
* Attempts to create an adapter for `type` annotated with `annotations`. This
|
||||
* returns the adapter if one was created, or null if this factory isn't capable of creating
|
||||
* such an adapter.
|
||||
*
|
||||
* Implementations may use [Moshi.adapter] to compose adapters of other types, or
|
||||
* [Moshi.nextAdapter] to delegate to the underlying adapter of the same type.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public fun create(type: Type, annotations: Set<Annotation>, moshi: Moshi): JsonAdapter<*>?
|
||||
}
|
||||
}
|
@@ -219,7 +219,7 @@ public final class JsonAdapterTest {
|
||||
adapter.indent(null);
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertThat(expected).hasMessageThat().isEqualTo("indent == null");
|
||||
assertThat(expected).hasMessageThat().contains("Parameter specified as non-null is null");
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user