All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.RaptorSettings.kt Maven / Gradle / Ivy

There is a newer version: 0.27.0
Show newest version
package io.fluidsonic.raptor


// FIXME inject with DI? or should this only be used at assembly-time?
// FIXME refactor
public interface RaptorSettings {

	public fun hasValue(path: String): Boolean
	public fun valueOrNull(path: String): Value?


	public companion object {

		public val empty: RaptorSettings = EmptyRaptorSettings


		public fun lookup(vararg settings: RaptorSettings): RaptorSettings =
			lookup(settings.toList())


		public fun lookup(settings: Iterable): RaptorSettings =
			LookupRaptorSettings(settings.toList())
	}


	@RaptorDsl
	public class Builder internal constructor() {

		private val values: MutableMap = hashMapOf()


		internal fun build(): RaptorSettings {
			if (values.isEmpty())
				return empty

			return DefaultRaptorSettings(values = values.toMap(hashMapOf()))
		}


		@RaptorDsl
		public fun set(key: String, value: Int) {
			set(key, Value.of(value))
		}


		@RaptorDsl
		public fun set(key: String, value: String) {
			set(key, Value.of(value))
		}


		@RaptorDsl
		public fun set(key: String, value: Value) {
			values[key] = value
		}


		@RaptorDsl
		public infix fun String.by(value: Int) {
			this by Value.of(value)
		}


		@RaptorDsl
		public infix fun String.by(value: String) {
			this by Value.of(value)
		}


		@RaptorDsl
		public infix fun String.by(value: Value) {
			set(this, value)
		}


		@RaptorDsl
		public operator fun String.invoke(values: Builder.() -> Unit) {
			[email protected][this] = Value.of(Builder().apply(values).build())
		}
	}


	public interface Value {

		public fun int(): Int
		public fun intList(): List
		public fun settings(): RaptorSettings
		public fun settingsList(): List
		public fun string(): String
		public fun stringList(): List


		public companion object {

			public fun of(string: Int): Value =
				IntValue(string)


			public fun of(string: String): Value =
				StringValue(string)


			public fun of(settings: RaptorSettings): Value =
				SettingsValue(settings)


			private class IntValue(val value: Int) : Value {

				override fun int() =
					value


				override fun intList() =
					listOf(value)


				override fun settings() =
					error("Int value cannot be converted to settings: $value")


				override fun settingsList() =
					error("Int value cannot be converted to settings: $value")


				override fun string() =
					error("Int value cannot be converted to string: $value")


				override fun stringList() =
					error("Int value cannot be converted to string: $value")
			}


			private class SettingsValue(private val value: RaptorSettings) : Value {

				override fun int() =
					error("Settings value cannot be converted to int: $value")


				override fun intList() =
					error("Settings value cannot be converted to int: $value")


				override fun settings() =
					value


				override fun settingsList() =
					listOf(value)


				override fun string() =
					error("Settings value cannot be converted to string: $value")


				override fun stringList() =
					error("Settings value cannot be converted to string: $value")
			}


			private class StringValue(val value: String) : Value {

				override fun int() =
					error("String value cannot be converted to int: $value")


				override fun intList() =
					error("String value cannot be converted to int: $value")


				override fun settings() =
					error("String value cannot be converted to settings: $value")


				override fun settingsList() =
					error("String value cannot be converted to settings: $value")


				override fun string() =
					value


				override fun stringList() =
					listOf(value)
			}
		}
	}
}


public fun RaptorSettings.int(path: String): Int =
	value(path).int()


public fun RaptorSettings.intList(path: String): List =
	value(path).intList()


public fun RaptorSettings.settings(path: String): RaptorSettings =
	value(path).settings()


public fun RaptorSettings.settingsList(path: String): List =
	value(path).settingsList()


public operator fun RaptorSettings.get(path: String): RaptorSettings.Value? =
	valueOrNull(path)


public fun RaptorSettings.string(path: String): String =
	value(path).string()


public fun RaptorSettings.stringOrNull(path: String): String? =
	valueOrNull(path)?.string()


public fun RaptorSettings.stringList(path: String): List =
	value(path).stringList()


public fun RaptorSettings.value(path: String): RaptorSettings.Value =
	valueOrNull(path) ?: error("Settings are missing a value for path '$path'.")


@RaptorDsl
public fun RaptorRootComponent.install(settings: RaptorSettings) {
	componentRegistry.oneOrNull(RaptorSettingsComponent.Key)?.let {
		error("Cannot set settings multiple times. Use RaptorSettings.lookup(…) to combine multiple settings.")
	}

	componentRegistry.register(RaptorSettingsComponent.Key, RaptorSettingsComponent(settings = settings))
}


@RaptorDsl
@Suppress("unused")
public fun RaptorGlobalDsl.settings(configure: RaptorSettings.Builder.() -> Unit): RaptorSettings =
	RaptorSettings.Builder().apply(configure).build()


@RaptorDsl
public val RaptorTopLevelConfigurationScope.settings: RaptorSettings
	get() = componentRegistry.root.oneOrNull(RaptorSettingsComponent.Key)?.settings
		?: error("No settings have been registered. Use install(settings) inside raptor { … } before any other configuration.")




© 2015 - 2025 Weber Informatics LLC | Privacy Policy