This repository has been archived by the owner on Apr 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 566
/
AnyParamDirectives.scala
129 lines (102 loc) · 5.54 KB
/
AnyParamDirectives.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* Copyright © 2011-2013 the spray project <http://spray.io>
*
* 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 spray.routing
package directives
import shapeless._
trait AnyParamDirectives {
/**
* Extracts a parameter either from a form field or from query parameters (in that order), and passes the value(s)
* to the inner route.
*
* Rejects the request if both form field and query parameter matcher(s) defined by the definition(s) don't match.
*/
/* directive */ def anyParam(apdm: AnyParamDefMagnet): apdm.Out = apdm()
/**
* Extracts a parameter either from a form field or from query parameters (in that order), and passes the value(s)
* to the inner route.
*
* Rejects the request if both form field and query parameter matcher(s) defined by the definition(s) don't match.
*/
/* directive */ def anyParams(apdm: AnyParamDefMagnet): apdm.Out = apdm()
}
object AnyParamDirectives extends AnyParamDirectives
trait AnyParamDefMagnet {
type Out
def apply(): Out
}
object AnyParamDefMagnet {
implicit def apply[T](value: T)(implicit apdm2: AnyParamDefMagnet2[T]) =
new AnyParamDefMagnet {
type Out = apdm2.Out
def apply() = apdm2(value)
}
}
trait AnyParamDefMagnet2[T] {
type Out
def apply(value: T): Out
}
object AnyParamDefMagnet2 {
import FieldDefMagnet2.FieldDefMagnetAux
import ParamDefMagnet2.ParamDefMagnetAux
type AnyParamDefMagnetAux[A, B] = AnyParamDefMagnet2[A] { type Out = B }
def AnyParamDefMagnetAux[A, B](f: A ⇒ B) = new AnyParamDefMagnet2[A] { type Out = B; def apply(a: A) = f(a) }
private def extractAnyParam[A, B](f: A ⇒ Directive1[B]) = AnyParamDefMagnetAux[A, Directive1[B]](f)
private def anyParamWrapper[A, B](a: A)(implicit fdma: FieldDefMagnetAux[A, Directive1[B]], pdma: ParamDefMagnetAux[A, Directive1[B]]): Directive1[B] = {
// handle optional params
// see https://groups.google.com/forum/?fromgroups=#!topic/spray-user/HGEEdVajpUw
fdma(a).hflatMap {
case None :: HNil ⇒ pdma(a)
case x ⇒ BasicDirectives.hprovide(x)
} | pdma(a)
}
private def anyParamDefaultWrapper[A, B](a: A, default: ⇒ B)(implicit fdma: FieldDefMagnetAux[A, Directive1[B]], pdma: ParamDefMagnetAux[A, Directive1[B]]): Directive1[B] =
anyParamWrapper(a).hflatMap {
case None :: HNil ⇒ BasicDirectives.provide(default)
case x ⇒ BasicDirectives.hprovide(x)
} | BasicDirectives.provide(default)
implicit def forString(implicit fdma: FieldDefMagnetAux[String, Directive1[String]], pdma: ParamDefMagnetAux[String, Directive1[String]]) = {
extractAnyParam[String, String](anyParamWrapper(_))
}
implicit def forSymbol(implicit fdma: FieldDefMagnetAux[Symbol, Directive1[String]], pdma: ParamDefMagnetAux[Symbol, Directive1[String]]) = {
extractAnyParam[Symbol, String](anyParamWrapper(_))
}
implicit def forNR[T](implicit fdma: FieldDefMagnetAux[NameReceptacle[T], Directive1[T]], pdma: ParamDefMagnetAux[NameReceptacle[T], Directive1[T]]) = {
extractAnyParam[NameReceptacle[T], T](anyParamWrapper(_))
}
implicit def forNDefR[T](implicit fdma: FieldDefMagnetAux[NameReceptacle[T], Directive1[T]], pdma: ParamDefMagnetAux[NameReceptacle[T], Directive1[T]]) = {
extractAnyParam[NameDefaultReceptacle[T], T](t ⇒ anyParamDefaultWrapper(NameReceptacle[T](t.name), t.default))
}
implicit def forNDesR[T](implicit fdma: FieldDefMagnetAux[NameDeserializerReceptacle[T], Directive1[T]], pdma: ParamDefMagnetAux[NameDeserializerReceptacle[T], Directive1[T]]) = {
extractAnyParam[NameDeserializerReceptacle[T], T](anyParamWrapper(_))
}
implicit def forNDesDefR[T](implicit fdma: FieldDefMagnetAux[NameDeserializerReceptacle[T], Directive1[T]], pdma: ParamDefMagnetAux[NameDeserializerReceptacle[T], Directive1[T]]) = {
extractAnyParam[NameDeserializerDefaultReceptacle[T], T](t ⇒ anyParamDefaultWrapper(NameDeserializerReceptacle[T](t.name, t.deserializer), t.default))
}
implicit def forRVR[T](implicit fdma: FieldDefMagnetAux[RequiredValueReceptacle[T], Directive1[T]], pdma: ParamDefMagnetAux[RequiredValueReceptacle[T], Directive1[T]]) = {
extractAnyParam[RequiredValueReceptacle[T], T](anyParamWrapper(_))
}
implicit def forRVDR[T](value: T)(implicit fdma: FieldDefMagnetAux[RequiredValueDeserializerReceptacle[T], Directive1[T]], pdma: ParamDefMagnetAux[RequiredValueDeserializerReceptacle[T], Directive1[T]]) = {
extractAnyParam[RequiredValueDeserializerReceptacle[T], T](anyParamWrapper(_))
}
implicit def forTuple[T <: Product, L <: HList, Out0](implicit hla: HListerAux[T, L], pdma: AnyParamDefMagnetAux[L, Out0]) =
AnyParamDefMagnetAux[T, Out0](tuple ⇒ pdma(hla(tuple)))
implicit def forHList[L <: HList](implicit f: LeftFolder[L, Directive0, MapReduce.type]) =
AnyParamDefMagnetAux[L, f.Out](_.foldLeft(BasicDirectives.noop)(MapReduce))
object MapReduce extends Poly2 {
implicit def from[T, LA <: HList, LB <: HList, Out <: HList](implicit pdma: AnyParamDefMagnetAux[T, Directive[LB]], ev: PrependAux[LA, LB, Out]) =
at[Directive[LA], T] { (a, t) ⇒ a & pdma(t) }
}
}