├── .github
└── workflows
│ ├── ci.yml
│ └── clean.yml
├── .gitignore
├── .mergify.yml
├── .scala-steward.conf
├── .scalafmt.conf
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.sbt
├── core
└── src
│ ├── main
│ └── scala
│ │ └── org
│ │ └── typelevel
│ │ └── unique
│ │ └── Unique.scala
│ └── test
│ └── scala
│ └── org
│ └── typelevel
│ └── unique
│ ├── CompileTest.scala
│ ├── UniqueSuite.scala
│ └── UniqueTests.scala
├── docs
├── Gemfile
├── Gemfile.lock
└── src
│ └── main
│ └── mdoc
│ └── index.md
└── project
├── build.properties
└── plugins.sbt
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | # This file was automatically generated by sbt-github-actions using the
2 | # githubWorkflowGenerate task. You should add and commit this file to
3 | # your git repository. It goes without saying that you shouldn't edit
4 | # this file by hand! Instead, if you wish to make changes, you should
5 | # change your sbt build configuration to revise the workflow description
6 | # to meet your needs, then regenerate this file.
7 |
8 | name: Continuous Integration
9 |
10 | on:
11 | pull_request:
12 | branches: ['*', series/*]
13 | push:
14 | branches: ['*', series/*]
15 | tags: [v*]
16 |
17 | env:
18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19 | SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
20 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
21 | PGP_SECRET: ${{ secrets.PGP_SECRET }}
22 |
23 | jobs:
24 | build:
25 | name: Build and Test
26 | strategy:
27 | matrix:
28 | os: [ubuntu-latest]
29 | scala: [2.12.15, 2.13.8, 3.0.2]
30 | java: [temurin@8, temurin@11, temurin@17]
31 | runs-on: ${{ matrix.os }}
32 | steps:
33 | - name: Checkout current branch (full)
34 | uses: actions/checkout@v2
35 | with:
36 | fetch-depth: 0
37 |
38 | - name: Setup Java (temurin@8)
39 | if: matrix.java == 'temurin@8'
40 | uses: actions/setup-java@v2
41 | with:
42 | distribution: temurin
43 | java-version: 8
44 |
45 | - name: Setup Java (temurin@11)
46 | if: matrix.java == 'temurin@11'
47 | uses: actions/setup-java@v2
48 | with:
49 | distribution: temurin
50 | java-version: 11
51 |
52 | - name: Setup Java (temurin@17)
53 | if: matrix.java == 'temurin@17'
54 | uses: actions/setup-java@v2
55 | with:
56 | distribution: temurin
57 | java-version: 17
58 |
59 | - name: Cache sbt
60 | uses: actions/cache@v2
61 | with:
62 | path: |
63 | ~/.sbt
64 | ~/.ivy2/cache
65 | ~/.coursier/cache/v1
66 | ~/.cache/coursier/v1
67 | ~/AppData/Local/Coursier/Cache/v1
68 | ~/Library/Caches/Coursier/v1
69 | key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
70 |
71 | - if: matrix.scala == '2.13.8'
72 | uses: ruby/setup-ruby@v1
73 | with:
74 | ruby-version: 2.7
75 |
76 | - if: matrix.scala == '2.13.8'
77 | run: gem install bundler
78 |
79 | - if: matrix.scala == '2.13.8'
80 | run: bundle install --gemfile=docs/Gemfile
81 |
82 | - name: Check that workflows are up to date
83 | run: sbt ++${{ matrix.scala }} githubWorkflowCheck
84 |
85 | - name: Check formatting
86 | run: sbt ++${{ matrix.scala }} fmtCheck
87 |
88 | - name: Check binary issues
89 | run: sbt ++${{ matrix.scala }} mimaReportBinaryIssues
90 |
91 | - name: Compile
92 | run: sbt ++${{ matrix.scala }} Test/compile
93 |
94 | - name: Run tests
95 | run: sbt ++${{ matrix.scala }} test
96 |
97 | - name: Build the microsite
98 | if: matrix.scala == '2.13.8'
99 | run: sbt ++${{ matrix.scala }} docs/makeMicrosite
100 |
101 | - name: Compress target directories
102 | run: tar cf targets.tar target core/.js/target core/.jvm/target project/target
103 |
104 | - name: Upload target directories
105 | uses: actions/upload-artifact@v2
106 | with:
107 | name: target-${{ matrix.os }}-${{ matrix.scala }}-${{ matrix.java }}
108 | path: targets.tar
109 |
110 | publish:
111 | name: Publish Artifacts
112 | needs: [build]
113 | if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v'))
114 | strategy:
115 | matrix:
116 | os: [ubuntu-latest]
117 | scala: [2.13.8]
118 | java: [temurin@8]
119 | runs-on: ${{ matrix.os }}
120 | steps:
121 | - name: Checkout current branch (full)
122 | uses: actions/checkout@v2
123 | with:
124 | fetch-depth: 0
125 |
126 | - name: Setup Java (temurin@8)
127 | if: matrix.java == 'temurin@8'
128 | uses: actions/setup-java@v2
129 | with:
130 | distribution: temurin
131 | java-version: 8
132 |
133 | - name: Setup Java (temurin@11)
134 | if: matrix.java == 'temurin@11'
135 | uses: actions/setup-java@v2
136 | with:
137 | distribution: temurin
138 | java-version: 11
139 |
140 | - name: Setup Java (temurin@17)
141 | if: matrix.java == 'temurin@17'
142 | uses: actions/setup-java@v2
143 | with:
144 | distribution: temurin
145 | java-version: 17
146 |
147 | - name: Cache sbt
148 | uses: actions/cache@v2
149 | with:
150 | path: |
151 | ~/.sbt
152 | ~/.ivy2/cache
153 | ~/.coursier/cache/v1
154 | ~/.cache/coursier/v1
155 | ~/AppData/Local/Coursier/Cache/v1
156 | ~/Library/Caches/Coursier/v1
157 | key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
158 |
159 | - name: Download target directories (2.12.15)
160 | uses: actions/download-artifact@v2
161 | with:
162 | name: target-${{ matrix.os }}-2.12.15-${{ matrix.java }}
163 |
164 | - name: Inflate target directories (2.12.15)
165 | run: |
166 | tar xf targets.tar
167 | rm targets.tar
168 |
169 | - name: Download target directories (2.13.8)
170 | uses: actions/download-artifact@v2
171 | with:
172 | name: target-${{ matrix.os }}-2.13.8-${{ matrix.java }}
173 |
174 | - name: Inflate target directories (2.13.8)
175 | run: |
176 | tar xf targets.tar
177 | rm targets.tar
178 |
179 | - name: Download target directories (3.0.2)
180 | uses: actions/download-artifact@v2
181 | with:
182 | name: target-${{ matrix.os }}-3.0.2-${{ matrix.java }}
183 |
184 | - name: Inflate target directories (3.0.2)
185 | run: |
186 | tar xf targets.tar
187 | rm targets.tar
188 |
189 | - name: Import signing key
190 | run: echo $PGP_SECRET | base64 -d | gpg --import
191 |
192 | - name: Release
193 | run: sbt ++${{ matrix.scala }} release
194 |
195 | - name: Publish the microsite
196 | run: sbt ++${{ matrix.scala }} docs/publishMicrosite
197 |
--------------------------------------------------------------------------------
/.github/workflows/clean.yml:
--------------------------------------------------------------------------------
1 | # This file was automatically generated by sbt-github-actions using the
2 | # githubWorkflowGenerate task. You should add and commit this file to
3 | # your git repository. It goes without saying that you shouldn't edit
4 | # this file by hand! Instead, if you wish to make changes, you should
5 | # change your sbt build configuration to revise the workflow description
6 | # to meet your needs, then regenerate this file.
7 |
8 | name: Clean
9 |
10 | on: push
11 |
12 | jobs:
13 | delete-artifacts:
14 | name: Delete Artifacts
15 | runs-on: ubuntu-latest
16 | env:
17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 | steps:
19 | - name: Delete artifacts
20 | run: |
21 | # Customize those three lines with your repository and credentials:
22 | REPO=${GITHUB_API_URL}/repos/${{ github.repository }}
23 |
24 | # A shortcut to call GitHub API.
25 | ghapi() { curl --silent --location --user _:$GITHUB_TOKEN "$@"; }
26 |
27 | # A temporary file which receives HTTP response headers.
28 | TMPFILE=/tmp/tmp.$$
29 |
30 | # An associative array, key: artifact name, value: number of artifacts of that name.
31 | declare -A ARTCOUNT
32 |
33 | # Process all artifacts on this repository, loop on returned "pages".
34 | URL=$REPO/actions/artifacts
35 | while [[ -n "$URL" ]]; do
36 |
37 | # Get current page, get response headers in a temporary file.
38 | JSON=$(ghapi --dump-header $TMPFILE "$URL")
39 |
40 | # Get URL of next page. Will be empty if we are at the last page.
41 | URL=$(grep '^Link:' "$TMPFILE" | tr ',' '\n' | grep 'rel="next"' | head -1 | sed -e 's/.*/' -e 's/>.*//')
42 | rm -f $TMPFILE
43 |
44 | # Number of artifacts on this page:
45 | COUNT=$(( $(jq <<<$JSON -r '.artifacts | length') ))
46 |
47 | # Loop on all artifacts on this page.
48 | for ((i=0; $i < $COUNT; i++)); do
49 |
50 | # Get name of artifact and count instances of this name.
51 | name=$(jq <<<$JSON -r ".artifacts[$i].name?")
52 | ARTCOUNT[$name]=$(( $(( ${ARTCOUNT[$name]} )) + 1))
53 |
54 | id=$(jq <<<$JSON -r ".artifacts[$i].id?")
55 | size=$(( $(jq <<<$JSON -r ".artifacts[$i].size_in_bytes?") ))
56 | printf "Deleting '%s' #%d, %'d bytes\n" $name ${ARTCOUNT[$name]} $size
57 | ghapi -X DELETE $REPO/actions/artifacts/$id
58 | done
59 | done
60 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | .idea/
3 | # vim
4 | *.sw?
5 |
6 | # Ignore [ce]tags filestags
7 |
8 | .bsp
9 | .bloop
10 | .metals
11 |
--------------------------------------------------------------------------------
/.mergify.yml:
--------------------------------------------------------------------------------
1 | pull_request_rules:
2 | - name: automatically merge scala-steward's PRs
3 | conditions:
4 | - author=scala-steward
5 | - status-success=Travis CI - Pull Request
6 | - body~=labels:.*semver-patch.*
7 | actions:
8 | merge:
9 | method: merge
10 |
--------------------------------------------------------------------------------
/.scala-steward.conf:
--------------------------------------------------------------------------------
1 | updates.pin = [
2 | { groupId = "org.typelevel", artifactId="cats-effect", version = "2." },
3 | { groupId = "org.scala-lang", artifactId = "scala3-library", version = "3.0." },
4 | { groupId = "org.scala-lang", artifactId = "scala3-library_sjs1", version = "3.0." }
5 | ]
6 |
--------------------------------------------------------------------------------
/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = 3.5.3
2 | align.openParenCallSite = true
3 | align.openParenDefnSite = true
4 | maxColumn = 120
5 | continuationIndent.defnSite = 2
6 | assumeStandardLibraryStripMargin = true
7 | danglingParentheses.preset = true
8 | rewrite.rules = [AvoidInfix, SortImports, RedundantParens, SortModifiers]
9 | newlines.afterCurlyLambda = preserve
10 | docstrings.style = Asterisk
11 | docstrings.oneline = unfold
12 | runner.dialect = scala213source3
13 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # changelog
2 |
3 | This file summarizes **notable** changes for each release, but does not describe internal changes unless they are particularly exciting. This change log is ordered chronologically, so each release contains all changes described below it.
4 |
5 | ----
6 |
7 | ## New and Noteworthy for Version 2.1.1
8 |
9 | - cats-2.4.2
10 | - cats-effect-2.3.3
11 | - Dropped Scala-3.0.0-M2
12 | - Added Scala 3.0.0-RC1
13 |
14 | ## New and Noteworthy for Version 2.1.0-M7
15 |
16 | - Published under `org.typelevel`
17 | - Base package moved to `org.typelevel.unique`
18 | - cats-2.3.1
19 | - cats-effect-2.3.1
20 | - Cross-built for Scala 3.0.0-M3, 3.0.0-M2, 2.13, and 2.12
21 |
22 | ## New and Noteworthy for Version 2.0.0
23 |
24 | - cats 2.0.0
25 | - cats-effect 2.0.0
26 |
27 | ## New and Noteworthy for Version 2.0.0-RC1
28 |
29 | - Update Off Scala 2.13
30 | - Cats 2.0-RC1
31 | - Cats-Effect 2.0-RC1
32 | - Got off Catsuite
33 | - Drop 2.11 Support
34 |
35 | ## New and Noteworthy for Version 1.0.0
36 |
37 | Stable Release of `unique`. This library will maintain binary compatibility moving forward for the forseeable future.
38 |
39 | - [#18](https://github.com/ChristopherDavenport/unique/pull/18) Scala 2.13 Integration
40 |
41 | Upgrades:
42 |
43 | - cats 1.6.0
44 | - cats-effect 1.2.0
45 |
46 | ## New and Noteworthy for Version 0.1.1
47 |
48 | Incorporate Useability Improvements
49 |
50 | - [#3](https://github.com/ChristopherDavenport/unique/pull/3) Better `toString` for readability, and extends `Serializable`.
51 | - [#2](https://github.com/ChristopherDavenport/unique/pull/2) Add MiMa for binary compatiblity checking.
52 |
53 | ## New and Noteworthy for Version 0.1.0
54 |
55 | Initial Release of `unique`. Create unique values that are equal only to the same effectfully created value. Scala.js project released as well. Fully law checked. [cats-effect](https://github.com/typelevel/cats-effect) is the only dependency and this version is based off 1.0.0.
56 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2018 Christopher Davenport
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # unique [](https://maven-badges.herokuapp.com/maven-central/org.typelevel/unique_2.12) 
2 |
3 | This is a shared library for creating and managing unique values in a referentially transparent way.
4 |
5 | ## End-of-life
6 |
7 | This project is now end-of-life. Its functionality has been [adopted into Cats-Effect 3](https://typelevel.github.io/unique). We will consider releases for [security](https://github.com/typelevel/unique/security/policy) or other significant tales of woe, but routine maintenance has ceased.
8 |
9 | ## [Head on over to the microsite](https://typelevel.github.io/unique)
10 |
11 | ## Quick Start
12 |
13 | To use Unique in an existing SBT project with Scala 2.12 or a later version, add the following dependencies to your
14 | `build.sbt` depending on your needs:
15 |
16 | ```scala
17 | libraryDependencies ++= Seq(
18 | "org.typelevel" %% "unique" % ""
19 | )
20 | ```
21 |
--------------------------------------------------------------------------------
/build.sbt:
--------------------------------------------------------------------------------
1 | import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}
2 |
3 | val Scala212 = "2.12.15"
4 | val Scala213 = "2.13.8"
5 | val Scala3 = "3.0.2"
6 |
7 | ThisBuild / organization := "org.typelevel"
8 | ThisBuild / baseVersion := "2.2"
9 | ThisBuild / crossScalaVersions := Seq(Scala212, Scala213, Scala3)
10 | ThisBuild / scalaVersion := crossScalaVersions.value.filter(_.startsWith("2.")).last
11 |
12 | ThisBuild / publishGithubUser := "christopherdavenport"
13 | ThisBuild / publishFullName := "Christopher Davenport"
14 |
15 | ThisBuild / spiewakMainBranches := Seq("main", "series/2.x")
16 |
17 | ThisBuild / sonatypeCredentialHost := "s01.oss.sonatype.org"
18 |
19 | enablePlugins(SonatypeCiReleasePlugin)
20 |
21 | lazy val unique = project
22 | .in(file("."))
23 | .enablePlugins(NoPublishPlugin)
24 | .aggregate(coreJVM, coreJS)
25 | .settings(commonSettings, releaseSettings, publish / skip := true)
26 |
27 | lazy val core = crossProject(JSPlatform, JVMPlatform)
28 | .crossType(CrossType.Pure)
29 | .in(file("core"))
30 | .settings(commonSettings, releaseSettings)
31 | .settings(
32 | name := "unique"
33 | )
34 | .jsSettings(scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule)))
35 |
36 | lazy val docs = project
37 | .in(file("docs"))
38 | .disablePlugins(MimaPlugin, NoPublishPlugin)
39 | .enablePlugins(MicrositesPlugin)
40 | .settings(
41 | commonSettings,
42 | releaseSettings,
43 | micrositeSettings,
44 | publish / skip := true,
45 | githubWorkflowArtifactUpload := false
46 | )
47 | .dependsOn(coreJVM)
48 |
49 | lazy val coreJVM = core.jvm
50 | lazy val coreJS = core.js
51 |
52 | val catsV = "2.7.0"
53 | val catsEffectV = "2.5.4"
54 | val disciplineMunitV = "1.0.9"
55 | val munitCatsEffectV = "1.0.7"
56 | val kindProjectorV = "0.13.2"
57 |
58 | lazy val contributors = Seq(
59 | "ChristopherDavenport" -> "Christopher Davenport"
60 | )
61 |
62 | // General Settings
63 | lazy val commonSettings = Seq(
64 | libraryDependencies ++= (
65 | if (ScalaArtifacts.isScala3(scalaVersion.value)) Nil
66 | else
67 | Seq(
68 | compilerPlugin(("org.typelevel" % "kind-projector" % kindProjectorV).cross(CrossVersion.full))
69 | )
70 | ),
71 | libraryDependencies ++= Seq(
72 | "org.typelevel" %%% "cats-core" % catsV,
73 | "org.typelevel" %%% "cats-effect" % catsEffectV,
74 | "org.typelevel" %%% "discipline-munit" % disciplineMunitV % Test,
75 | "org.typelevel" %%% "munit-cats-effect-2" % munitCatsEffectV % Test,
76 | "org.typelevel" %%% "cats-laws" % catsV % Test
77 | ),
78 | testFrameworks += new TestFramework("munit.Framework")
79 | )
80 |
81 | lazy val releaseSettings = {
82 | Seq(
83 | scmInfo := Some(
84 | ScmInfo(
85 | url("https://github.com/typelevel/unique"),
86 | "git@github.com:typelevel/unique.git"
87 | )
88 | ),
89 | homepage := Some(url("https://github.com/typelevel/unique")),
90 | licenses := List("MIT" -> url("http://opensource.org/licenses/MIT")),
91 | pomIncludeRepository := { _ => false }
92 | )
93 | }
94 |
95 | lazy val micrositeSettings = {
96 | import microsites._
97 | Seq(
98 | micrositeName := "unique",
99 | micrositeDescription := "Functional Unique Values for Scala",
100 | micrositeAuthor := "Typelevel",
101 | micrositeGithubOwner := "typelevel",
102 | micrositeGithubRepo := "unique",
103 | micrositeBaseUrl := "/unique",
104 | micrositeDocumentationUrl := "https://www.javadoc.io/doc/org.typelevel/unique_2.13",
105 | micrositeFooterText := None,
106 | micrositeHighlightTheme := "atom-one-light",
107 | micrositePalette := Map(
108 | "brand-primary" -> "#3e5b95",
109 | "brand-secondary" -> "#294066",
110 | "brand-tertiary" -> "#2d5799",
111 | "gray-dark" -> "#49494B",
112 | "gray" -> "#7B7B7E",
113 | "gray-light" -> "#E5E5E6",
114 | "gray-lighter" -> "#F4F3F4",
115 | "white-color" -> "#FFFFFF"
116 | ),
117 | libraryDependencies += "com.47deg" %% "github4s" % "0.27.1",
118 | micrositePushSiteWith := GitHub4s,
119 | micrositeGithubToken := sys.env.get("GITHUB_TOKEN"),
120 | micrositeExtraMdFiles := Map(
121 | file("CHANGELOG.md") -> ExtraMdFileConfig("changelog.md",
122 | "page",
123 | Map("title" -> "changelog",
124 | "section" -> "changelog",
125 | "position" -> "100"
126 | )
127 | ),
128 | file("CODE_OF_CONDUCT.md") -> ExtraMdFileConfig("code-of-conduct.md",
129 | "page",
130 | Map("title" -> "code of conduct",
131 | "section" -> "code of conduct",
132 | "position" -> "101"
133 | )
134 | ),
135 | file("LICENSE") -> ExtraMdFileConfig("license.md",
136 | "page",
137 | Map("title" -> "license", "section" -> "license", "position" -> "102")
138 | )
139 | ),
140 | mdocIn := (Compile / sourceDirectory).value / "mdoc"
141 | )
142 | }
143 |
144 | val isScala213Cond = s"matrix.scala == '$Scala213'"
145 |
146 | ThisBuild / githubWorkflowBuildPreamble ++= Seq(
147 | WorkflowStep.Use(UseRef.Public("ruby", "setup-ruby", "v1"),
148 | params = Map("ruby-version" -> "2.7"),
149 | cond = Some(isScala213Cond)
150 | ),
151 | WorkflowStep.Run(List("gem install bundler"), cond = Some(isScala213Cond)),
152 | WorkflowStep.Run(List("bundle install --gemfile=docs/Gemfile"), cond = Some(isScala213Cond))
153 | )
154 |
155 | ThisBuild / githubWorkflowTargetBranches := List("*", "series/*")
156 |
157 | val JDK8 = JavaSpec.temurin("8")
158 | val JDK11 = JavaSpec.temurin("11")
159 | val JDK17 = JavaSpec.temurin("17")
160 |
161 | ThisBuild / githubWorkflowJavaVersions := Seq(JDK8, JDK11, JDK17)
162 | ThisBuild / githubWorkflowBuild := Seq(
163 | WorkflowStep
164 | .Sbt(
165 | List("fmtCheck"),
166 | name = Some("Check formatting")
167 | ),
168 | WorkflowStep.Sbt(List("mimaReportBinaryIssues"), name = Some("Check binary issues")),
169 | WorkflowStep.Sbt(List("Test/compile"), name = Some("Compile")),
170 | WorkflowStep.Sbt(List("test"), name = Some("Run tests")),
171 | WorkflowStep.Sbt(List("docs/makeMicrosite"), name = Some("Build the microsite"), cond = Some(isScala213Cond))
172 | )
173 |
174 | ThisBuild / githubWorkflowPublish := Seq(
175 | WorkflowStep.Sbt(List("release"), name = Some("Release")),
176 | WorkflowStep.Sbt(List("docs/publishMicrosite"), name = Some(s"Publish the microsite"))
177 | )
178 |
179 | ThisBuild / versionIntroduced := Map(
180 | "2.12" -> "2.1.1",
181 | "2.13" -> "2.1.1",
182 | "3.0.0-M3" -> "2.1.1",
183 | "3.0.0-RC1" -> "2.1.1",
184 | "3.0.0-RC2" -> "2.1.3",
185 | "3.0.0-RC3" -> "2.1.4"
186 | )
187 |
188 | // Scalafmt
189 | addCommandAlias("fmt", "; Compile / scalafmt; Test / scalafmt; scalafmtSbt")
190 | addCommandAlias("fmtCheck", "; Compile / scalafmtCheck; Test / scalafmtCheck; scalafmtSbtCheck")
191 |
--------------------------------------------------------------------------------
/core/src/main/scala/org/typelevel/unique/Unique.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Christopher Davenport
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of
5 | * this software and associated documentation files (the "Software"), to deal in
6 | * the Software without restriction, including without limitation the rights to
7 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 | * the Software, and to permit persons to whom the Software is furnished to do so,
9 | * subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 |
22 | package org.typelevel.unique
23 |
24 | import cats.Hash
25 | import cats.effect.Sync
26 |
27 | final class Unique private extends Serializable {
28 | override def toString: String = s"Unique(${hashCode.toHexString})"
29 | }
30 | object Unique {
31 | def newUnique[F[_]: Sync]: F[Unique] = Sync[F].delay(new Unique)
32 |
33 | implicit val uniqueInstances: Hash[Unique] =
34 | Hash.fromUniversalHashCode[Unique]
35 | }
36 |
--------------------------------------------------------------------------------
/core/src/test/scala/org/typelevel/unique/CompileTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Christopher Davenport
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of
5 | * this software and associated documentation files (the "Software"), to deal in
6 | * the Software without restriction, including without limitation the rights to
7 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 | * the Software, and to permit persons to whom the Software is furnished to do so,
9 | * subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 |
22 | package org.typelevel.unique
23 |
24 | import cats.implicits._
25 |
26 | object CompileTest {
27 |
28 | def compare(a: Unique, b: Unique): Boolean = a === b
29 | }
30 |
--------------------------------------------------------------------------------
/core/src/test/scala/org/typelevel/unique/UniqueSuite.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Christopher Davenport
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of
5 | * this software and associated documentation files (the "Software"), to deal in
6 | * the Software without restriction, including without limitation the rights to
7 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 | * the Software, and to permit persons to whom the Software is furnished to do so,
9 | * subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 |
22 | package org.typelevel.unique
23 |
24 | import cats._
25 | import cats.effect._
26 | import munit.CatsEffectSuite
27 |
28 | class UniqueSuite extends CatsEffectSuite {
29 |
30 | test("Equality - be equal when comparing the same value") {
31 | for {
32 | unique <- Unique.newUnique[IO]
33 | } yield assert(Eq[Unique].eqv(unique, unique))
34 | }
35 |
36 | test("Non-Equality - Not be equal when comparing different values") {
37 | for {
38 | unique1 <- Unique.newUnique[IO]
39 | unique2 <- Unique.newUnique[IO]
40 | } yield assert(Eq[Unique].neqv(unique1, unique2))
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/core/src/test/scala/org/typelevel/unique/UniqueTests.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Christopher Davenport
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of
5 | * this software and associated documentation files (the "Software"), to deal in
6 | * the Software without restriction, including without limitation the rights to
7 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 | * the Software, and to permit persons to whom the Software is furnished to do so,
9 | * subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 |
22 | package org.typelevel.unique
23 |
24 | import org.scalacheck._
25 | import cats.effect.SyncIO
26 | import cats.kernel.laws.discipline.{EqTests, HashTests}
27 | import munit.DisciplineSuite
28 |
29 | class UniqueTests extends DisciplineSuite {
30 |
31 | implicit def functionArbitrary[B, A: Arbitrary]: Arbitrary[B => A] = Arbitrary {
32 | for {
33 | a <- Arbitrary.arbitrary[A]
34 | } yield { (_: B) => a }
35 | }
36 |
37 | implicit val uniqueArb: Arbitrary[Unique] = Arbitrary {
38 | Arbitrary.arbitrary[Unit].map(_ => Unique.newUnique[SyncIO].unsafeRunSync())
39 | }
40 |
41 | checkAll("Unique", HashTests[Unique].hash)
42 | checkAll("Unique", EqTests[Unique].eqv)
43 | }
44 |
--------------------------------------------------------------------------------
/docs/Gemfile:
--------------------------------------------------------------------------------
1 | source 'http://rubygems.org'
2 |
3 | gem "jekyll", ">= 3.2.1", "< 4.0.0"
4 | gem "jekyll-relative-links"
5 | gem "sass"
6 |
--------------------------------------------------------------------------------
/docs/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://rubygems.org/
3 | specs:
4 | addressable (2.8.0)
5 | public_suffix (>= 2.0.2, < 5.0)
6 | colorator (1.1.0)
7 | concurrent-ruby (1.1.5)
8 | em-websocket (0.5.1)
9 | eventmachine (>= 0.12.9)
10 | http_parser.rb (~> 0.6.0)
11 | eventmachine (1.2.7)
12 | ffi (1.11.3)
13 | forwardable-extended (2.6.0)
14 | http_parser.rb (0.6.0)
15 | i18n (0.9.5)
16 | concurrent-ruby (~> 1.0)
17 | jekyll (3.8.6)
18 | addressable (~> 2.4)
19 | colorator (~> 1.0)
20 | em-websocket (~> 0.5)
21 | i18n (~> 0.7)
22 | jekyll-sass-converter (~> 1.0)
23 | jekyll-watch (~> 2.0)
24 | kramdown (~> 1.14)
25 | liquid (~> 4.0)
26 | mercenary (~> 0.3.3)
27 | pathutil (~> 0.9)
28 | rouge (>= 1.7, < 4)
29 | safe_yaml (~> 1.0)
30 | jekyll-relative-links (0.6.1)
31 | jekyll (>= 3.3, < 5.0)
32 | jekyll-sass-converter (1.5.2)
33 | sass (~> 3.4)
34 | jekyll-watch (2.2.1)
35 | listen (~> 3.0)
36 | kramdown (1.17.0)
37 | liquid (4.0.3)
38 | listen (3.2.1)
39 | rb-fsevent (~> 0.10, >= 0.10.3)
40 | rb-inotify (~> 0.9, >= 0.9.10)
41 | mercenary (0.3.6)
42 | pathutil (0.16.2)
43 | forwardable-extended (~> 2.6)
44 | public_suffix (4.0.6)
45 | rb-fsevent (0.10.3)
46 | rb-inotify (0.10.0)
47 | ffi (~> 1.0)
48 | rouge (3.14.0)
49 | safe_yaml (1.0.5)
50 | sass (3.7.4)
51 | sass-listen (~> 4.0.0)
52 | sass-listen (4.0.0)
53 | rb-fsevent (~> 0.9, >= 0.9.4)
54 | rb-inotify (~> 0.9, >= 0.9.7)
55 |
56 | PLATFORMS
57 | ruby
58 |
59 | DEPENDENCIES
60 | jekyll (>= 3.2.1, < 4.0.0)
61 | jekyll-relative-links
62 | sass
63 |
64 | BUNDLED WITH
65 | 2.2.11
66 |
--------------------------------------------------------------------------------
/docs/src/main/mdoc/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 |
4 | ---
5 | # unique [](https://maven-badges.herokuapp.com/maven-central/org.typelevel/unique_2.12)
6 |
7 | This is a shared library for creating and managing unique values in a referentially transparent way.
8 |
9 | ## Maintenance status
10 |
11 | This project is now end-of-life. Its functionality has been [adopted into Cats-Effect 3](https://typelevel.github.io/unique). We will consider releases for [security](https://github.com/typelevel/unique/security/policy) or other significant tales of woe, but routine maintenance has ceased.
12 |
13 | ## Synopsis
14 |
15 | Creation of a unique value must always happen within an effect.
16 |
17 | Let's start with some imports.
18 |
19 | ```scala mdoc:silent
20 | import org.typelevel.unique.Unique
21 | import cats.implicits._
22 | import cats.effect._
23 | ```
24 |
25 | Then we can display that only values created by the same effect are equal.
26 |
27 | ```scala mdoc
28 | // Equal
29 | {
30 | for {
31 | unique <- Unique.newUnique[IO]
32 | } yield unique === unique
33 | }.unsafeRunSync()
34 |
35 | // Not equal
36 | {
37 | for {
38 | unique1 <- Unique.newUnique[IO]
39 | unique2 <- Unique.newUnique[IO]
40 | } yield unique1 === unique2
41 | }.unsafeRunSync()
42 |
43 |
44 | ```
45 |
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.6.2
2 |
3 |
4 |
--------------------------------------------------------------------------------
/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("com.47deg" % "sbt-microsites" % "1.3.4")
2 | addSbtPlugin("com.codecommit" % "sbt-spiewak-sonatype" % "0.23.0")
3 | addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
4 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.0")
5 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
6 |
--------------------------------------------------------------------------------