diff options
author | stuebinm | 2022-11-23 23:39:27 +0100 |
---|---|---|
committer | stuebinm | 2022-11-23 23:39:27 +0100 |
commit | f0f5fa44dd3dbc2a5a6308e2dce047a82c8b1be2 (patch) | |
tree | 6ff1a8a97cc78b6e2664a0fa97227bcbf539eb0f /vdv-server/VDV451.hs | |
parent | 97b99ed70f900716e17771f14a210dbed2ab9841 (diff) |
VDV 452 instances for serialisation
this may occasionally produce wrong output. In a lot of places I'm
not entirey sure if I understood the standard correctly …
Diffstat (limited to 'vdv-server/VDV451.hs')
-rw-r--r-- | vdv-server/VDV451.hs | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/vdv-server/VDV451.hs b/vdv-server/VDV451.hs index 1d56e1c..b962208 100644 --- a/vdv-server/VDV451.hs +++ b/vdv-server/VDV451.hs @@ -47,10 +47,6 @@ instance ÖPNVEncode Text where instance ÖPNVEncode Day where encode day = "\""+|crop 2 d|+"."+|crop 2 m|+"."+|crop 4 y|+"\"" where (y,m,d) = toGregorian day - crop n thing = if T.length shown < n - then T.replicate (n - T.length shown) "0" <> shown - else T.takeEnd n shown - where shown = T.pack $ show thing -- | for things which can be encoded as either string or number, -- this module defaults to strings. Add this newtype to the schema @@ -69,6 +65,32 @@ instance ÖPNVEncode Int instance ÖPNVEncode Integer +-- | these are encoded in a horrible format +newtype Longitude = Longitude Double +newtype Latitude = Latitude Double + +encodeGeoLength :: Double -> ByteString +encodeGeoLength d' = ""+|sign|+""+|crop 3 deg|+""+|crop 2 min|+""+|crop 5 sec|+"" + where deg = truncate d + min = truncate (d * 60) `mod` 60 + sec = truncate (d * 3600 * 1000) `mod` (60 * 1000) + d = abs d' + sign :: Text + sign = if d' < 0 then "-" else "" + +instance ÖPNVEncode Latitude where + encode (Latitude d) = encodeGeoLength d +instance ÖPNVEncode Longitude where + encode (Longitude d) = encodeGeoLength d + +-- | this isn't specified anywhere, but seems to be what VDV 452 implies +instance ÖPNVEncode a => ÖPNVEncode (Maybe a) where + encode (Just a) = encode a + encode Nothing = "NULL" + +instance ÖPNVEncode Bool where + encode False = "0" + encode True = "1" data ÖPNVBefehl = MOD | SRC | CHS | VER | IFV @@ -102,6 +124,7 @@ instance ÖPNVEncode ÖPNVType where class ÖPNVDatum a where tableName :: Proxy a -> ByteString + tableNumber :: Proxy a -> Int tableSchema :: Proxy a -> [(ByteString, ÖPNVType, a -> Feld)] encodeRow :: forall a. ÖPNVDatum a => a -> [Feld] @@ -145,3 +168,9 @@ data ÖPNVOptions = ÖPNVOptions . C8.intercalate "; " . fmap (\case { (F a) -> encode a; Raw a -> a }) (colNames, colTypes) = unzip (tableInfo (Proxy @a)) + + +crop n thing = if T.length shown < n + then T.replicate (n - T.length shown) "0" <> shown + else T.takeEnd n shown + where shown = T.pack $ show thing |