SleepDetailsToCsv.java
package com.seebie.server.mapper.entitytodto;
import com.seebie.server.dto.SleepDetails;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import static com.seebie.server.function.Functional.uncheck;
import static java.util.stream.Collectors.joining;
@Component
public class SleepDetailsToCsv implements Function<List<SleepDetails>, String> {
    public enum HEADER {
        TIME_ASLEEP, TIME_AWAKE, TIMEZONE, MINUTES_ASLEEP, MINUTES_AWAKE, NOTES
    }
    public static final CSVFormat CSV_OUTPUT = CSVFormat.RFC4180.builder()
                                                                .setHeader(HEADER.class)
                                                                .build();
    public static String headerRow() {
        return Arrays.stream(CSV_OUTPUT.getHeader()).collect(joining(","));
    }
    private final SleepDetailsToCsvRow toCsvRow = new SleepDetailsToCsvRow();
    @Override
    public String apply(List<SleepDetails> data) {
        return uncheck(this::internalApply).apply(data);
    }
    private String internalApply(List<SleepDetails> data) throws IOException {
        // The IOException is just part of the API that in theory could be triggered by the Appendable
        // (which could be to an Appendable File stream) but which in practice would never happen with a StringWriter.
        StringWriter stringWriter = new StringWriter();
        try (final CSVPrinter printer = new CSVPrinter(stringWriter, CSV_OUTPUT)) {
            data.stream()
                    .map(toCsvRow)
                    .forEach(uncheck((List<String> s) -> printer.printRecord(s)));
        }
        return stringWriter.toString();
    }
}