Skip to content

Commit 2d13b70

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 2d13b70

File tree

9 files changed

+693
-0
lines changed

9 files changed

+693
-0
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: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
http-types,
21+
text,
22+
bytestring
23+
hs-source-dirs: src
24+
default-language: Haskell2010
25+
ghc-options: -Wall
26+

solga-core/src/Solga/Core.hs

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

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: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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
42+
, text
43+
, bytestring
44+
, wai
45+
, wai-extra
46+
, aeson
47+
, hspec
48+
, hspec-wai
49+
, hspec-wai-json
50+
, http-types
51+
, unordered-containers
52+
, hashable
53+
, vector
54+
, scientific
55+
, QuickCheck

0 commit comments

Comments
 (0)