Skip to content

Commit

Permalink
Merge pull request #152 from jCabala/main
Browse files Browse the repository at this point in the history
Add consistent naming of writers
  • Loading branch information
noelwelsh authored Mar 18, 2024
2 parents 2e5a290 + bf40565 commit 643f034
Show file tree
Hide file tree
Showing 23 changed files with 215 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import doodle.algebra.Algebra
import doodle.algebra.Picture
import java.awt.image.BufferedImage

trait BufferedImageConverter[+Alg <: Algebra, Frame] {
/** The BufferedImageWriter type represent the ability to encode an image as a
* java BufferedImage class.
*/
trait BufferedImageWriter[+Alg <: Algebra, Frame] extends Writer[Alg, Frame] {
def bufferedImage[A](
description: Frame,
picture: Picture[Alg, A]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,36 @@ import doodle.algebra.Algebra
import doodle.algebra.Picture
import doodle.core.format.Format
import doodle.core.{Base64 => B64}
import doodle.effect.Base64
import doodle.effect.Base64Writer

trait Base64Syntax {
trait Base64WriterSyntax {
implicit class Base64Ops[Alg <: Algebra, A](
picture: Picture[Alg, A]
) {
// This class exists solely so the user doesn't have to provide the `Frame`
// type parameter when calling syntax methods.
class Base64OpsHelper[Fmt <: Format](picture: Picture[Alg, A]) {
def apply[Frame]()(implicit
w: Base64[Alg, Frame, Fmt],
w: Base64Writer[Alg, Frame, Fmt],
r: IORuntime
): (A, B64[Fmt]) =
w.base64(picture).unsafeRunSync()

def apply[Frame](frame: Frame)(implicit
w: Base64[Alg, Frame, Fmt],
w: Base64Writer[Alg, Frame, Fmt],
r: IORuntime
): (A, B64[Fmt]) =
w.base64(frame, picture).unsafeRunSync()
}

class Base64IOOpsHelper[Fmt <: Format](picture: Picture[Alg, A]) {
def apply[Frame]()(implicit
w: Base64[Alg, Frame, Fmt]
w: Base64Writer[Alg, Frame, Fmt]
): IO[(A, B64[Fmt])] =
w.base64(picture)

def apply[Frame](frame: Frame)(implicit
w: Base64[Alg, Frame, Fmt]
w: Base64Writer[Alg, Frame, Fmt]
): IO[(A, B64[Fmt])] =
w.base64(frame, picture)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ import cats.effect.IO
import cats.effect.unsafe.IORuntime
import doodle.algebra.Algebra
import doodle.algebra.Picture
import doodle.effect.BufferedImageConverter
import doodle.effect.BufferedImageWriter
import java.awt.image.BufferedImage

trait BufferedImageConverterSyntax {
implicit class BufferedImageConverterOps[Alg <: Algebra, A](
trait BufferedImageWriterSyntax {
implicit class BufferedImageWriterOps[Alg <: Algebra, A](
picture: Picture[Alg, A]
) {
def bufferedImage[Frame](frame: Frame)(implicit
w: BufferedImageConverter[Alg, Frame],
w: BufferedImageWriter[Alg, Frame],
r: IORuntime
): (A, BufferedImage) =
w.bufferedImage(frame, picture).unsafeRunSync()

def bufferedImageToIO[Frame](frame: Frame)(implicit
w: BufferedImageConverter[Alg, Frame]
w: BufferedImageWriter[Alg, Frame]
): IO[(A, BufferedImage)] =
w.bufferedImage(frame, picture)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,68 +22,68 @@ import cats.effect.unsafe.IORuntime
import doodle.algebra.Algebra
import doodle.algebra.Picture
import doodle.core.format.Format
import doodle.effect.Writer
import doodle.effect.FileWriter

import java.io.File

trait WriterSyntax {
trait FileWriterSyntax {
implicit class WriterOps[Alg <: Algebra, A](
picture: Picture[Alg, A]
) {
// This class exists solely so the user doesn't have to provide the `Frame`
// type parameter when calling syntax methods.
class WriterOpsHelper[Fmt <: Format](picture: Picture[Alg, A]) {
class FileWriterOpsHelper[Fmt <: Format](picture: Picture[Alg, A]) {
def apply[Frame](file: String)(implicit
w: Writer[Alg, Frame, Fmt],
w: FileWriter[Alg, Frame, Fmt],
r: IORuntime
): A =
apply(new File(file))

def apply[Frame](file: File)(implicit
w: Writer[Alg, Frame, Fmt],
w: FileWriter[Alg, Frame, Fmt],
r: IORuntime
): A =
w.write(file, picture).unsafeRunSync()

def apply[Frame](file: String, frame: Frame)(implicit
w: Writer[Alg, Frame, Fmt],
w: FileWriter[Alg, Frame, Fmt],
r: IORuntime
): A =
apply(new File(file), frame)

def apply[Frame](file: File, frame: Frame)(implicit
w: Writer[Alg, Frame, Fmt],
w: FileWriter[Alg, Frame, Fmt],
r: IORuntime
): A =
w.write(file, frame, picture).unsafeRunSync()
}

class WriterIOOpsHelper[Fmt <: Format](picture: Picture[Alg, A]) {
class FileWriterIOOpsHelper[Fmt <: Format](picture: Picture[Alg, A]) {
def apply[Frame](file: String)(implicit
w: Writer[Alg, Frame, Fmt]
w: FileWriter[Alg, Frame, Fmt]
): IO[A] =
apply(new File(file))

def apply[Frame](file: File)(implicit
w: Writer[Alg, Frame, Fmt]
w: FileWriter[Alg, Frame, Fmt]
): IO[A] =
w.write(file, picture)

def apply[Frame](file: String, frame: Frame)(implicit
w: Writer[Alg, Frame, Fmt]
w: FileWriter[Alg, Frame, Fmt]
): IO[A] =
apply(new File(file), frame)

def apply[Frame](file: File, frame: Frame)(implicit
w: Writer[Alg, Frame, Fmt]
w: FileWriter[Alg, Frame, Fmt]
): IO[A] =
w.write(file, frame, picture)
}

def write[Fmt <: Format] =
new WriterOpsHelper[Fmt](picture)
new FileWriterOpsHelper[Fmt](picture)

def writeToIO[Fmt <: Format] =
new WriterIOOpsHelper[Fmt](picture)
new FileWriterIOOpsHelper[Fmt](picture)
}
}
12 changes: 6 additions & 6 deletions core/jvm/src/main/scala/doodle/syntax/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ package doodle
package object syntax {
object all
extends AngleSyntax
with Base64Syntax
with Base64WriterSyntax
with BitmapSyntax
with BlendSyntax
with BufferedImageConverterSyntax
with BufferedImageWriterSyntax
with DebugSyntax
with LayoutSyntax
with NormalizedSyntax
Expand All @@ -36,12 +36,12 @@ package object syntax {
with TransformSyntax
with TraverseSyntax
with UnsignedByteSyntax
with WriterSyntax
with FileWriterSyntax
object angle extends AngleSyntax
object base64 extends Base64Syntax
object base64Writer extends Base64WriterSyntax
object bitmap extends BitmapSyntax
object blend extends BlendSyntax
object bufferedImageConverter extends BufferedImageConverterSyntax
object bufferedImageWriter extends BufferedImageWriterSyntax
object debug extends DebugSyntax
object layout extends LayoutSyntax
object normalized extends NormalizedSyntax
Expand All @@ -55,5 +55,5 @@ package object syntax {
object transform extends TransformSyntax
object traverse extends TraverseSyntax
object unsignedByte extends UnsignedByteSyntax
object writer extends WriterSyntax
object fileWriter extends FileWriterSyntax
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import doodle.algebra.Picture
import doodle.core.format.Format
import doodle.core.{Base64 => B64}

/** The Base64 type represent the ability to encode an image as a Base64 String
* in a given format.
/** The Base64Writer type represent the ability to encode an image as a Base64
* String in a given format.
*/
trait Base64[+Alg <: Algebra, Frame, Fmt <: Format] {
trait Base64Writer[+Alg <: Algebra, Frame, Fmt <: Format]
extends Writer[Alg, Frame] {
def base64[A](
description: Frame,
picture: Picture[Alg, A]
Expand Down
34 changes: 34 additions & 0 deletions core/shared/src/main/scala/doodle/effect/FileWriter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2015 Creative Scala
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package doodle
package effect

import cats.effect.IO
import doodle.algebra.Algebra
import doodle.algebra.Picture
import doodle.core.format.Format

import java.io.File

/** The `FileWriter` typeclass represents write a picture to a file in a given
* format.
*/
trait FileWriter[+Alg <: Algebra, Frame, Fmt <: Format]
extends Writer[Alg, Frame] {
def write[A](file: File, description: Frame, image: Picture[Alg, A]): IO[A]
def write[A](file: File, image: Picture[Alg, A]): IO[A]
}
13 changes: 2 additions & 11 deletions core/shared/src/main/scala/doodle/effect/Writer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,8 @@
package doodle
package effect

import cats.effect.IO
import doodle.algebra.Algebra
import doodle.algebra.Picture
import doodle.core.format.Format

import java.io.File

/** The `Writer` typeclass represents write a picture to a file in a given
* format.
/** Marker trait for effects that write a picture to a file or some other type.
*/
trait Writer[+Alg <: Algebra, Frame, Fmt <: Format] {
def write[A](file: File, description: Frame, image: Picture[Alg, A]): IO[A]
def write[A](file: File, image: Picture[Alg, A]): IO[A]
}
trait Writer[+Alg <: Algebra, Frame]
2 changes: 1 addition & 1 deletion docs/src/pages/concepts/effects.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Effects

In Doodle, an effect such as @:api(doodle.effect.Renderer) carries out the instructions in a `Picture`. In the case of `Renderer`, this is drawing the picture on the screen. Saving a `Picture` to a file is another very common effect.
In Doodle, an effect such as @:api(doodle.effect.Renderer) carries out the instructions in a `Picture`. In the case of `Renderer`, this is drawing the picture on the screen. Converting a `Picture` to another type or saving it to a file are another very common effects managed by `Writers`, for example, a `Base64Writer` or a `FileWriter`.

You will mostly interact with effects by convenient syntax. For example, when you call `draw` on a `Picture` you are using an effect via such a convenience.

4 changes: 3 additions & 1 deletion docs/src/pages/effect/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Effects

A picture is a description of what should be drawn. An effect carries out the description by, for example, drawing a picture to the screen or writing it to a file. Effects are defined in the @:api(doodle.effect.index) package. All effects have @:api(doodle.syntax.index) that makes them easier to use. You should not have to use effects directly unless you are extending Doodle.
A picture is a description of what should be drawn. An effect carries out the description by, for example, drawing a picture to the screen. Another example includes converting a picture to a different type or saving it to a file which is managed by a special class of effects called `Writers`.

Effects are defined in the @:api(doodle.effect.index) package. All effects have @:api(doodle.syntax.index) that makes them easier to use. You should not have to use effects directly unless you are extending Doodle.
8 changes: 4 additions & 4 deletions golden/src/test/scala/doodle/golden/GoldenPicture.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import cats.effect.unsafe.implicits.global
import doodle.algebra.Algebra
import doodle.algebra.Picture
import doodle.core.format._
import doodle.effect.Writer
import doodle.effect.FileWriter
import doodle.java2d._
import munit._

Expand All @@ -32,7 +32,7 @@ trait GoldenPicture extends Golden { self: FunSuite =>
name: String,
picture: Picture[Alg, Unit],
frame: Frame = Frame.default.withSizedToPicture()
)(implicit loc: Location, w: Writer[Alg, Frame, Png]) = {
)(implicit loc: Location, w: FileWriter[Alg, Frame, Png]) = {
import java.io.File
val file = new File(s"${goldenDir}/${name}.png")

Expand All @@ -56,7 +56,7 @@ trait GoldenPicture extends Golden { self: FunSuite =>

def testPicture[Alg <: Algebra, A](name: String)(
picture: Picture[Alg, Unit]
)(implicit loc: Location, w: Writer[Alg, Frame, Png]) =
)(implicit loc: Location, w: FileWriter[Alg, Frame, Png]) =
test(name) {
assertGoldenPicture(name, picture)
}
Expand All @@ -65,7 +65,7 @@ trait GoldenPicture extends Golden { self: FunSuite =>
frame: Frame
)(
picture: Picture[Alg, Unit]
)(implicit loc: Location, w: Writer[Alg, Frame, Png]) =
)(implicit loc: Location, w: FileWriter[Alg, Frame, Png]) =
test(name) {
assertGoldenPicture(name, picture, frame)
}
Expand Down
Loading

0 comments on commit 643f034

Please sign in to comment.