Skip to content

Commit c730f4b

Browse files
authored
Replace LocalizationContext factories with a builder (#259)
1 parent e483627 commit c730f4b

File tree

7 files changed

+146
-50
lines changed

7 files changed

+146
-50
lines changed

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/localization/context/AppLocalizationContext.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ import javax.annotation.CheckReturnValue
2121
*
2222
* ### Manual usage
2323
* While instances of this interface are primarily injected with [@LocalizationBundle][LocalizationBundle],
24-
* you can also construct instances of this interface with [LocalizationContext.create].
24+
* you can also construct instances of this interface with [LocalizationContext.builder].
2525
*
2626
* Instances are only injectable if the event is a subclass of [Interaction].
2727
*
2828
* @see userLocale
2929
* @see guildLocale
30-
* @see LocalizationContext.create
30+
* @see LocalizationContext.builder
3131
*/
3232
interface AppLocalizationContext : TextLocalizationContext {
3333
/**

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/localization/context/LocalizationContext.kt

Lines changed: 106 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import io.github.freya022.botcommands.api.core.service.getService
66
import io.github.freya022.botcommands.api.localization.Localization
77
import io.github.freya022.botcommands.api.localization.LocalizationService
88
import io.github.freya022.botcommands.api.localization.annotations.LocalizationBundle
9-
import io.github.freya022.botcommands.api.localization.context.LocalizationContext.Companion.create
9+
import io.github.freya022.botcommands.api.localization.context.LocalizationContext.Companion.builder
1010
import io.github.freya022.botcommands.api.localization.interaction.GuildLocaleProvider
1111
import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider
1212
import io.github.freya022.botcommands.api.localization.text.TextCommandLocaleProvider
@@ -38,7 +38,7 @@ typealias PairEntry = Pair<String, Any>
3838
*
3939
* @see TextLocalizationContext
4040
* @see AppLocalizationContext
41-
* @see create
41+
* @see builder
4242
*/
4343
interface LocalizationContext {
4444
/**
@@ -61,11 +61,9 @@ interface LocalizationContext {
6161
val localizationBundle: String
6262

6363
/**
64-
* Returns the localization prefix of the current context.
64+
* The prefix to add to every localization request.
6565
*
66-
* The localization prefix can either come from [LocalizationBundle.prefix] or [withPrefix].
67-
*
68-
* @return The localization prefix for this context, or `null` if none has been set
66+
* This will be ignored if the request's path starts with a `/`.
6967
*
7068
* @see withPrefix
7169
*/
@@ -153,9 +151,80 @@ interface LocalizationContext {
153151
fun localizeOrNull(localizationPath: String, vararg entries: Localization.Entry): String? =
154152
localizeOrNull(effectiveLocale, localizationPath, *entries)
155153

154+
class Builder internal constructor(private val localizationService: LocalizationService, private val bundleName: String) {
155+
private var prefix: String? = null
156+
private var guildLocaleProvider: Lazy<DiscordLocale>? = null
157+
private var userLocaleProvider: Lazy<DiscordLocale>? = null
158+
159+
/**
160+
* Sets the prefix of the context.
161+
*
162+
* @see LocalizationContext.localizationPrefix
163+
*/
164+
fun setPrefix(prefix: String?): Builder {
165+
this.prefix = prefix
166+
return this
167+
}
168+
169+
/**
170+
* Sets the guild locale to be provided by the passed [GuildLocaleProvider].
171+
*/
172+
fun setGuildLocaleProvider(provider: GuildLocaleProvider, interaction: Interaction): Builder {
173+
return setGuildLocaleProvider(lazy { provider.getDiscordLocale(interaction) })
174+
}
175+
176+
/**
177+
* Sets the guild locale to be provided by the passed [TextCommandLocaleProvider].
178+
*/
179+
fun setGuildLocaleProvider(provider: TextCommandLocaleProvider, event: MessageReceivedEvent): Builder {
180+
return setGuildLocaleProvider(lazy { provider.getDiscordLocale(event) })
181+
}
182+
183+
/**
184+
* Sets the guild locale to the provided one.
185+
*/
186+
fun setGuildLocale(locale: DiscordLocale): Builder {
187+
return setGuildLocaleProvider(lazyOf(locale))
188+
}
189+
190+
private fun setGuildLocaleProvider(provider: Lazy<DiscordLocale>): Builder {
191+
this.guildLocaleProvider = provider
192+
return this
193+
}
194+
195+
/**
196+
* Sets the user locale to be provided by the passed [UserLocaleProvider].
197+
*/
198+
fun setUserLocaleProvider(provider: UserLocaleProvider, interaction: Interaction): Builder {
199+
return setUserLocaleProvider(lazy { provider.getDiscordLocale(interaction) })
200+
}
201+
202+
/**
203+
* Sets the user locale to the provided one.
204+
*/
205+
fun setUserLocale(locale: DiscordLocale): Builder {
206+
return setUserLocaleProvider(lazyOf(locale))
207+
}
208+
209+
private fun setUserLocaleProvider(provider: Lazy<DiscordLocale>): Builder {
210+
this.userLocaleProvider = provider
211+
return this
212+
}
213+
214+
/**
215+
* Builds an instance with the current configuration.
216+
*
217+
* **Note:** This returns an [AppLocalizationContext] (instead of a [LocalizationContext]) to give you full capabilities.
218+
*/
219+
fun build(): AppLocalizationContext {
220+
return LocalizationContextImpl(localizationService, bundleName, prefix, guildLocaleProvider, userLocaleProvider)
221+
}
222+
}
223+
156224
companion object {
157225
@JvmStatic
158226
@JvmOverloads
227+
@Deprecated("Replaced by builder")
159228
fun create(
160229
context: BContext,
161230
localizationBundle: String,
@@ -167,13 +236,14 @@ interface LocalizationContext {
167236
context.getService<LocalizationService>(),
168237
localizationBundle,
169238
localizationPrefix,
170-
guildLocale,
171-
userLocale
239+
guildLocale?.toProvider(),
240+
userLocale?.toProvider()
172241
)
173242
}
174243

175244
@JvmStatic
176245
@JvmOverloads
246+
@Deprecated("Replaced by builder")
177247
fun create(
178248
localizationService: LocalizationService,
179249
localizationBundle: String,
@@ -185,13 +255,14 @@ interface LocalizationContext {
185255
localizationService,
186256
localizationBundle,
187257
localizationPrefix,
188-
guildLocale,
189-
userLocale
258+
guildLocale?.toProvider(),
259+
userLocale?.toProvider()
190260
)
191261
}
192262

193263
@JvmStatic
194264
@JvmOverloads
265+
@Deprecated("Replaced by builder")
195266
fun fromLocaleProviders(
196267
context: BContext,
197268
event: Interaction,
@@ -202,13 +273,14 @@ interface LocalizationContext {
202273
context.getService<LocalizationService>(),
203274
localizationBundle,
204275
localizationPrefix,
205-
context.getService<GuildLocaleProvider>().getDiscordLocale(event),
206-
context.getService<UserLocaleProvider>().getDiscordLocale(event),
276+
lazy { context.getService<GuildLocaleProvider>().getDiscordLocale(event) },
277+
lazy { context.getService<UserLocaleProvider>().getDiscordLocale(event) },
207278
)
208279
}
209280

210281
@JvmStatic
211282
@JvmOverloads
283+
@Deprecated("Replaced by builder")
212284
fun fromLocaleProviders(
213285
context: BContext,
214286
event: MessageReceivedEvent,
@@ -220,10 +292,30 @@ interface LocalizationContext {
220292
context.getService<LocalizationService>(),
221293
localizationBundle,
222294
localizationPrefix,
223-
context.getService<TextCommandLocaleProvider>().getDiscordLocale(event),
224-
userLocale,
295+
lazy { context.getService<TextCommandLocaleProvider>().getDiscordLocale(event) },
296+
userLocale?.toProvider(),
225297
)
226298
}
299+
300+
/**
301+
* Creates a new builder, using a [LocalizationService] retrieved from the provided context,
302+
* and the specified bundle name, from which the strings will be retrieved from.
303+
*/
304+
@JvmStatic
305+
fun builder(context: BContext, localizationBundle: String): Builder {
306+
return Builder(localizationService = context.getService(), localizationBundle)
307+
}
308+
309+
/**
310+
* Creates a new builder, using a [LocalizationService] and the specified bundle name,
311+
* from which the strings will be retrieved from.
312+
*/
313+
@JvmStatic
314+
fun builder(localizationService: LocalizationService, localizationBundle: String): Builder {
315+
return Builder(localizationService, localizationBundle)
316+
}
317+
318+
private fun DiscordLocale.toProvider(): Lazy<DiscordLocale> = lazyOf(this)
227319
}
228320
}
229321

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/localization/context/TextLocalizationContext.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ import javax.annotation.CheckReturnValue
2020
*
2121
* ### Manual usage
2222
* While instances of this interface are primarily injected with [@LocalizationBundle][LocalizationBundle],
23-
* you can also construct instances of this interface with [LocalizationContext.create].
23+
* you can also construct instances of this interface with [LocalizationContext.builder].
2424
*
2525
* Instances are only injectable if the event is a subclass of either [Interaction] or [MessageReceivedEvent].
2626
*
2727
* @see guildLocale
2828
* @see AppLocalizationContext
2929
*
30-
* @see LocalizationContext.create
30+
* @see LocalizationContext.builder
3131
*/
3232
interface TextLocalizationContext : LocalizationContext {
3333
/**
@@ -124,4 +124,4 @@ fun TextLocalizationContext.localizeGuild(localizationPath: String, vararg entri
124124
* @see Guild.getLocale
125125
*/
126126
fun TextLocalizationContext.localizeGuildOrNull(localizationPath: String, vararg entries: PairEntry): String? =
127-
localizeOrNull(guildLocale, localizationPath, *entries.mapToEntries())
127+
localizeOrNull(guildLocale, localizationPath, *entries.mapToEntries())

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/internal/localization/LocalizationContextImpl.kt

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,25 @@ internal class LocalizationContextImpl(
1414
private val localizationService: LocalizationService,
1515
override val localizationBundle: String,
1616
override val localizationPrefix: String?,
17-
private val _guildLocale: DiscordLocale?,
18-
private val _userLocale: DiscordLocale?
17+
private val _guildLocaleProvider: Lazy<DiscordLocale>?,
18+
private val _userLocaleProvider: Lazy<DiscordLocale>?,
1919
) : TextLocalizationContext, AppLocalizationContext {
20+
private val guildLocaleProvider: Lazy<DiscordLocale>
21+
get() = _guildLocaleProvider ?: throwArgument("Cannot guild localize on an event which doesn't provide guild localization")
22+
23+
private val userLocaleProvider: Lazy<DiscordLocale>
24+
get() = _userLocaleProvider ?: throwArgument("Cannot user localize on an event which doesn't provide user localization")
25+
2026
override val userLocale: DiscordLocale
21-
get() = _userLocale ?: throwArgument("Cannot user localize on an event which doesn't provide user localization")
27+
get() = guildLocaleProvider.value
2228

2329
override val guildLocale: DiscordLocale
24-
get() = _guildLocale ?: throwArgument("Cannot guild localize on an event which doesn't provide guild localization")
30+
get() = userLocaleProvider.value
2531

2632
override val effectiveLocale: DiscordLocale
2733
get() = when {
28-
_userLocale != null -> _userLocale
29-
hasGuildLocale() -> guildLocale
34+
_userLocaleProvider != null -> userLocale
35+
_guildLocaleProvider != null -> guildLocale
3036
else -> DiscordLocale.ENGLISH_US
3137
}
3238

@@ -38,27 +44,27 @@ internal class LocalizationContextImpl(
3844
}
3945

4046
override fun withGuildLocale(guildLocale: DiscordLocale?): LocalizationContextImpl {
41-
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, guildLocale, _userLocale)
47+
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, guildLocale?.toProvider(), _userLocaleProvider)
4248
}
4349

4450
override fun withUserLocale(userLocale: DiscordLocale?): LocalizationContextImpl {
45-
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, _guildLocale, userLocale)
51+
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, _guildLocaleProvider, userLocale?.toProvider())
4652
}
4753

4854
override fun withBundle(localizationBundle: String): LocalizationContextImpl {
49-
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, _guildLocale, _userLocale)
55+
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, _guildLocaleProvider, _userLocaleProvider)
5056
}
5157

5258
override fun withPrefix(localizationPrefix: String?): LocalizationContextImpl {
53-
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, _guildLocale, _userLocale)
59+
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, _guildLocaleProvider, _userLocaleProvider)
5460
}
5561

5662
override fun switchBundle(localizationBundle: String): LocalizationContextImpl {
57-
return LocalizationContextImpl(localizationService, localizationBundle, null, _guildLocale, _userLocale)
63+
return LocalizationContextImpl(localizationService, localizationBundle, null, _guildLocaleProvider, _userLocaleProvider)
5864
}
5965

6066
fun withLocales(guildLocale: DiscordLocale, userLocale: DiscordLocale): LocalizationContextImpl {
61-
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, guildLocale, userLocale)
67+
return LocalizationContextImpl(localizationService, localizationBundle, localizationPrefix, lazyOf(guildLocale), lazyOf(userLocale))
6268
}
6369

6470
override fun localize(locale: DiscordLocale, localizationPath: String, vararg entries: Localization.Entry): String {
@@ -83,6 +89,8 @@ internal class LocalizationContextImpl(
8389
?: throwInternal("Found no localization instance for bundle '$localizationBundle' and locale '$discordLocale', the root bundle should have been checked")
8490

8591
override fun hasGuildLocale(): Boolean {
86-
return _guildLocale != null
92+
return _guildLocaleProvider != null
8793
}
88-
}
94+
95+
private fun DiscordLocale.toProvider(): Lazy<DiscordLocale> = lazyOf(this)
96+
}

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,11 @@ internal class LocalizableInteractionImpl internal constructor(
3434
private val guildLocale: Locale by lazy { guildLocaleProvider.getLocale(deferrableCallback) }
3535

3636
override fun getLocalizationContext(bundleName: String, pathPrefix: String?): AppLocalizationContext {
37-
return LocalizationContext.create(
38-
localizationService,
39-
bundleName,
40-
pathPrefix,
41-
guildLocale = guildLocaleProvider.getDiscordLocale(deferrableCallback),
42-
userLocale = userLocaleProvider.getDiscordLocale(deferrableCallback)
43-
)
37+
return LocalizationContext.builder(localizationService, bundleName)
38+
.setPrefix(pathPrefix)
39+
.setGuildLocaleProvider(guildLocaleProvider, deferrableCallback)
40+
.setUserLocaleProvider(userLocaleProvider, deferrableCallback)
41+
.build()
4442
}
4543

4644
@Suppress("DEPRECATION", "removal")
@@ -64,4 +62,4 @@ internal class LocalizableInteractionImpl internal constructor(
6462
override fun getHook(): LocalizableInteractionHook {
6563
return LocalizableInteractionHookImpl(deferrableCallback.hook, this)
6664
}
67-
}
65+
}

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ internal class LocalizableTextCommandImpl internal constructor(
2929
private val locale: Locale by lazy { localeProvider.getLocale(event) }
3030

3131
override fun getLocalizationContext(bundleName: String, pathPrefix: String?): TextLocalizationContext {
32-
return LocalizationContext.create(
33-
localizationService,
34-
bundleName,
35-
pathPrefix,
36-
guildLocale = localeProvider.getDiscordLocale(event)
37-
)
32+
return LocalizationContext.builder(localizationService, bundleName)
33+
.setPrefix(pathPrefix)
34+
.setGuildLocaleProvider(localeProvider, event)
35+
.build()
3836
}
3937

4038
@Suppress("DEPRECATION", "removal")

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/localization/LocalizationContextResolverFactories.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ internal object LocalizationContextResolverFactories {
7474
localizationService,
7575
localizationBundle = annotation.value,
7676
localizationPrefix = annotation.prefix.nullIfBlank(),
77-
_guildLocale = null,
78-
_userLocale = null
77+
_guildLocaleProvider = null,
78+
_userLocaleProvider = null,
7979
)
8080
}
81-
}
81+
}

0 commit comments

Comments
 (0)