diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 1fca28a..92fb98d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,2 +1,5 @@ # Scala Steward: Reformat with scalafmt 3.7.17 7c6966fbfe8e67006302d992d51bef38713be851 + +# Scala Steward: Reformat with scalafmt 3.8.0 +17c83ae6a8cc70e0b0ff8b5cc18975a37166a945 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bf7677..ab0d46a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.12.18, 2.13.12, 3.3.1] + scala: [2.12.19, 2.13.12, 3.3.3] java: [temurin@8, temurin@17] runs-on: ${{ matrix.os }} steps: diff --git a/.scalafmt.conf b/.scalafmt.conf index f4b59b7..1f22f13 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -7,4 +7,4 @@ newlines.topLevelStatementBlankLines = [ ] rewrite.rules = [SortImports, RedundantBraces] runner.dialect = scala213 -version=3.7.17 +version=3.8.2 diff --git a/README.md b/README.md index e842405..e79ab32 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,53 @@ # sealed-monad -## Scala library for nice for-comprehension-style error handling - [![Maven Central](https://img.shields.io/maven-central/v/pl.iterators/sealed-monad_2.13.svg)]() -[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/theiterators/sealed-monad/master/COPYING) -[![Build Status](https://travis-ci.org/theiterators/sealed-monad.svg?branch=master)](https://travis-ci.org/theiterators/sealed-monad) +[![GitHub license](https://img.shields.io/badge/license-Apache2.0-blue.svg)](https://raw.githubusercontent.com/theiterators/sealed-monad/master/COPYING) [![sealed-monad Scala version support](https://index.scala-lang.org/theiterators/sealed-monad/sealed-monad/latest-by-scala-version.svg)](https://index.scala-lang.org/theiterators/sealed-monad/sealed-monad) -![logo](https://raw.githubusercontent.com/theiterators/sealed-monad/master/logo.png) -### Documentation +Scala library for nice business logic oriented, for-comprehension-style error handling. Write logic that even your manager can understand! + +Or in more technical terms, think of EitherT on steroids, with more human-readable method names. + +## Installation + +Add the following to your `build.sbt`: + +```scala +libraryDependencies += "pl.iterators" %% "sealed-monad" % "1.3.0" +``` + +Available for Scala 2.12.x, 2.13.x and 3.x. + +## Usage + +```scala + def createTodo(userId: UUID, organizationId: UUID, request: CreateTodoRequest): IO[CreateTodoResponse] = { + (for { + user <- userRepository + .find(userId) // IO[Option[User]] + .valueOr(CreateTodoResponse.UserNotFound) // extracts User or returns UserNotFound + _ <- organizationRepository + .findFor(userId) // IO[Option[Organization]] + .valueOr(CreateTodoResponse.UserNotInOrganization) // extracts Organization or returns UserNotInOrganization + .ensure(_.canCreateTodos(user), CreateTodoResponse.UserNotAllowedToCreateTodos) // checks if user can create todos or returns UserNotAllowedToCreateTodos + _ <- todoRepository + .find(request.title) // IO[Option[Todo]] + .ensure(_.isEmpty, CreateTodoResponse.TodoAlreadyExists) // checks if todo already exists or returns TodoAlreadyExists + _ <- Todo + .from(request) + .pure[IO] // IO[Todo] + .ensure(_.title.nonEmpty, CreateTodoResponse.TodoTitleEmpty) // checks if todo title is non-empty or returns TodoTitleEmpty + todo <- todoRepository.insert(Todo(UUID.randomUUID(), request.title)).seal // todo created! + } yield CreateTodoResponse.Created(todo)).run // compile to IO[CreateTodoResponse] + } +``` + +## Documentation Please refer to the [docs](https://theiterators.github.io/sealed-monad) site. + +![logo](https://raw.githubusercontent.com/theiterators/sealed-monad/master/logo.png) + +## License + +This project is licensed under the Apache 2.0 License - see the [LICENSE](https://github.com/theiterators/sealed-monad/blob/master/LICENSE) file for details. diff --git a/build.sbt b/build.sbt index eb742a1..1a25ab9 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,7 @@ val isDotty = Def.setting(CrossVersion.partialVersion(scalaVersion.value).exists // Dependencies -val catsVersion = "2.10.0" +val catsVersion = "2.12.0" val castsTestkitScalatestVersion = "2.1.5" libraryDependencies ++= Seq( @@ -18,7 +18,7 @@ libraryDependencies ++= (if (isDotty.value) Nil // Multiple Scala versions support -val scala_2_12 = "2.12.18" +val scala_2_12 = "2.12.19" val scala_2_13 = "2.13.12" val dotty = "3.3.1" val mainScalaVersion = scala_2_13 diff --git a/logo.png b/logo.png index daa7cf9..be854a2 100644 Binary files a/logo.png and b/logo.png differ