com.google.cloud.storage.Conversions Maven / Gradle / Ivy
Show all versions of google-cloud-storage Show documentation
/*
* Copyright 2022 Google LLC
*
* 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
*
* http://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.google.cloud.storage;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Abstraction utilities for converting between two different types.
*
* Primarily targeted at encapsulating the logic for conversion from our model classes and the
* respective transport specific models.
*/
final class Conversions {
private Conversions() {}
/** Entry point to the registry of Codecs for conversions with the JSON Api model */
static JsonConversions json() {
return JsonConversions.INSTANCE;
}
/** Entry point to the registry of Codecs for conversions with the gRPC Api model */
static GrpcConversions grpc() {
return GrpcConversions.INSTANCE;
}
/**
* Abstraction representing a conversion to a different model type.
*
*
This class is the inverse of {@link Decoder}
*
*
A symmetric {@link Encoder} {@link Decoder} pair can make a {@link Codec}
*
* @param
* @param
* @see Decoder
* @see Codec
*/
@FunctionalInterface
interface Encoder {
To encode(From f);
}
/**
* Abstraction representing a conversion from a different model type.
*
* This class is the inverse of {@link Encoder}
*
*
A symmetric {@link Encoder} {@link Decoder} pair can make a {@link Codec}
*
* @param
* @param
* @see Encoder
* @see Codec
*/
@FunctionalInterface
interface Decoder {
To decode(From f);
default Decoder andThen(Decoder d) {
return f -> d.decode(this.decode(f));
}
default Decoder compose(Decoder before) {
return in -> this.decode(before.decode(in));
}
static Decoder identity() {
return (x) -> x;
}
}
interface Codec extends Encoder, Decoder {
static Codec of(Encoder e, Decoder d) {
return new SimpleCodec<>(e, d);
}
default Codec andThen(Codec c) {
Codec self = this;
return new Codec() {
@Override
public A decode(R f) {
return self.decode(c.decode(f));
}
@Override
public R encode(A f) {
return c.encode(self.encode(f));
}
};
}
/**
* Create a new Codec which guards calling each method with a null check.
*
* If the values provided to either {@link #decode(Object)} or {@link #encode(Object)} is
* null, null will be returned.
*/
default Codec<@Nullable A, @Nullable B> nullable() {
Codec self = this;
return new Codec() {
@Override
public A decode(B f) {
return f == null ? null : self.decode(f);
}
@Override
public B encode(A f) {
return f == null ? null : self.encode(f);
}
};
}
}
/**
* Internal implementation detail, not to be opened if the containing class and interfaces are
* ever opened up for access.
*/
private static final class SimpleCodec implements Codec {
private final Encoder e;
private final Decoder d;
private SimpleCodec(Encoder e, Decoder d) {
this.e = e;
this.d = d;
}
@Override
public B encode(A f) {
return e.encode(f);
}
@Override
public A decode(B f) {
return d.decode(f);
}
}
}