diff --git a/src/main/java/dev/nolij/zson/Comment.java b/src/main/java/dev/nolij/zson/Comment.java new file mode 100644 index 0000000..d275662 --- /dev/null +++ b/src/main/java/dev/nolij/zson/Comment.java @@ -0,0 +1,12 @@ +package dev.nolij.zson; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Comment { + String value(); +} diff --git a/src/main/java/dev/nolij/zson/Zson.java b/src/main/java/dev/nolij/zson/Zson.java index 6472de0..c186ae9 100644 --- a/src/main/java/dev/nolij/zson/Zson.java +++ b/src/main/java/dev/nolij/zson/Zson.java @@ -1,5 +1,7 @@ package dev.nolij.zson; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.*; import java.util.Map.Entry; @@ -127,6 +129,57 @@ public static String escape(String string, char escapeQuotes) { return result.toString(); } + public static Map fromObject(Object object) { + Map map = Zson.object(); + for (Field field : object.getClass().getDeclaredFields()) { + if(Modifier.isStatic(field.getModifiers())) continue; + Comment comment = field.getAnnotation(Comment.class); + String commentValue = comment == null ? null : comment.value(); + try { + map.put(field.getName(), new ZsonValue(commentValue, field.get(object))); + } catch (IllegalAccessException e) { + throw new RuntimeException("Failed to get field " + field.getName(), e); + } + } + return map; + } + + public static T toObject(Map map, Class type) { + try { + T object = type.getDeclaredConstructor().newInstance(); + for (Field field : type.getDeclaredFields()) { + if(Modifier.isStatic(field.getModifiers())) continue; + setField(field, object, map.get(field.getName()).value); + } + return object; + } catch (Exception e) { + throw new RuntimeException("Failed to create object of type " + type.getSimpleName(), e); + } + } + + private static void setField(Field field, Object object, Object value) { + @SuppressWarnings("unchecked") + Class type = (Class) field.getType(); + try { + if(type.isPrimitive()) { + switch (type.getName()) { + case "boolean" -> field.setBoolean(object, (boolean) value); + case "short" -> field.setShort(object, (short) (int) value); + case "int" -> field.setInt(object, (int) value); + case "float" -> field.setFloat(object, (float) (double) value); + case "double" -> field.setDouble(object, (double) value); + } + } else { + field.set(object, type.cast(value)); + } + } catch (Exception e) { + throw new RuntimeException( + "Failed to set field " + field.getName() + " (type " + type.getSimpleName() + ") to " + value + " " + + "(type " + value.getClass().getSimpleName() + ")", e + ); + } + } + private Zson() { } }