-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTourJson.hs
More file actions
133 lines (111 loc) · 4.16 KB
/
Copy pathTourJson.hs
File metadata and controls
133 lines (111 loc) · 4.16 KB
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
130
131
132
133
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE CPP #-}
module TourJson where
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import Data.Time.Calendar (Day)
import Data.Time.Format (parseTimeM, defaultTimeLocale, formatTime, iso8601DateFormat)
import Data.Time.LocalTime (LocalTime, TimeOfDay)
import Data.Time.Clock.POSIX (POSIXTime)
import Data.Time.Clock (NominalDiffTime)
import Data.Map (Map, fromList)
import Data.Maybe (catMaybes)
import Data.List (intercalate)
import Data.Aeson
import Data.Aeson.Types
import Data.Monoid
import Control.Monad (forM)
import Data.Text (Text)
import GHC.Generics
import qualified Data.Map as M
import qualified Data.Vector as V
import Naqsha.Geometry
import Data.Scientific (toRealFloat)
import Network.URI (URI(..), parseURIReference)
import Types
prefixOptions :: Options
prefixOptions = defaultOptions { fieldLabelModifier = drop 1 . dropWhile (/= '_') . camel }
instance ToJSON TourDay where
toJSON = genericToJSON prefixOptions
instance ToJSON Tour where
toJSON = genericToJSON prefixOptions
instance ToJSON Geo where
toJSON (Geo lat' lon') = Array (V.fromList [num lat', num lon'])
where
num :: Angular n => n -> Value
num = Number . toDegree . toAngle
instance FromJSON Tour where
parseJSON (Object v) = Tour <$>
v .: "name" <*>
v .:? "description" .!= "" <*>
v .:? "days" .!= [] <*>
v .:? "start_date" <*>
v .:? "end_date" <*>
v .:? "countries" .!= []
-- A non-Object value is of the wrong type, so fail.
parseJSON _ = mempty
instance FromJSON TourDay where
parseJSON (Object v) = TourDay <$>
v .:? "num" .!= 0 <*>
v .: "date" <*>
v .:? "start" <*>
v .:? "end" <*>
v .:? "from" .!= "" <*>
v .:? "to" .!= "" <*>
v .:? "from_coord" <*>
v .:? "to_coord" <*>
v .:? "dist" .!= 0 <*>
v .:? "blog"
parseJSON (String d) = do
d' <- parseJSON (String d)
return $ TourDay 0 d' Nothing Nothing "" "" Nothing Nothing 0 Nothing
-- A non-Object value is of the wrong type, so fail.
parseJSON v = typeMismatch "TourDay" v
instance FromJSON Geo where
parseJSON (Object v) = Geo <$> v .: "lat" <*> v .: "lng"
parseJSON (Array a) = case V.toList a of
[lat', lon'] -> Geo <$> parseJSON lat' <*> parseJSON lon'
_ -> fail "expected length 2 array"
parseJSON v = typeMismatch "Geo" v
parseCoord :: (Angle -> a) -> Value -> Parser a
parseCoord coord (Number n) = pure . coord . degree . toRational . toRealFloat $ n
parseCoord _ v = typeMismatch "Angle" v
instance FromJSON Latitude where
parseJSON = parseCoord lat
instance FromJSON Longitude where
parseJSON = parseCoord lon
instance ToJSON ElevPoint where
toJSON (ElevPoint e s t) = object ["ele" .= e, "dist" .= s, "time" .= t]
instance FromJSON ElevPoint where
parseJSON (Object v) = ElevPoint
<$> v .: "ele"
<*> v .: "dist"
<*> v .: "time"
parseJSON v = typeMismatch "ElevPoint" v
instance ToJSON URI where
toJSON = String . T.pack . show
instance FromJSON URI where
parseJSON (String u) = case parseURIReference (T.unpack u) of
Just uri -> pure uri
Nothing -> fail "Not a valid URI"
----------------------------------------------------------------------------
#if !MIN_VERSION_aeson(1,0,0)
instance ToJSON Day where
toJSON _ = object []
instance ToJSON TimeOfDay where
toJSON _ = object []
instance ToJSON NominalDiffTime where
toJSON _ = object []
instance FromJSON Day where
parseJSON _ = undefined
instance FromJSON TimeOfDay where
parseJSON _ = undefined
instance FromJSON NominalDiffTime where
parseJSON _ = undefined
camel = camelTo '_'
#else
camel = camelTo2 '_'
#endif