{-# OPTIONS_HADDOCK not-home #-}
module MagicWormhole.Internal.FileTransfer
( Offer(..)
, DirectoryMode(..)
) where
import Protolude
import Data.Aeson
( FromJSON(..)
, ToJSON(..)
, (.:)
, (.=)
, object
, withObject
, Value( String )
)
import Data.Aeson.Types (typeMismatch)
import System.Posix.Types (FileOffset)
import Numeric.Natural (Natural)
data Offer
= Message Text
| File FilePath FileOffset
| Directory
{ directoryMode :: DirectoryMode
, dirName :: Text
, zipSize :: Natural
, numBytes :: Natural
, numFiles :: Natural
} deriving (Eq, Show)
instance ToJSON Offer where
toJSON (Message text) = object [ "offer" .= object [ "message" .= text ] ]
toJSON (File name size) = object [ "offer" .= object [ "file" .= object [ "filename" .= name, "filesize" .= fromEnum size ] ] ]
toJSON (Directory mode dirname zipsize numbytes numfiles) = object [ "offer" .= object [ "directory" .= object [ "mode" .= mode, "dirname" .= dirname, "zipsize" .= zipsize, "numbytes" .= numbytes, "numfiles" .= numfiles ] ] ]
instance FromJSON Offer where
parseJSON = withObject "Offer" $ \obj -> do
offer <- obj .: "offer"
asum [ Message <$> offer .: "message"
, File
<$> ((offer .: "file") >>= (.: "filename"))
<*> (toEnum <$> ((offer .: "file") >>= (.: "filesize")))
, Directory
<$> ((offer .: "directory") >>= (.: "mode"))
<*> ((offer .: "directory") >>= (.: "dirname"))
<*> (toEnum <$> ((offer .: "directory") >>= (.: "zipsize")))
<*> (toEnum <$> ((offer .: "directory") >>= (.: "numbytes")))
<*> (toEnum <$> ((offer .: "directory") >>= (.: "numfiles")))
]
data DirectoryMode = ZipFileDeflated
deriving (Eq, Show)
instance FromJSON DirectoryMode where
parseJSON (String s) | s == "zipfile/deflated" = return ZipFileDeflated
parseJSON o = typeMismatch "failed to parse Directory Mode" o
instance ToJSON DirectoryMode where
toJSON ZipFileDeflated = String "zipfile/deflated"