// Path: src/main/java/io/github/cbartosiak/bson/codecs/jsr310/internal/CodecsUtil.java
// public static <Value> Value getFieldValue(
//         Document document,
//         Object key,
//         Class<Value> clazz) {
// 
//     try {
//         Value value = document.get(key, clazz);
//         if (value == null) {
//             throw new BsonInvalidOperationException(format(
//                     "The value of the field %s is null", key
//             ));
//         }
//         return value;
//     }
//     catch (ClassCastException ex) {
//         throw new BsonInvalidOperationException(format(
//                 "The value of the field %s is not of the type %s",
//                 key, clazz.getName()
//         ), ex);
//     }
// }
// 
// Path: src/main/java/io/github/cbartosiak/bson/codecs/jsr310/internal/CodecsUtil.java
// public static Document readDocument(
//         BsonReader reader,
//         DecoderContext decoderContext,
//         Map<String, Decoder<?>> fieldDecoders) {
// 
//     Document document = new Document();
//     reader.readStartDocument();
//     while (reader.readBsonType() != END_OF_DOCUMENT) {
//         String fieldName = reader.readName();
//         if (fieldDecoders.containsKey(fieldName)) {
//             document.put(
//                     fieldName,
//                     fieldDecoders
//                             .get(fieldName)
//                             .decode(reader, decoderContext)
//             );
//         }
//         else {
//             throw new BsonInvalidOperationException(format(
//                     "The field %s is not expected here", fieldName
//             ));
//         }
//     }
//     reader.readEndDocument();
//     return document;
// }
// 
// Path: src/main/java/io/github/cbartosiak/bson/codecs/jsr310/internal/CodecsUtil.java
// public static <Value, Result> Result translateDecodeExceptions(
//         Supplier<Value> valueSupplier,
//         Function<Value, Result> valueConverter) {
// 
//     Value value = valueSupplier.get();
//     try {
//         return valueConverter.apply(value);
//     }
//     catch (ArithmeticException |
//             DateTimeException |
//             IllegalArgumentException ex) {
// 
//         throw new BsonInvalidOperationException(format(
//                 "The value %s is not supported", value
//         ), ex);
//     }
// }


import org.bson.codecs.Decoder;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
import static io.github.cbartosiak.bson.codecs.jsr310.internal.CodecsUtil.getFieldValue;
import static io.github.cbartosiak.bson.codecs.jsr310.internal.CodecsUtil.readDocument;
import static io.github.cbartosiak.bson.codecs.jsr310.internal.CodecsUtil.translateDecodeExceptions;
import static java.time.YearMonth.of;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
import java.time.YearMonth;
import java.util.HashMap;
import java.util.Map;
import org.bson.BsonReader;
import org.bson.BsonWriter;
import org.bson.codecs.Codec;
/*
 * Copyright 2018 Cezary Bartosiak
 *
 * 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 io.github.cbartosiak.bson.codecs.jsr310.yearmonth;




/**
 * <p>
 * Encodes and decodes {@code YearMonth} values to and from
 * {@code BSON Document}, such as {@code { year: 2018, month: 1 }}.
 * <p>
 * The values are stored using the following structure:
 * <ul>
 * <li>{@code year} (a non-null {@code Int32});
 * <li>{@code month} (a non-null {@code Int32}).
 * </ul>
 * <p>
 * This type is <b>immutable</b>.
 */
public final class YearMonthAsDocumentCodec implements Codec<YearMonth> {

    private static final Map<String, Decoder<?>> FIELD_DECODERS;

    static {
        Map<String, Decoder<?>> fd = new HashMap<>();
        fd.put("year", (r, dc) -> r.readInt32());
        fd.put("month", (r, dc) -> r.readInt32());
        FIELD_DECODERS = unmodifiableMap(fd);
    }

    @Override
    public void encode(
            BsonWriter writer,
            YearMonth value,
            EncoderContext encoderContext) {

        requireNonNull(writer, "writer is null");
        requireNonNull(value, "value is null");
// Path: src/main/java/io/github/cbartosiak/bson/codecs/jsr310/internal/CodecsUtil.java
// public static <Value> Value getFieldValue(
//         Document document,
//         Object key,
//         Class<Value> clazz) {
// 
//     try {
//         Value value = document.get(key, clazz);
//         if (value == null) {
//             throw new BsonInvalidOperationException(format(
//                     "The value of the field %s is null", key
//             ));
//         }
//         return value;
//     }
//     catch (ClassCastException ex) {
//         throw new BsonInvalidOperationException(format(
//                 "The value of the field %s is not of the type %s",
//                 key, clazz.getName()
//         ), ex);
//     }
// }
// 
// Path: src/main/java/io/github/cbartosiak/bson/codecs/jsr310/internal/CodecsUtil.java
// public static Document readDocument(
//         BsonReader reader,
//         DecoderContext decoderContext,
//         Map<String, Decoder<?>> fieldDecoders) {
// 
//     Document document = new Document();
//     reader.readStartDocument();
//     while (reader.readBsonType() != END_OF_DOCUMENT) {
//         String fieldName = reader.readName();
//         if (fieldDecoders.containsKey(fieldName)) {
//             document.put(
//                     fieldName,
//                     fieldDecoders
//                             .get(fieldName)
//                             .decode(reader, decoderContext)
//             );
//         }
//         else {
//             throw new BsonInvalidOperationException(format(
//                     "The field %s is not expected here", fieldName
//             ));
//         }
//     }
//     reader.readEndDocument();
//     return document;
// }
// 
// Path: src/main/java/io/github/cbartosiak/bson/codecs/jsr310/internal/CodecsUtil.java
// public static <Value, Result> Result translateDecodeExceptions(
//         Supplier<Value> valueSupplier,
//         Function<Value, Result> valueConverter) {
// 
//     Value value = valueSupplier.get();
//     try {
//         return valueConverter.apply(value);
//     }
//     catch (ArithmeticException |
//             DateTimeException |
//             IllegalArgumentException ex) {
// 
//         throw new BsonInvalidOperationException(format(
//                 "The value %s is not supported", value
//         ), ex);
//     }
// }


// Path: src/main/java/io/github/cbartosiak/bson/codecs/jsr310/yearmonth/YearMonthAsDocumentCodec.java
import org.bson.codecs.Decoder;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
import static io.github.cbartosiak.bson.codecs.jsr310.internal.CodecsUtil.getFieldValue;
import static io.github.cbartosiak.bson.codecs.jsr310.internal.CodecsUtil.readDocument;
import static io.github.cbartosiak.bson.codecs.jsr310.internal.CodecsUtil.translateDecodeExceptions;
import static java.time.YearMonth.of;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
import java.time.YearMonth;
import java.util.HashMap;
import java.util.Map;
import org.bson.BsonReader;
import org.bson.BsonWriter;
import org.bson.codecs.Codec;

/*
 * Copyright 2018 Cezary Bartosiak
 *
 * 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 io.github.cbartosiak.bson.codecs.jsr310.yearmonth;




/**
 * <p>
 * Encodes and decodes {@code YearMonth} values to and from
 * {@code BSON Document}, such as {@code { year: 2018, month: 1 }}.
 * <p>
 * The values are stored using the following structure:
 * <ul>
 * <li>{@code year} (a non-null {@code Int32});
 * <li>{@code month} (a non-null {@code Int32}).
 * </ul>
 * <p>
 * This type is <b>immutable</b>.
 */
public final class YearMonthAsDocumentCodec implements Codec<YearMonth> {

    private static final Map<String, Decoder<?>> FIELD_DECODERS;

    static {
        Map<String, Decoder<?>> fd = new HashMap<>();
        fd.put("year", (r, dc) -> r.readInt32());
        fd.put("month", (r, dc) -> r.readInt32());
        FIELD_DECODERS = unmodifiableMap(fd);
    }

    @Override
    public void encode(
            BsonWriter writer,
            YearMonth value,
            EncoderContext encoderContext) {

        requireNonNull(writer, "writer is null");
        requireNonNull(value, "value is null");
        writer.writeStartDocument();