Skip to content

Commit 66c05df

Browse files
Merge pull request #6 from RedMadRobot/feature/5-add-kdoc-for-public-classes
#5 - Added comprehensive KDoc documentation for all public APIs
2 parents 8e01fc7 + 7bfdc5e commit 66c05df

File tree

12 files changed

+377
-1
lines changed

12 files changed

+377
-1
lines changed

konfeature/src/commonMain/kotlin/com/redmadrobot/konfeature/FeatureConfig.kt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,37 @@ import com.redmadrobot.konfeature.source.SourceSelectionStrategy
44
import kotlin.properties.ReadOnlyProperty
55
import kotlin.reflect.KProperty
66

7+
/**
8+
* Abstract base class for defining feature configurations.
9+
*
10+
* FeatureConfig provides a declarative way to define configuration schemas using
11+
* property delegates. Each configuration element is defined using either `by toggle()`
12+
* for Boolean values or `by value()` for other types.
13+
*
14+
* Example usage:
15+
* ```kotlin
16+
* class MyFeatureConfig : FeatureConfig(
17+
* name = "my_feature",
18+
* description = "Configuration for my feature"
19+
* ) {
20+
* val isEnabled: Boolean by toggle(
21+
* key = "my_feature_enabled",
22+
* description = "Enable/disable my feature",
23+
* defaultValue = false,
24+
* sourceSelectionStrategy = SourceSelectionStrategy.Any
25+
* )
26+
*
27+
* val timeout: Long by value(
28+
* key = "my_feature_timeout",
29+
* description = "Timeout in milliseconds",
30+
* defaultValue = 5000L
31+
* )
32+
* }
33+
* ```
34+
*
35+
* @param name unique identifier for this configuration
36+
* @param description human-readable description of this configuration's purpose
37+
*/
738
public abstract class FeatureConfig(
839
override val name: String,
940
override val description: String
@@ -34,6 +65,16 @@ public abstract class FeatureConfig(
3465
error("Use toggle instead of boolean value")
3566
}
3667

68+
/**
69+
* Creates a configuration value delegate for non-Boolean types.
70+
*
71+
* @param T the type of the configuration value
72+
* @param key unique identifier for this value used in sources
73+
* @param description human-readable description of this value's purpose
74+
* @param defaultValue fallback value when no sources provide a value
75+
* @param sourceSelectionStrategy strategy for selecting which sources can provide values
76+
* @return a property delegate that resolves the configuration value
77+
*/
3778
public fun <T : Any> value(
3879
key: String,
3980
description: String,
@@ -48,6 +89,18 @@ public abstract class FeatureConfig(
4889
)
4990
}
5091

92+
/**
93+
* Creates a configuration toggle delegate for Boolean values.
94+
*
95+
* This method should be used instead of `value()` for Boolean configuration
96+
* elements to provide better semantic clarity for feature flags and toggles.
97+
*
98+
* @param key unique identifier for this toggle used in sources
99+
* @param description human-readable description of this toggle's purpose
100+
* @param defaultValue fallback value when no sources provide a value
101+
* @param sourceSelectionStrategy strategy for selecting which sources can provide values
102+
* @return a property delegate that resolves the Boolean configuration value
103+
*/
51104
public fun toggle(
52105
key: String,
53106
description: String,
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,36 @@
11
package com.redmadrobot.konfeature
22

3+
/**
4+
* Interface representing the specification of a feature configuration.
5+
*
6+
* This interface provides metadata about a feature configuration including
7+
* its name, description, and the list of configuration values it contains.
8+
* It's implemented by [FeatureConfig] and used for introspection and
9+
* building debug interfaces.
10+
*
11+
* @see FeatureConfig for the concrete implementation
12+
*/
313
public interface FeatureConfigSpec {
14+
/**
15+
* Unique name identifying this feature configuration.
16+
*
17+
* The name should be descriptive and unique among all registered configurations.
18+
*/
419
public val name: String
20+
21+
/**
22+
* Human-readable description of what this feature configuration controls.
23+
*
24+
* This description helps developers understand the purpose and scope of
25+
* the configuration when viewing it in debug panels or documentation.
26+
*/
527
public val description: String
28+
29+
/**
30+
* List of all configuration value specifications contained in this configuration.
31+
*
32+
* This provides access to metadata about each individual configuration element,
33+
* including their keys, descriptions, default values, and source selection strategies.
34+
*/
635
public val values: List<FeatureValueSpec<out Any>>
736
}

konfeature/src/commonMain/kotlin/com/redmadrobot/konfeature/FeatureValue.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ package com.redmadrobot.konfeature
33
import com.redmadrobot.konfeature.source.FeatureValueSource
44
import dev.drewhamilton.poko.Poko
55

6+
/**
7+
* Represents a resolved configuration value along with information about its source.
8+
*
9+
* This class encapsulates both the actual configuration value and metadata about
10+
* where the value came from (default, source, or interceptor). This information
11+
* is useful for debugging, logging, and understanding the configuration resolution flow.
12+
*
13+
* @param T the type of the configuration value
14+
* @property source information about where this value originated from
15+
* @property value the resolved configuration value
16+
*/
617
@Poko
718
public class FeatureValue<T>(
819
public val source: FeatureValueSource,

konfeature/src/commonMain/kotlin/com/redmadrobot/konfeature/FeatureValueSpec.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@ package com.redmadrobot.konfeature
33
import com.redmadrobot.konfeature.source.SourceSelectionStrategy
44
import dev.drewhamilton.poko.Poko
55

6+
/**
7+
* Specification for a feature configuration value element.
8+
*
9+
* This class defines the metadata and behavior for a single configuration element
10+
* within a [FeatureConfig]. It includes the key used to look up values in sources,
11+
* documentation, fallback behavior, and source selection rules.
12+
*
13+
* @param T the type of the configuration value
14+
* @property key the unique identifier used to retrieve this value from sources
15+
* @property description human-readable description of what this configuration element controls
16+
* @property defaultValue the fallback value used when no sources provide a value
17+
* @property sourceSelectionStrategy strategy for determining which sources can provide values
18+
*/
619
@Poko
720
public class FeatureValueSpec<T : Any>(
821
public val key: String,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
11
package com.redmadrobot.konfeature
22

3+
/**
4+
* Main entry point for the Konfeature library that manages feature configuration.
5+
*
6+
* Konfeature provides a unified way to work with remote feature configurations by combining
7+
* multiple data sources, interceptors, and providing runtime access to configuration values.
8+
*
9+
* @see FeatureConfig for defining configuration schemas
10+
* @see com.redmadrobot.konfeature.source.FeatureSource for implementing configuration data sources
11+
* @see com.redmadrobot.konfeature.source.Interceptor for implementing value overrides
12+
*/
313
public interface Konfeature {
414

15+
/**
16+
* List of all registered feature configuration specifications.
17+
*
18+
* This property provides access to metadata about all registered [FeatureConfig] instances,
19+
* including their names, descriptions, and value specifications. Useful for building
20+
* debug panels or configuration management UIs.
21+
*/
522
public val spec: List<FeatureConfigSpec>
623

24+
/**
25+
* Retrieves the current value for a given feature configuration specification.
26+
*
27+
* The value resolution follows this order:
28+
* 1. Default value is assigned
29+
* 2. Sources are filtered using the spec's [com.redmadrobot.konfeature.source.SourceSelectionStrategy]
30+
* 3. Sources are searched in registration order (first match wins)
31+
* 4. Interceptors are applied in registration order (last non-null wins)
32+
*
33+
* @param T the type of the configuration value
34+
* @param spec the feature value specification defining the configuration element
35+
* @return [FeatureValue] containing the resolved value and its source
36+
*/
737
public fun <T : Any> getValue(spec: FeatureValueSpec<T>): FeatureValue<T>
838
}

konfeature/src/commonMain/kotlin/com/redmadrobot/konfeature/Logger.kt

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,40 @@
11
package com.redmadrobot.konfeature
22

3+
/**
4+
* Interface for logging Konfeature events and errors.
5+
*
6+
* The logger is used to track configuration value access, type mismatches,
7+
* and other diagnostic information. Implementations can integrate with
8+
* existing logging frameworks like Timber, SLF4J, or custom solutions.
9+
*
10+
* Events that are logged include:
11+
* - Configuration value access with source information
12+
* - Type mismatch warnings when sources return unexpected types
13+
* - Configuration validation warnings
14+
*/
315
public interface Logger {
416

17+
/**
18+
* Logs a message with the specified severity level.
19+
*
20+
* @param severity the severity level of the log message
21+
* @param message the message to log
22+
*/
523
public fun log(severity: Severity, message: String)
624

25+
/**
26+
* Severity levels for log messages.
27+
*/
728
public enum class Severity {
8-
WARNING, INFO
29+
/**
30+
* Warning level for non-critical issues like type mismatches or empty configurations.
31+
*/
32+
WARNING,
33+
34+
/**
35+
* Information level for normal operations like value access and source information.
36+
*/
37+
INFO
938
}
1039
}
1140

konfeature/src/commonMain/kotlin/com/redmadrobot/konfeature/builder/KonfeatureBuilder.kt

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,49 @@ import com.redmadrobot.konfeature.exception.SourceNameAlreadyExistException
88
import com.redmadrobot.konfeature.source.FeatureSource
99
import com.redmadrobot.konfeature.source.Interceptor
1010

11+
/**
12+
* Builder class for configuring and creating a [Konfeature] instance.
13+
*
14+
* KonfeatureBuilder uses the builder pattern to configure all aspects of a Konfeature
15+
* instance including sources, interceptors, feature configurations, and logging.
16+
* It validates the configuration during the build process to ensure consistency.
17+
*
18+
* Example usage:
19+
* ```kotlin
20+
* val konfeature = konfeature {
21+
* addSource(FirebaseFeatureSource(remoteConfig))
22+
* addInterceptor(DebugPanelInterceptor())
23+
* register(MyFeatureConfig())
24+
* setLogger(TimberLogger())
25+
* }
26+
* ```
27+
*
28+
* @see konfeature for the DSL function that creates and configures a builder
29+
*/
1130
public class KonfeatureBuilder {
1231
private val sources = mutableListOf<FeatureSource>()
1332
private var interceptors = mutableListOf<Interceptor>()
1433
private var spec = mutableListOf<FeatureConfig>()
1534
private var logger: Logger? = null
1635

36+
/**
37+
* Adds an interceptor to the Konfeature configuration.
38+
*
39+
* @param interceptor the interceptor to add
40+
* @return this builder instance for method chaining
41+
*/
1742
public fun addInterceptor(interceptor: Interceptor): KonfeatureBuilder {
1843
interceptors.add(interceptor)
1944
return this
2045
}
2146

47+
/**
48+
* Adds a feature source to the Konfeature configuration.
49+
*
50+
* @param source the source to add
51+
* @return this builder instance for method chaining
52+
* @throws SourceNameAlreadyExistException if a source with the same name already exists
53+
*/
2254
public fun addSource(source: FeatureSource): KonfeatureBuilder {
2355
if (sources.any { it.name == source.name }) {
2456
throw SourceNameAlreadyExistException(source.name)
@@ -28,6 +60,13 @@ public class KonfeatureBuilder {
2860
return this
2961
}
3062

63+
/**
64+
* Registers a feature configuration with the Konfeature instance.
65+
*
66+
* @param featureConfig the configuration to register
67+
* @return this builder instance for method chaining
68+
* @throws ConfigNameAlreadyExistException if a config with the same name already exists
69+
*/
3170
public fun register(featureConfig: FeatureConfig): KonfeatureBuilder {
3271
if (spec.any { it.name == featureConfig.name }) {
3372
throw ConfigNameAlreadyExistException(featureConfig.name)
@@ -36,11 +75,28 @@ public class KonfeatureBuilder {
3675
return this
3776
}
3877

78+
/**
79+
* Sets the logger for the Konfeature instance.
80+
*
81+
* @param logger the logger to use for Konfeature events
82+
* @return this builder instance for method chaining
83+
*/
3984
public fun setLogger(logger: Logger): KonfeatureBuilder {
4085
this.logger = logger
4186
return this
4287
}
4388

89+
/**
90+
* Builds and returns a configured Konfeature instance.
91+
*
92+
* This method validates the configuration and throws exceptions if:
93+
* - No feature configurations are registered
94+
* - Feature configurations have duplicate keys
95+
*
96+
* @return a fully configured Konfeature instance
97+
* @throws NoFeatureConfigException if no configurations are registered
98+
* @throws KeyDuplicationException if configurations have duplicate keys
99+
*/
44100
public fun build(): Konfeature {
45101
if (spec.isEmpty()) throw NoFeatureConfigException()
46102

@@ -81,6 +137,16 @@ public class KonfeatureBuilder {
81137
}
82138
}
83139

140+
/**
141+
* DSL function for creating and configuring a Konfeature instance.
142+
*
143+
* This function provides a convenient way to configure a Konfeature instance
144+
* using a builder DSL. It creates a KonfeatureBuilder, applies the configuration
145+
* block, and returns the built Konfeature instance.
146+
*
147+
* @param build configuration block applied to the KonfeatureBuilder
148+
* @return a configured Konfeature instance
149+
*/
84150
public fun konfeature(build: KonfeatureBuilder.() -> Unit): Konfeature {
85151
return KonfeatureBuilder().apply(build).build()
86152
}

konfeature/src/commonMain/kotlin/com/redmadrobot/konfeature/exception/KonfeatureException.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
package com.redmadrobot.konfeature.exception
22

3+
/**
4+
* Base sealed class for all Konfeature-specific exceptions.
5+
*
6+
* All exceptions thrown by the Konfeature library inherit from this class,
7+
* allowing for comprehensive error handling when working with the library.
8+
*/
39
public sealed class KonfeatureException(messageProvider: () -> String) : Exception(messageProvider.invoke())
410

11+
/**
12+
* Exception thrown when attempting to register a feature configuration with a name that already exists.
13+
*
14+
* @param name the duplicate configuration name
15+
*/
516
public class ConfigNameAlreadyExistException(
617
name: String
718
) : KonfeatureException({ "feature config with name '$name' already registered" })
819

20+
/**
21+
* Exception thrown when a feature configuration contains duplicate keys.
22+
*
23+
* @param values the list of duplicate keys
24+
* @param config the name of the configuration containing duplicates
25+
*/
926
public class KeyDuplicationException(
1027
values: List<String>,
1128
config: String
@@ -14,8 +31,16 @@ public class KeyDuplicationException(
1431
"values with keys <$duplicatedValues> are duplicated in config '$config'"
1532
})
1633

34+
/**
35+
* Exception thrown when attempting to build a Konfeature instance without any registered configurations.
36+
*/
1737
public class NoFeatureConfigException : KonfeatureException({ "No feature config added" })
1838

39+
/**
40+
* Exception thrown when attempting to register a source with a name that already exists.
41+
*
42+
* @param name the duplicate source name
43+
*/
1944
public class SourceNameAlreadyExistException(
2045
name: String
2146
) : KonfeatureException({ "source with name '$name' already registered" })

0 commit comments

Comments
 (0)