Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use ValueSerializer #25

Closed
arthurr0 opened this issue Jun 13, 2021 · 13 comments
Closed

How to use ValueSerializer #25

arthurr0 opened this issue Jun 13, 2021 · 13 comments
Labels
documentation Improvements or additions to documentation question Further information is requested

Comments

@arthurr0
Copy link

arthurr0 commented Jun 13, 2021

Hi, how i can use ValueSerializer?

@A248
Copy link
Owner

A248 commented Jun 13, 2021

You use ValueSerialiser so you can use a custom type in your configuration. Let's say you had the following:

public class CustomType {

	private final String value;

	public CustomType(String value) {
		this.value = value;
	}

	public String stringValue() {
		return value;
	}
}
  1. First implement the ValueSerialiser:
public class MyCustomSerializer implements ValueSerialiser<CustomType> {
	@Override
	public Class<CustomType> getTargetClass() {
		return CustomType.class;
	}

	@Override
	public CustomType deserialise(FlexibleType flexibleType) throws BadValueException {
		// Convert from a String -> CustomType
		String value = flexibleType.getString();
		return new CustomType(value);
	}

	@Override
	public Object serialise(CustomType value, Decomposer decomposer) {
		// Convert from a CustomType -> String
		return value.stringValue();
	}
}
  1. Then add the serializer to the ConfigurationOptions:
ConfigurationOptions options = new ConfigurationOptions.Builder()
				.addSerialiser(new MyCustomSerializer())
				.build();

Use the ConfigurationOptions when you create your config factory (GsonConfigurationFactory, SnakeYamlConfigurationFactory, etc.)

@A248 A248 added the question Further information is requested label Jun 13, 2021
@A248 A248 changed the title ValueSerializer How to use ValueSerializer Jun 13, 2021
@arthurr0
Copy link
Author

How i can use this for object with more variables?

@A248
Copy link
Owner

A248 commented Jun 13, 2021

I'm not exactly sure what you mean by that. If you need to use this type in your configuration, you can very easily:

public interface Config {

  @DefaultString("default value")
  CustomType something();

  // You can even use it in a List, Set, or Collection
  @DefaultStrings({"value1", "value2"})
  List<CustomType> listOfThings();

}

@arthurr0
Copy link
Author

arthurr0 commented Jun 13, 2021

I need put this to config:

   static Map<Integer, Level> defaultLevels() {
        Map<Integer, Level> levelsMap = new HashMap<>();
        levelsMap.put(1, new Level(5, 10, 1, 10, 0));
        levelsMap.put(2, new Level(7, 12, 2, 11, 10));
        levelsMap.put(3, new Level(9, 14, 3, 12, 20));
        levelsMap.put(4, new Level(12, 16, 4, 13, 30));
        levelsMap.put(5, new Level(15, 18, 5, 14, 40));
        return levelsMap;
    }

    @ConfDefault.DefaultObject("defaultLevels")
    Map<Integer, Level> levels();

@A248
Copy link
Owner

A248 commented Jun 13, 2021

I see. For that, you can treat a Level as a list of integers and implement your serializer like this:

public class LevelSerializer implements ValueSerialiser<Level> {
	@Override
	public Class<Level> getTargetClass() {
		return Level.class;
	}

	@Override
	public Level deserialise(FlexibleType flexibleType) throws BadValueException {
		List<Integer> values = new ArrayList<>();
		for (FlexibleType element : flexibleType.getList()) {
			values.add(element.getInteger());
		}
		return new Level(values);
	}

	@Override
	public Object serialise(Level value, Decomposer decomposer) {
		return value.values();
	}
}

public class Level {

	private final List<Integer> values;

	public Level(List<Integer> values) {
		this.values = List.copyOf(values);
		if (this.values.size() != 5) {
			throw new IllegalArgumentException("Size of Level values must be 5");
		}
	}

	public List<Integer> values() {
		return values;
	}
}

There are other ways you could do this, like by treating a Level as a configuration section, but I choose this way because it's relatively simple.

@arthurr0
Copy link
Author

arthurr0 commented Jun 13, 2021

But you can show my how i can do ths like by treating a level as configuration section? Your solution is not convenient to configuration.

Level:

public class Level {
    int minSpawnDelay;
    int maxSpawnDelay;
    int spawnCount;
    int spawnRage;
    int price;
    }

@arthurr0 arthurr0 reopened this Jun 13, 2021
@A248
Copy link
Owner

A248 commented Jun 13, 2021

Yes. You can even do this without using a value serializer:

public interface Config {

   static Map<Integer, Level> defaultLevels() {
        Map<Integer, Level> levelsMap = new HashMap<>();
        levelsMap.put(1, Level.of(5, 10, 1, 10, 0));
        levelsMap.put(2, Level.of(7, 12, 2, 11, 10));
        levelsMap.put(3, Level.of(9, 14, 3, 12, 20));
        levelsMap.put(4, Level.of(12, 16, 4, 13, 30));
        levelsMap.put(5, Level.of(15, 18, 5, 14, 40));
        return levelsMap;
    }

    @ConfDefault.DefaultObject("defaultLevels")
    Map<Integer, @SubSection Level> levels();


}
public interface Level {

	int minSpawnDelay();

	int maxSpawnDelay();

	int spawnCount();

	int spawnRange();

	int price();

	static Level of(int minSpawnDelay, int maxSpawnDelay, int spawnCount, int spawnRange, int price) {
		return new Level() {

			@Override
			public int minSpawnDelay() { return minSpawnDelay; }
			@Override
			public int maxSpawnDelay() { return maxSpawnDelay; }
			@Override
			public int spawnCount() { return spawnCount; }
			@Override
			public int spawnRange() { return spawnRange; }
			@Override
			public int price() { return price; }
		};
	}

}

@A248
Copy link
Owner

A248 commented Jun 13, 2021

Note that you need @SubSection here:

    @ConfDefault.DefaultObject("defaultLevels")
    Map<Integer, @SubSection Level> levels();

@arthurr0
Copy link
Author

Thank you wery much <3

@A248
Copy link
Owner

A248 commented Jun 13, 2021

You're welcome. A thanks to you too - I've added this information to the wiki now:
https://github.com/A248/DazzleConf/wiki/Examples-of-custom-types-in-your-configuration

@A248 A248 closed this as completed Jun 13, 2021
@arthurr0
Copy link
Author

Map key need be String :(

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeRemainingMapEntries(CommentedWriter.java:99) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeMap(CommentedWriter.java:93) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.lambda$writeValue$0(CommentedWriter.java:188) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.descendAndDo(CommentedWriter.java:157) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeValue(CommentedWriter.java:188) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeRemainingMapEntries(CommentedWriter.java:112) ~[?:?]        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeMap(CommentedWriter.java:93) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.lambda$writeValue$0(CommentedWriter.java:188) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.descendAndDo(CommentedWriter.java:157) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeValue(CommentedWriter.java:188) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeRemainingMapEntries(CommentedWriter.java:112) ~[?:?]        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeMap(CommentedWriter.java:93) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.CommentedWriter.writeData(CommentedWriter.java:84) ~[?:?]
        at space.arim.dazzleconf.ext.snakeyaml.SnakeYamlConfigurationFactory.writeMapToWriter(SnakeYamlConfigurationFactory.java:148) ~[?:?]
        at space.arim.dazzleconf.factory.AbstractConfigurationFactory$ConfigFactoryDelegate.writeMap(AbstractConfigurationFactory.java:153) ~[?:?]
        at space.arim.dazzleconf.factory.HumanReadableConfigurationFactory.bufferedWriteMap(HumanReadableConfigurationFactory.java:125) ~[?:?]
        at space.arim.dazzleconf.factory.HumanReadableConfigurationFactory.writeMap(HumanReadableConfigurationFactory.java:114) ~[?:?]
        at space.arim.dazzleconf.factory.ConfigurationFormatFactory.write(ConfigurationFormatFactory.java:184) ~[?:?]
        at space.arim.dazzleconf.factory.DelegatingConfigurationFactory.write(DelegatingConfigurationFactory.java:72) ~[?:?]
        at space.arim.dazzleconf.factory.AbstractConfigurationFactory.write(AbstractConfigurationFactory.java:42) ~[?:?]        at space.arim.dazzleconf.helper.ConfigurationHelper.reloadConfigData(ConfigurationHelper.java:102) ~[?:?]
        at pl.minecodes.minespawner.configuration.ConfigurationLoader.reloadConfig(ConfigurationLoader.java:35) ~[?:?]
        at pl.minecodes.minespawner.MineSpawner.loadConfiguration(MineSpawner.java:33) ~[?:?]
        at pl.minecodes.minespawner.MineSpawner.onEnable(MineSpawner.java:41) ~[?:?]

@A248
Copy link
Owner

A248 commented Jun 13, 2021

Thanks. This is a bug with the snakeyaml extension. The core should support non-string keys.

Also, I tested that this bug is specific to CommentMode.alternateWriter as well as CommentMode.fullComments. For now, to avoid it, you can use CommentMode.headerOnly, which lacks comment support except for the header.

If you need comments and can't wait until the next release, let me know and I will publish a SNAPSHOT release with the bug fix.

@A248 A248 added the documentation Improvements or additions to documentation label Jun 13, 2021
@A248
Copy link
Owner

A248 commented Jul 5, 2021

Released in 1.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants