@@ -122,6 +122,14 @@ import Servant.API.Sub ( type (:>) )
122122import Servant.API.Raw ( Raw )
123123import Servant.API.Alternative ( type (:<|>) )
124124
125+-- | A safe link datatype.
126+-- The only way of constructing a 'Link' is using 'safeLink', which means any
127+-- 'Link' is guaranteed to be part of the mentioned API.
128+data Link = Link
129+ { _segments :: [String] -- ^ Segments of "foo/bar" would be ["foo", "bar"]
130+ , _queryParams :: [Param Query]
131+ } deriving Show
132+
125133-- | If either a or b produce an empty constraint, produce an empty constraint.
126134type family Or (a :: Constraint) (b :: Constraint) :: Constraint where
127135 Or () b = ()
@@ -156,14 +164,26 @@ type family IsElem endpoint api :: Constraint where
156164 IsElem sa (MatrixFlag x :> sb) = IsElem sa sb
157165 IsElem e e = ()
158166 IsElem e a = IsElem' e a
167+ IsElem (Get ct typ) (Get ct' typ) = IsSubList ct ct'
168+ IsElem (Post ct typ) (Post ct' typ) = IsSubList ct ct'
169+ IsElem (Put ct typ) (Put ct' typ) = IsSubList ct ct'
170+ IsElem e e = 'True
171+ IsElem e a = 'False
159172
160−-- | A safe link datatype.
161−-- The only way of constructing a 'Link' is using 'safeLink', which means any
162−-- 'Link' is guaranteed to be part of the mentioned API.
163−data Link = Link
164− { _segments :: [String] -- ^ Segments of "foo/bar" would be ["foo", "bar"]
165− , _queryParams :: [Param Query]
166− } deriving Show
173+
174+type family IsSubList a b where
175+ IsSubList '[] b = 'True
176+ IsSubList '[x] (x ': xs) = 'True
177+ IsSubList '[x] (y ': ys) = IsSubList '[x] ys
178+ IsSubList (x ': xs) y = IsSubList '[x] y `And` IsSubList xs y
179+ IsSubList a b = 'False
180+
181+type family IsLink'' l where
182+ IsLink'' (e :> Get cts x) = IsLink' e
183+ IsLink'' (e :> Post cts x) = IsLink' e
184+ IsLink'' (e :> Put cts x) = IsLink' e
185+ IsLink'' (e :> Delete) = IsLink' e
186+ IsLink'' a = 'False
167187
168188
169189-- Phantom types for Param
@@ -317,16 +337,16 @@ instance (ToText v, HasLink sub)
317337 addSegment (escape . unpack $ toText v) l
318338
319339-- Verb (terminal) instances
320−instance HasLink (Get r) where
321− type MkLink (Get r) = URI
340+instance HasLink (Get y r) where
341+ type MkLink (Get y r) = URI
322342 toLink _ = linkURI
323343
324344instance HasLink (Post r) where
325− type MkLink (Post r) = URI
345+ type MkLink (Post y r) = URI
326346 toLink _ = linkURI
327347
328−instance HasLink (Put r) where
329− type MkLink (Put r) = URI
348+instance HasLink (Put y r) where
349+ type MkLink (Put y r) = URI
330350 toLink _ = linkURI
331351
332352instance HasLink Delete where