Skip to content

Commit b7b257b

Browse files
committed
refined4s v1.9.0
1 parent 03d6f24 commit b7b257b

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

changelogs/1.9.0.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
## [1.9.0](https://github.com/kevin-lee/refined4s/issues?q=is%3Aissue%20is%3Aclosed%20-label%3Ainvalid%20-label%3Awontfix%20milestone%3Am30) - 2025-09-05
2+
3+
### New Features
4+
5+
* [`refined4s-core`] Add `cats.Hash` type class instances for `refined4s.types.strings` with `orphan-cats` (#488)
6+
* [`refined4s-core`] Add `cats.Hash` type class instances for `refined4s.types.network` with `orphan-cats` (#490)
7+
* [`refined4s-core`] Add `cats.Hash` type class instances for `refined4s.types.numeric` with `orphan-cats` (#491)
8+
* [`refined4s-core`] Add `cats.Hash` type class instances for `refined4s.types.time` with `orphan-cats` (#492)
9+
* [`refined4s-circe`] Add `Encoder`, `Decoder`, `KeyEncoder` and `KeyDecoder` type-class instances for `refined4s.types.time` types (#497)
10+
11+
Add `Encoder`, `Decoder`, `KeyEncoder` and `KeyDecoder` instances for
12+
* `Month`
13+
* `Day`
14+
* `Hour`
15+
* `Minute`
16+
* `Second`
17+
* `Millis`
18+
19+
20+
* [`refined4s-extras-render`] Add `Render` type-class instances for `refined4s.types.time` types (#499)
21+
* [`refined4s-chimney`] Add `Transformer` and `PartialTransformer` type-class instances for `refined4s.types.time` types (#500)
22+
* [`refined4s-pureconfig`] Add `ConfigReader` and `ConfigWriter` type-class instances for `refined4s.types.time` types (#501)
23+
* [`refined4s-doobie-ce2`] Add `Get` and `Put` type-class instances for `refined4s.types.time` types (#502)
24+
* [`refined4s-doobie-ce3`] Add `Get` and `Put` type-class instances for `refined4s.types.time` types (#503)
25+
* [`refined4s-tapir`] Add `Schema` type-class instances for `refined4s.types.time` types (#504)
26+
* [`refined4s-cats`] Add `CatsHash` to derive `Hash` from the actual type's `Hash` (#508)
27+
28+
```scala 3
29+
type MyNewtype = MyNewtype.Type
30+
object MyNewtype extends Newtype[String], CatsHash[String]
31+
32+
type MyRefinedType = MyRefinedType.Type
33+
object MyRefinedType extends Refined[String], CatsHash[String] {
34+
override inline def invalidReason(a: String): String =
35+
"It has to be a non-empty String but got \"" + a + "\""
36+
37+
override inline def predicate(a: String): Boolean = a != ""
38+
}
39+
40+
type MyRefinedNewtype = MyRefinedNewtype.Type
41+
object MyRefinedNewtype extends Newtype[MyRefinedType], CatsHash[MyRefinedType]
42+
```
43+
44+
***
45+
46+
### Internal Changes
47+
48+
* Do not use `java.net.URL`'s constructors as they are deprecated since Java 20 (#484)
49+
50+
`new URL()` is used in `Url` validation, but it shouldn't be used because it was deprecated in Java 20.
51+
52+
53+
#### Reorganize type-class instances in the modules (#507)
54+
1. `all` => `strings`, `numeric`, `network` and `time` + `all`
55+
56+
If the type class instances are in the `all` object, split them into multiple objects such as `strings`, `numeric`, `network`, and `time`, as well as an `all` object that contains all of them.
57+
58+
2. Move type-class instances from `trait`s to `object`s
59+
60+
The type-class instances in `trait`s should be moved to `object`s and the `trait`s should have the same ones from the `object`s.
61+
62+
e.g.)
63+
```scala 3
64+
trait strings {
65+
66+
/* NonEmptyString */
67+
inline given derivedNonEmptyStringEncoder: Encoder[NonEmptyString] = Encoder[String].contramap[NonEmptyString](_.value)
68+
inline given derivedNonEmptyStringDecoder: Decoder[NonEmptyString] = Decoder[String].emap(NonEmptyString.from)
69+
}
70+
object strings extends strings
71+
```
72+
to
73+
```scala 3
74+
trait strings {
75+
76+
/* NonEmptyString */
77+
inline given derivedNonEmptyStringEncoder: Encoder[NonEmptyString] = strings.derivedNonEmptyStringEncoder
78+
inline given derivedNonEmptyStringDecoder: Decoder[NonEmptyString] = strings.derivedNonEmptyStringDecoder
79+
80+
}
81+
object strings {
82+
83+
/* NonEmptyString */
84+
given derivedNonEmptyStringEncoder: Encoder[NonEmptyString] = Encoder[String].contramap[NonEmptyString](_.value)
85+
given derivedNonEmptyStringDecoder: Decoder[NonEmptyString] = Decoder[String].emap(NonEmptyString.from)
86+
87+
}
88+
```
89+
90+
91+
##### Why?
92+
With
93+
```scala 3
94+
trait strings {
95+
96+
/* NonEmptyString */
97+
inline given derivedNonEmptyStringEncoder: Encoder[NonEmptyString] = Encoder[String].contramap[NonEmptyString](_.value)
98+
inline given derivedNonEmptyStringDecoder: Decoder[NonEmptyString] = Decoder[String].emap(NonEmptyString.from)
99+
}
100+
object strings extends strings
101+
```
102+
Each object extending the `trait` has new non-equal type-class instances, and it is completely unnecessary.
103+
```scala 3
104+
val strings = new refined4s.modules.circe.derivation.types.strings {}
105+
106+
strings.derivedNonEmptyStringEncoder == refined4s.modules.circe.derivation.types.strings.derivedNonEmptyStringEncoder
107+
// Boolean = false
108+
109+
strings.derivedNonEmptyStringEncoder eq refined4s.modules.circe.derivation.types.strings.derivedNonEmptyStringEncoder
110+
// Boolean = false
111+
```
112+
***
113+
With
114+
```scala 3
115+
trait strings {
116+
117+
/* NonEmptyString */
118+
inline given derivedNonEmptyStringEncoder: Encoder[NonEmptyString] = strings.derivedNonEmptyStringEncoder
119+
inline given derivedNonEmptyStringDecoder: Decoder[NonEmptyString] = strings.derivedNonEmptyStringDecoder
120+
121+
}
122+
object strings {
123+
124+
/* NonEmptyString */
125+
given derivedNonEmptyStringEncoder: Encoder[NonEmptyString] = Encoder[String].contramap[NonEmptyString](_.value)
126+
given derivedNonEmptyStringDecoder: Decoder[NonEmptyString] = Decoder[String].emap(NonEmptyString.from)
127+
128+
}
129+
```
130+
It is
131+
```scala 3
132+
val strings = new refined4s.modules.circe.derivation.types.strings {}
133+
134+
strings.derivedNonEmptyStringEncoder == refined4s.modules.circe.derivation.types.strings.derivedNonEmptyStringEncoder
135+
// Boolean = true
136+
137+
strings.derivedNonEmptyStringEncoder eq refined4s.modules.circe.derivation.types.strings.derivedNonEmptyStringEncoder
138+
// Boolean = true
139+
```
140+
141+
***
142+
143+
### Internal Housekeeping
144+
145+
* [`refined4s-cats`] Add not-equal tests for `Eq` instances for the types in `refined4s.types` (#486)

0 commit comments

Comments
 (0)