Open tg44 opened 4 years ago
Interesting, I didn't know about this akka-http feature :)
Let's maybe first look at the first case, leaving validation for later.
So we have:
def pathFromMapWithDefault[K: PlainCodec, V](inMap: Map[K, V], default: V): EndpointInput[V]
decoding is quite straightforward, encoding is more tricky, as we have a value, which we need to convert to a key (this would be used when calling this endpoint as a client).
So we'd need to create a Map[V, K]
- also with a default. Question is then, what to do when there's no matching key? We could either have defaultK: K
, or throw an exception indicating a programming error - there's currently no other way to signal an encoding error.
The impl would be sth like:
def pathFromMapWithDefault[K: PlainCodec, V](inMap: Map[K, V], default: V): EndpointInput[V] = {
val vToK = inMap.map(_.swap)
path[K].map(k => inMap.getOrElse(k, default))(v => vToK.getOrElse(v, throw new RuntimeException(s"No key for value: $v")))
}
What do you think?
Hmm... If we should map both directions, I would use bimap with some implementations, and probably with an api with implicit converter from map. (So the def would be
def pathFromMapWithDefault[K: PlainCodec, V](inMap: BiMap[K, V], default: V): EndpointInput[V]
, and you need to import bimap.syntax._
for a pathFromMapWithDefault(Map.empty[A,B].toBimap, B.empty)
call option. Also probably would use a default K for the 'withDefault(s)' function.)
BTW: the def pathFromStringMap[V](inMap: Map[String, V]): EndpointInput[V]
works as expected; I get
- name: p3
in: path
required: true
schema:
type: string
enum:
- add
- remove
to my output yaml, the APIs runs as expected with it.
Sure, bimap would be an option as well. And yes, your implementation works for server & doc interpreters, but would fail for client interpreter (though you might not need it :) )
Okay! I will draft a PR with this.
I'm currently migrating lot of endpoints from akka-http to tapir. And sometimes we used some really handy akka features in our code. My current struggle is the
Map[String, V]
handling;Here are the official akka path matchers list: https://doc.akka.io/docs/akka-http/current/routing-dsl/path-matchers.html#basic-pathmatchers
My not tested but compiling code for the
Map
s;My main question is the
.map(inMap)(_ => inMap.keys.head)
line and how bad this idea is? (If we not count theMap.empty.head
case.)Also can we add this next to the official
path[T]
?