package com.googlecode.totallylazy.json; import com.googlecode.totallylazy.Iterators; import com.googlecode.totallylazy.Value; import com.googlecode.totallylazy.annotations.multimethod; import com.googlecode.totallylazy.multi; import com.googlecode.totallylazy.time.Dates; import java.util.Date; import java.util.Iterator; import java.util.Map; import static com.googlecode.totallylazy.Appendables.append; public class JsonWriter { public static final String SEPARATOR = ","; private static multi multi; public static <A extends Appendable> A write(final Object o, final A appendable) { if(multi == null) multi = new multi(){}; return multi.<A>methodOption(o, appendable).getOrElse(() -> { return write(o.toString(), appendable); }); } @multimethod public static <A extends Appendable> A write(final Value<?> value, final A appendable) { if(value instanceof Map.Entry) return write((Map.Entry) value, appendable); return write(value.value(), appendable); } @multimethod public static <A extends Appendable> A write(final CharSequence charSequence, final A appendable) { return append(Strings.toString(charSequence), appendable); } @multimethod public static <A extends Appendable> A write(final Iterator<?> iterator, final A appendable) { return iterate(iterator, appendable, "[", SEPARATOR, "]"); } @multimethod public static <A extends Appendable> A write(final Iterable<?> iterable, final A appendable) { if(iterable instanceof Map) return write((Map) iterable, appendable); return write(iterable.iterator(), appendable); } @multimethod public static <A extends Appendable> A write(final Map<?, ?> map, final A appendable) { return iterate(map.entrySet().iterator(), appendable, "{", SEPARATOR, "}"); } @multimethod public static <A extends Appendable> A write(final Map.Entry<?, ?> entry, final A appendable) { return write(entry.getValue(), append(':', append(Strings.toString(String.valueOf(entry.getKey())), appendable))); } @multimethod public static <A extends Appendable> A write(final Void aVoid, final A appendable) { return append("null", appendable); } @multimethod public static <A extends Appendable> A write(final Number number, final A appendable) { return append(number.toString(), appendable); } @multimethod public static <A extends Appendable> A write(final Date date, final A appendable) { return append(Strings.quote(Dates.RFC3339withMilliseconds().format(date)), appendable); } @multimethod public static <A extends Appendable> A write(final Boolean bool, final A appendable) { return append(bool.toString(), appendable); } private static <A extends Appendable> A iterate(final Iterator<?> iterator, final A appendable, String start, String separator, String end) { return Iterators.appendTo(Iterators.map(iterator, o -> { write(o, appendable); return ""; }), appendable, start, separator, end); } }