From 86af4d18b85e44448950dc7c3376ccb7a1c3e48d Mon Sep 17 00:00:00 2001 From: Pat Garrity Date: Thu, 11 Sep 2025 21:34:54 -0500 Subject: [PATCH] (patch) Better UX: Convert Datagen to Gen, add better list/set functions. --- build.sbt | 2 +- .../main/scala/gs/datagen/v0/Datagen.scala | 9 +++ .../src/main/scala/gs/datagen/v0/gen.scala | 59 +++++++++++++++++++ project/build.properties | 2 +- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 344131e..2dc4a93 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -val scala3: String = "3.7.1" +val scala3: String = "3.7.2" ThisBuild / scalaVersion := scala3 ThisBuild / versionScheme := Some("semver-spec") diff --git a/modules/core/src/main/scala/gs/datagen/v0/Datagen.scala b/modules/core/src/main/scala/gs/datagen/v0/Datagen.scala index 13dea7d..ac38ac7 100644 --- a/modules/core/src/main/scala/gs/datagen/v0/Datagen.scala +++ b/modules/core/src/main/scala/gs/datagen/v0/Datagen.scala @@ -13,6 +13,15 @@ abstract class Datagen[A, -I]: */ def generate(input: I): A + /** Convert this to a `Gen[A]` using the supplied input. + * + * @param input + * The input that must always be applied. + * @return + * The new generator that does not require input. + */ + def toGen(input: I): Gen[A] = (_: Any) => this.generate(input) + def flatMap[B, I2 <: I](f: A => Datagen[B, I2]): Datagen[B, I2] = new Datagen.Defer[B, I2](input => f(generate(input)).generate(input)) diff --git a/modules/core/src/main/scala/gs/datagen/v0/gen.scala b/modules/core/src/main/scala/gs/datagen/v0/gen.scala index f145427..1981f16 100644 --- a/modules/core/src/main/scala/gs/datagen/v0/gen.scala +++ b/modules/core/src/main/scala/gs/datagen/v0/gen.scala @@ -158,6 +158,35 @@ object Gen: gen: Gen[A] ): Gen[List[A]] = new GenList[A](size, gen) + /** Generator for a list of some fixed size based on a generator for the list + * elements. + * + * @param fixedSize + * The [[gs.datagen.v0.generators.Size]] of the list. + * @param gen + * The generator for the list elements. + */ + def list[A]( + fixedSize: Int, + gen: Gen[A] + ): Gen[List[A]] = new GenList[A](Size.Fixed(fixedSize), gen) + + /** Generator for a list of some size based on a generator for the list + * elements. + * + * @param minSize + * The minimum size of the list. + * @param maxSize + * The maximum size of the list. + * @param gen + * The generator for the list elements. + */ + def list[A]( + minSize: Int, + maxSize: Int, + gen: Gen[A] + ): Gen[List[A]] = new GenList[A](Size.Between(minSize, maxSize), gen) + /** Generator for a set of some [[gs.datagen.v0.generators.Size]] based on a * generator for the set elements. * @@ -172,6 +201,36 @@ object Gen: gen: Gen[A] ): Gen[Set[A]] = new GenSet[A](size, gen) + /** Generator for a set of some fixed size based on a generator for the set + * elements. + * + * @param fixedSize + * The goal [[gs.datagen.v0.generators.Size]] of the set. If duplicate + * elements are generated, the size will be less then specified. + * @param gen + * The generator for the list elements. + */ + def set[A]( + fixedSize: Int, + gen: Gen[A] + ): Gen[Set[A]] = new GenSet[A](Size.Fixed(fixedSize), gen) + + /** Generator for a set of some size based on a generator for the set + * elements. + * + * @param minSize + * Minimum size of the generated set. + * @param maxSize + * Maximum size of the generated set. + * @param gen + * The generator for the list elements. + */ + def set[A]( + minSize: Int, + maxSize: Int, + gen: Gen[A] + ): Gen[Set[A]] = new GenSet[A](Size.Between(minSize, maxSize), gen) + /** Generators which pick a single random element from a collection. */ object oneOf: diff --git a/project/build.properties b/project/build.properties index bbb0b60..5e6884d 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.11.2 +sbt.version=1.11.6 -- 2.43.0