night-config icon indicating copy to clipboard operation
night-config copied to clipboard

(De)serialization of interface/abstract types

Open NeumimTo opened this issue 4 years ago • 1 comments

Is it possible to automatically map an interface to implementation during its de/serialization?

NeumimTo avatar Sep 29 '19 15:09 NeumimTo

Do you mean serializing/deserializing a field whose type is an interface? For example:

interface MyInterface {
    String data();
}
class MyImpl implements MyInterface {
    private String data;
    public MyImpl(String data) { this.data = data; }
    public String data() { return data; }
}

class MyConfig { // to serialize
    public MyInterface interface;
}
MyConfig cfg = new MyConfig();
cfg.interface = new MyImpl();

In that case, the default serialization will work:

Config serialized = new ObjectConverter().toConfig(cfg, Config::inMemory);
assert serialized.get("interface.data") == cfg.interface.data();

However, deserialization will not work by default, because NightConfig doesn't known which MyInterface you want to use. You must specify a converter:

class MyConfig {
    @Conversion(MyConverter.class)
    public MyInterface interface;
}
class MyConverter implements Converter<MyInterface, Config> {
    public MyInterface convertToField(Config value) {
        return new MyImpl(value.get("data"));
    }
    public Config convertFromField(MyInterface value) {
        Config c = Config.inMemory();
        c.set("data", value.data());
        return c;
    }
}

This is what you need to do for now. But I could do better: for the next version, I'll add a way to provide a default implementation of the interface :smiley:

TheElectronWill avatar Sep 29 '19 16:09 TheElectronWill