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

JsonArrayBuilder - add convenience function for adding multiple elements #2127

Closed
aSemy opened this issue Dec 17, 2022 · 2 comments
Closed
Labels
design feature json-builders Suggested enhancements for JsonElements builders

Comments

@aSemy
Copy link
Contributor

aSemy commented Dec 17, 2022

What is your use-case and why do you need this feature?

When building a JSON array I'd like to add multiple strings.

Currently this must be done one at a time, using JsonArrayBuilder.add(value: String?)

val alphaDependencies = listOf("a", "b", "c")

buildJsonObject {
  put("name", "alpha")
  putJsonArray("dependencies") {

    // currently have to manually define a for-loop
    alphaDependencies.forEach { dep -> 
      add(dep)
    }
  }
}.toString()

It's a surprise that buildJsonArray() doesn't have addAll(), because buildList() does have addAll().

val x = listOf('b', 'c')

val y = buildList() {
    addAll(x)
}

Describe the solution you'd like

It would be convenient to have an addAll(elements: Collection<String>) helper function that would accept a list

I'm proposing four new functions.

1 function in JsonArrayBuilder for adding multiple JsonElements.

public class JsonArrayBuilder @PublishedApi internal constructor() {
    
    /**
     * Adds the given JSON [elements] to a resulting JSON array.
     *
     * @return `true` if the list was changed as the result of the operation.
     */
    public fun addAll(elements: Collection<JsonElement>): Boolean {
      return content.addAll(elements)
    }
}

And 3 extension functions, for adding strings, numbers, booleans:

/** Adds the given string [values] to a resulting JSON array. */
public fun JsonArrayBuilder.addAll(values: Collection<String?>): Boolean =
  addAll(values.map(::JsonPrimitive))

/** Adds the given boolean [values] to a resulting JSON array. */
public fun JsonArrayBuilder.addAll(values: Collection<Boolean?>): Boolean =
  addAll(values.map(::JsonPrimitive))

/** Adds the given numeric [values] to a resulting JSON array. */
public fun JsonArrayBuilder.addAll(values: Collection<Number?>): Boolean =
  addAll(values.map(::JsonPrimitive))

Example usage

buildJsonObject {
  put("name", "alpha")
  putJsonArray("dependencies") {
    // no more need for a for loop
    addAll(alphaDependencies)
  }
}.toString()
@aSemy aSemy added the feature label Dec 17, 2022
@aSemy aSemy changed the title JsonArrayBuilder - ad convenience function for adding multiple elements JsonArrayBuilder - add convenience function for adding multiple elements Dec 17, 2022
@sandwwraith sandwwraith added design json-builders Suggested enhancements for JsonElements builders labels Dec 19, 2022
@sandwwraith
Copy link
Member

I wonder if we should just add addAll or simply make JsonArrayBuilder implement MutableList (by delegation, like with JsonArray or by implementing AbstractMutableList)

@aSemy
Copy link
Contributor Author

aSemy commented Jan 19, 2023

Yeah, that thought crossed my mind. It makes sense to me. It could even be an inline class:

@JvmInline
public value class JsonArrayBuilder @PublishedApi internal constructor(
    private val content: MutableList<JsonElement> = mutableListOf()
): MutableList<JsonElement> by content

The add() and addAll() extension function overloads for adding raw strings/numbers/booleans would still be needed.

I chose not to do it in #2156 because implementing MutableList is a more significant change, and it can be done in a later PR - the addAll() overloads would work seamlessly. But we can do it immediately, if you approve!

Going one step further, all of the JsonArrayBuilder extension functions could also extend MutableList<JsonElement> instead of JsonArrayBuilder.

public fun MutableList<JsonElement>.add(value: Number?): Boolean = add(JsonPrimitive(value))

The upside being that these convenience functions would work for both JsonArrayBuilder and MutableList<JsonElement>, which is convenient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design feature json-builders Suggested enhancements for JsonElements builders
Projects
None yet
Development

No branches or pull requests

2 participants