Skip to content

Commit 0e77ae1

Browse files
committed
split datatypes definitions out from router...
...in preparation to ghcjs client side library, which we do not want to burden with inappropriate dependencies such as wai.
1 parent e3a9fd9 commit 0e77ae1

File tree

14 files changed

+574
-416
lines changed

14 files changed

+574
-416
lines changed

solga-core/LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (c) 2016 Patrick Chilton
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
"Software"), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included
12+
in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

solga-core/Setup.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

solga-core/solga-core.cabal

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: solga-core
2+
version: 0.1.0.0
3+
synopsis: Simple typesafe web routing
4+
description: A library for easily specifying web APIs and implementing them in a type-safe way.
5+
license: MIT
6+
license-file: LICENSE
7+
author: Patrick Chilton
8+
maintainer: [email protected]
9+
copyright: Copyright (C) 2016 Patrick Chilton
10+
category: Web
11+
build-type: Simple
12+
homepage: https://github.com/chpatrick/solga
13+
bug-reports: https://github.com/chpatrick/solga/issues
14+
-- extra-source-files:
15+
cabal-version: >=1.10
16+
17+
library
18+
exposed-modules: Solga.Core
19+
build-depends: base >= 4.8 && < 5,
20+
case-insensitive,
21+
bytestring
22+
hs-source-dirs: src
23+
default-language: Haskell2010
24+
ghc-options: -Wall
25+

solga-core/src/Solga/Core.hs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
{-# LANGUAGE DataKinds #-}
2+
{-# LANGUAGE FlexibleContexts #-}
3+
{-# LANGUAGE FlexibleInstances #-}
4+
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5+
{-# LANGUAGE KindSignatures #-}
6+
{-# LANGUAGE LambdaCase #-}
7+
{-# LANGUAGE MultiParamTypeClasses #-}
8+
{-# LANGUAGE OverloadedStrings #-}
9+
{-# LANGUAGE ScopedTypeVariables #-}
10+
{-# LANGUAGE TypeOperators #-}
11+
{-# LANGUAGE TypeFamilies #-}
12+
{-# LANGUAGE DefaultSignatures #-}
13+
{-# LANGUAGE StandaloneDeriving #-}
14+
{-# LANGUAGE NamedFieldPuns #-}
15+
module Solga.Core
16+
( -- * Path components
17+
type (:>), type (/>)
18+
, Get
19+
, Post
20+
, JSON(..)
21+
, Raw(..)
22+
, RawResponse(..)
23+
, End(..)
24+
, WithIO(..)
25+
, Seg(..)
26+
, OneOfSegs(..)
27+
, Capture(..)
28+
, Method(..)
29+
, HeaderName
30+
, Header
31+
, ResponseHeaders
32+
, ExtraHeaders(..)
33+
, NoCache(..)
34+
, ReqBodyJSON(..)
35+
, MultiPartParam
36+
, MultiPartFile
37+
, MultiPartFileInfo(..)
38+
, MultiPartData
39+
, ReqBodyMultipart(..)
40+
, Endpoint
41+
, (:<|>)(..)
42+
) where
43+
44+
import GHC.TypeLits
45+
import Data.ByteString (ByteString)
46+
import Data.CaseInsensitive (CI)
47+
48+
---------------------------------------------------
49+
50+
-- | Compose routers. This is just type application,
51+
-- ie.: @Foo :> Bar :> Baz == Foo (Bar Baz)@
52+
type f :> g = f g
53+
infixr 2 :>
54+
55+
-- | Serve a given WAI `Wai.Application`.
56+
newtype Raw a = Raw { rawApp :: a }
57+
58+
-- | Serve a given WAI `Wai.Response`.
59+
newtype RawResponse a = RawResponse { rawResponse :: a }
60+
61+
-- | Only accept the end of a path.
62+
newtype End next = End { endNext :: next }
63+
64+
-- | Match a constant directory in the path.
65+
--
66+
-- When specifying APIs, use the `/>` combinator to specify sub-paths:
67+
-- @"foo" `/>` `JSON` Bar@
68+
newtype Seg (seg :: Symbol) next = Seg { segNext :: next }
69+
deriving (Eq, Ord, Show)
70+
71+
-- | Match a path, segment, e.g @"foo" `/>` `JSON` Bar@
72+
type seg /> g = Seg seg :> g
73+
infixr 2 />
74+
75+
-- | Try to route with @left@, or try to route with @right@.
76+
data left :<|> right = (:<|>) { altLeft :: left, altRight :: right }
77+
deriving (Eq, Ord, Show)
78+
79+
infixr 1 :<|>
80+
81+
-- | Match any of a set of path segments.
82+
data OneOfSegs (segs :: [ Symbol ]) next = OneOfSegs { oneOfSegsNext :: next }
83+
84+
-- | Capture a path segment and pass it on.
85+
newtype Capture a next = Capture { captureNext :: a -> next }
86+
87+
-- | Accepts requests with a certain method.
88+
newtype Method (method :: Symbol) next = Method { methodNext :: next }
89+
deriving (Eq, Ord, Show)
90+
91+
-- | Return a given JSON object
92+
newtype JSON a = JSON { jsonResponse :: a }
93+
deriving (Eq, Ord, Show)
94+
95+
type HeaderName = CI ByteString
96+
type Header = (HeaderName, ByteString)
97+
type ResponseHeaders = [Header]
98+
99+
-- | Set extra headers on responses.
100+
-- Existing headers will be overriden if specified here.
101+
data ExtraHeaders next = ExtraHeaders
102+
{ extraHeaders :: ResponseHeaders
103+
, extraHeadersNext :: next
104+
}
105+
106+
-- | Prevent caching for sub-routers.
107+
newtype NoCache next = NoCache { noCacheNext :: next }
108+
109+
-- | Parse a JSON request body.
110+
newtype ReqBodyJSON a next = ReqBodyJSON { reqBodyJSONNext :: a -> next }
111+
112+
-- | Produce a response with `IO`.
113+
newtype WithIO next = WithIO { withIONext :: IO next }
114+
115+
type MultiPartParam = (ByteString, ByteString)
116+
type MultiPartFile y = (ByteString, MultiPartFileInfo y)
117+
118+
data MultiPartFileInfo c = MultiPartFileInfo
119+
{ mpfiName :: ByteString
120+
, mpfiContentType :: ByteString
121+
, mpfiContent :: FilePath
122+
}
123+
124+
-- | A parsed "multipart/form-data" request.
125+
type MultiPartData y = ([MultiPartParam], [MultiPartFile y])
126+
127+
-- | Accept a "multipart/form-data" request.
128+
-- Files will be stored in a temporary directory and will be deleted
129+
-- automatically after the request is processed.
130+
data ReqBodyMultipart y a next = ReqBodyMultipart
131+
{ reqMultiPartParse :: MultiPartData y -> Either String a
132+
, reqMultiPartNext :: a -> next
133+
}
134+
135+
-- | Useful synonym for dynamic endpoints: accept requests with a given method, compute a JSON response in `IO` and don't cache.
136+
type Endpoint method a = End :> NoCache :> Method method :> WithIO :> a
137+
138+
-- | Handle a "GET" request and produce a "JSON" response, with `IO`.
139+
type Get a = Endpoint "GET" (JSON a)
140+
-- | Handle a "POST" request and produce a "JSON" response, with `IO`.
141+
type Post a = Endpoint "POST" (JSON a)
142+

solga-router/LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (c) 2016 Patrick Chilton
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
"Software"), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included
12+
in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

solga-router/Setup.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

solga-router/solga-router.cabal

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: solga-router
2+
version: 0.1.0.0
3+
synopsis: Simple typesafe web routing
4+
description: A library for easily specifying web APIs and implementing them in a type-safe way.
5+
license: MIT
6+
license-file: LICENSE
7+
author: Patrick Chilton
8+
maintainer: [email protected]
9+
copyright: Copyright (C) 2016 Patrick Chilton
10+
category: Web
11+
build-type: Simple
12+
homepage: https://github.com/chpatrick/solga
13+
bug-reports: https://github.com/chpatrick/solga/issues
14+
-- extra-source-files:
15+
cabal-version: >=1.10
16+
17+
library
18+
exposed-modules: Solga.Router
19+
build-depends: base >= 4.8 && < 5,
20+
solga-core,
21+
text,
22+
wai,
23+
bytestring,
24+
containers,
25+
aeson >= 1.0.0.0,
26+
wai-extra,
27+
http-types,
28+
resourcet,
29+
safe-exceptions
30+
hs-source-dirs: src
31+
default-language: Haskell2010
32+
ghc-options: -Wall
33+
34+
test-suite solga-tests
35+
type: exitcode-stdio-1.0
36+
hs-source-dirs: test
37+
main-is: Test.hs
38+
ghc-options: -Wall
39+
default-language: Haskell2010
40+
build-depends: base
41+
, solga-router
42+
, solga-core
43+
, text
44+
, bytestring
45+
, wai
46+
, wai-extra
47+
, aeson
48+
, hspec
49+
, hspec-wai
50+
, hspec-wai-json
51+
, http-types
52+
, unordered-containers
53+
, hashable
54+
, vector
55+
, scientific
56+
, QuickCheck

0 commit comments

Comments
 (0)