Comments (7)
As a saying goes: "Where is a will there's a way"
implicit val limitPeriodTypeCodec: Codec[LimitPeriodType] = deriveAllCodecs
implicit def finalBoss[V: Encoder: Decoder, LT <: LimitPeriodType: ClassTag]: Codec[Limit[V, LT]] = {
import LimitPeriodType._
def aCodec: Codec[Limit[V, Day.type]] =
Codec.bimap[Option[V], Limit[V, Day.type]](f = x => x.asInstanceOf[Daily[V]].value, g = x => Daily(x))
def bCodec: Codec[Limit[V, Week.type]] =
Codec.bimap[Option[V], Limit[V, Week.type]](f = x => x.asInstanceOf[Weekly[V]].value, g = x => Weekly(x))
def cCodec: Codec[Limit[V, Month.type]] =
Codec.bimap[Option[V], Limit[V, Month.type]](f = x => x.asInstanceOf[Monthly[V]].value, g = x => Monthly(x))
val clazz = classTag[LT].runtimeClass
if (clazz == classOf[Day.type]) {
aCodec.asInstanceOf[Codec[Limit[V, LT]]]
} else if (clazz == classOf[Week.type]) {
bCodec.asInstanceOf[Codec[Limit[V, LT]]]
} else if (clazz == classOf[Month.type]) {
cCodec.asInstanceOf[Codec[Limit[V, LT]]]
} else {
throw new RuntimeException
}
}
implicit def limitsCodec[V: Encoder: Decoder]: Codec[Limits[V]] = deriveCodec[Limits[V]]
implicit def effectiveLimitCodec[V: Encoder: Decoder, LT <: LimitPeriodType : ClassTag]: Codec[EffectiveLimit[V, LT]] =
deriveCodec[EffectiveLimit[V, LT]]
Notice the ClassTag that must be pulled throughout the program
from akka-serialization-helper.
implicit val limitPeriodTypeCodec: Codec[LimitPeriodType] = deriveAllCodecs
implicit def aCodec[V: Encoder: Decoder]: Codec[Limit[V, LimitPeriodType.Day.type]] =
Codec.bimap[Option[V], Limit[V, LimitPeriodType.Day.type]](
f = x => x.asInstanceOf[Daily[V]].value,
g = x => Daily(x))
implicit def bCodec[V: Encoder: Decoder]: Codec[Limit[V, LimitPeriodType.Week.type]] =
Codec.bimap[Option[V], Limit[V, LimitPeriodType.Week.type]](
f = x => x.asInstanceOf[Weekly[V]].value,
g = x => Weekly(x))
implicit def cCodec[V: Encoder: Decoder]: Codec[Limit[V, LimitPeriodType.Month.type]] =
Codec.bimap[Option[V], Limit[V, LimitPeriodType.Month.type]](
f = x => x.asInstanceOf[Monthly[V]].value,
g = x => Monthly(x))
implicit def limitsCodec[V: Encoder: Decoder]: Codec[Limits[V]] = deriveCodec[Limits[V]]
val test = Limits[Int](Daily(Some(2)), Weekly(None), Monthly(Some(3)))
val s = Cbor.encode(test).toByteArray
val r = Cbor.decode(s).to[Limits[Int]].value
print(test == r)//true
This is the hack I came up with.
Of course, it's very bad. The notion of runtime safety goes through the window.
from akka-serialization-helper.
Thanks, lemme try applying that in Hydra... even if this hack will stay for good, it's still better than Jackson where there's little runtime safety for any type 😅
from akka-serialization-helper.
I think the problem comes from the fact, that Codec[Limit[V, Day]] can encode/decode a different subset of classes than for example Codec[Limit[V, Month]].
For example when I do something like this:
implicit def aCodec[V: Encoder: Decoder]: Codec[Limit[V, LimitPeriodType.Day.type]] = deriveAllCodecs[Limit[V, LimitPeriodType.Day.type]]
It gives error:
pattern type is incompatible with expected type;
found : org.virtuslab.akkasaferserializer.data.DataGeneric.Limit.Monthly[V]
required: org.virtuslab.akkasaferserializer.data.DataGeneric.Limit[V,org.virtuslab.akkasaferserializer.data.DataGeneric.LimitPeriodType.Day.type]
implicit def aCodec[V: Encoder: Decoder]: Codec[Limit[V, LimitPeriodType.Day.type]] = deriveAllCodecs[Limit[V, LimitPeriodType.Day.type]]
It takes Monthly into codec and therefore fails type check. That's why it would be impossible to create something even more generic like Codec[Limit[V, LT].
from akka-serialization-helper.
Whoops yeah, it seems that's exactly what I've got now... it turned out there's one extra class to consider:
final case class EffectiveLimit[V, +LT <: LimitPeriodType](
limit: Limit[V, LT],
since: OffsetDateTime)
aaand here the workaround you've proposed doesn't work ://
Can you see any other potential solution for EffectiveLimit
-like cases (where LT
type param is NOT fixed to Day
/Week
/Month
)? 🤔
from akka-serialization-helper.
Okay! this compiles now...
from akka-serialization-helper.
Resolved 🎉
from akka-serialization-helper.
Related Issues (20)
- Set sbt keys for all `ashSerializabilityCheckerCompilerPlugin` flags
- Update `AkkaCodecs` usage in `examples/`
- Add support for Scala 3 HOT 1
- Enable security reports from `Dependabot`
- Fix critical Log4J vulnerabilities HOT 1
- Support for `Laguna` - add persistence schema checks to CI
- Support for `Laguna` - tidy up the mess with multiple ASH cache directories
- Updata scala versions to `2.12.17` and `2.13.9`
- In README document jackson ScalaObjectDeserializerModule HOT 2
- Support for native serializable types and/or exclusions HOT 14
- Support for `Laguna` - fix persistence schema check in CI HOT 1
- Question, adding many options HOT 3
- `OverlappingFileLockException` from `SerializerCheckCompilerPluginComponent$$anon$1.interactWithTheCacheFile` HOT 15
- `spray.json.JsonParser$ParsingException: Unexpected end-of-input` at `PersistenceSchemaWriter`
- Untangle file access in codec-registration-checker-compiler-plugin
- Pekko support HOT 2
- Snapshots are published for each Scala minor version
- Snapshots are published as `0.0.0+...` version, regardless of the latest tag
- Restore Scala Steward (?) HOT 2
- Is it possible to check only if Event and State is serializable? HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from akka-serialization-helper.