TheElectronWill / night-config

Powerful java configuration library for toml, yaml, hocon, json and in-memory configurations. Serialization/deserialization framework.
GNU Lesser General Public License v3.0
242 stars 28 forks source link

Make multiple @Spec checks #150

Closed enimaloc closed 10 months ago

enimaloc commented 11 months ago

Currently, only the first annotation is checked, this does not allow multiple conditions to be checked or the need to create a custom specification for each condition:

public class Configuration {
    @Path("server.port") 
    @SpecIntInRange(min = 1, max = 65535) 
    @SpecValidator(PortValidator.class) // Not possible 
    int serverPort = 25566;

    @Override
    public String toString() { 
        return "Configuration{serverPort=" + serverPort + '}';
    }

   public static class PortValidator implements Predicate<Object> { 
       @Override public boolean test(Object o) { 
           return o instanceof Integer i && i != 25565; 
       }
    }
}

We need to do this instead:

public class Configuration {
    @Path("server.port")
    @SpecValidator(PortValidator.class)
    int serverPort = 25566;

    @Override
    public String toString() {
        return "Configuration{serverPort=" + serverPort + '}';
    }

    public static class PortValidator implements Predicate<Object> {
        @Override public boolean test(Object o) {
            return o instanceof Integer i && i != 25565 && i >= 1 && i <= 65535;
        }
    } 
}

Which prevents us from doing multiple conditions without recreating a Predicate, what I'm proposing is to be able to do such a thing:

public class Configuration {
    @Path("server.port")
    @SpecIntInRange(min = 1, max = 65535)
    @SpecValidator(PortValidator.class)
    @SpecValidator(NotTenValidator.class)
    int serverPort = 25566;

    @Override public String toString() {
        return "Configuration{serverPort=" + serverPort + '}';
    }

    public static class PortValidator implements Predicate<Object> {
        @Override 
        public boolean test(Object o) { 
            return o instanceof Integer i && i != 25565 && i >= 1 && i <= 65535;
        }
    }

    public static class NotTenValidator implements Predicate<Object> {
        @Override
        public boolean test(Object o) {
            return o instanceof Integer i && i != 10;
        }
    }
}

One solution to this issue is to remove the return; at the various checks made by the program.

TheElectronWill commented 11 months ago

Yes that's an interesting feature. Thanks for the ticket!