--
-- MinIO Haskell SDK, (C) 2017 MinIO, Inc.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

module Network.Minio.XmlParser
  ( parseListBuckets,
    parseLocation,
    parseNewMultipartUpload,
    parseCompleteMultipartUploadResponse,
    parseCopyObjectResponse,
    parseListObjectsResponse,
    parseListObjectsV1Response,
    parseListUploadsResponse,
    parseListPartsResponse,
    parseErrResponse,
    parseNotification,
    parseSelectProgress,
  )
where

import qualified Data.ByteString.Lazy as LB
import qualified Data.HashMap.Strict as H
import Data.List (zip4, zip6)
import qualified Data.Text as T
import Data.Text.Read (decimal)
import Data.Time
import Lib.Prelude
import Network.Minio.Data
import Network.Minio.Errors
import Text.XML
import Text.XML.Cursor hiding (bool)

-- | Represent the time format string returned by S3 API calls.
s3TimeFormat :: [Char]
s3TimeFormat :: [Char]
s3TimeFormat = Maybe [Char] -> [Char]
iso8601DateFormat (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"%T%QZ"

-- | Helper functions.
uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
uncurry4 a -> b -> c -> d -> e
f (a
a, b
b, c
c, d
d) = a -> b -> c -> d -> e
f a
a b
b c
c d
d

uncurry6 :: (a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 :: (a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 a -> b -> c -> d -> e -> f -> g
f (a
a, b
b, c
c, d
d, e
e, f
g) = a -> b -> c -> d -> e -> f -> g
f a
a b
b c
c d
d e
e f
g

-- | Parse time strings from XML
parseS3XMLTime :: MonadIO m => Text -> m UTCTime
parseS3XMLTime :: Text -> m UTCTime
parseS3XMLTime Text
t =
  m UTCTime -> (UTCTime -> m UTCTime) -> Maybe UTCTime -> m UTCTime
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (MErrV -> m UTCTime
forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
throwIO (MErrV -> m UTCTime) -> MErrV -> m UTCTime
forall a b. (a -> b) -> a -> b
$ Text -> MErrV
MErrVXmlParse (Text -> MErrV) -> Text -> MErrV
forall a b. (a -> b) -> a -> b
$ Text
"timestamp parse failure: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t) UTCTime -> m UTCTime
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe UTCTime -> m UTCTime) -> Maybe UTCTime -> m UTCTime
forall a b. (a -> b) -> a -> b
$
    Bool -> TimeLocale -> [Char] -> [Char] -> Maybe UTCTime
forall (m :: * -> *) t.
(MonadFail m, ParseTime t) =>
Bool -> TimeLocale -> [Char] -> [Char] -> m t
parseTimeM Bool
True TimeLocale
defaultTimeLocale [Char]
s3TimeFormat ([Char] -> Maybe UTCTime) -> [Char] -> Maybe UTCTime
forall a b. (a -> b) -> a -> b
$
      Text -> [Char]
T.unpack Text
t

parseDecimal :: (MonadIO m, Integral a) => Text -> m a
parseDecimal :: Text -> m a
parseDecimal Text
numStr =
  ([Char] -> m a) -> (a -> m a) -> Either [Char] a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (MErrV -> m a
forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
throwIO (MErrV -> m a) -> ([Char] -> MErrV) -> [Char] -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> MErrV
MErrVXmlParse (Text -> MErrV) -> ([Char] -> Text) -> [Char] -> MErrV
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Text
forall b a. (Show a, IsString b) => a -> b
show) a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [Char] a -> m a) -> Either [Char] a -> m a
forall a b. (a -> b) -> a -> b
$
    (a, Text) -> a
forall a b. (a, b) -> a
fst ((a, Text) -> a) -> Either [Char] (a, Text) -> Either [Char] a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Reader a
forall a. Integral a => Reader a
decimal Text
numStr

parseDecimals :: (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals :: [Text] -> m [a]
parseDecimals [Text]
numStr = [Text] -> (Text -> m a) -> m [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Text]
numStr Text -> m a
forall (m :: * -> *) a. (MonadIO m, Integral a) => Text -> m a
parseDecimal

s3Elem :: Text -> Text -> Axis
s3Elem :: Text -> Text -> Axis
s3Elem Text
ns = Name -> Axis
element (Name -> Axis) -> (Text -> Name) -> Text -> Axis
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> Name
s3Name Text
ns

parseRoot :: (MonadIO m) => LByteString -> m Cursor
parseRoot :: LByteString -> m Cursor
parseRoot =
  (SomeException -> m Cursor)
-> (Document -> m Cursor)
-> Either SomeException Document
-> m Cursor
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (MErrV -> m Cursor
forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
throwIO (MErrV -> m Cursor)
-> (SomeException -> MErrV) -> SomeException -> m Cursor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> MErrV
MErrVXmlParse (Text -> MErrV)
-> (SomeException -> Text) -> SomeException -> MErrV
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> Text
forall b a. (Show a, IsString b) => a -> b
show) (Cursor -> m Cursor
forall (m :: * -> *) a. Monad m => a -> m a
return (Cursor -> m Cursor)
-> (Document -> Cursor) -> Document -> m Cursor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Document -> Cursor
fromDocument)
    (Either SomeException Document -> m Cursor)
-> (LByteString -> Either SomeException Document)
-> LByteString
-> m Cursor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseSettings -> LByteString -> Either SomeException Document
parseLBS ParseSettings
forall a. Default a => a
def

-- | Parse the response XML of a list buckets call.
parseListBuckets :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m [BucketInfo]
parseListBuckets :: LByteString -> m [BucketInfo]
parseListBuckets LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      names :: [Text]
names = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"Bucket" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&// Text -> Axis
s3Elem' Text
"Name" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      timeStrings :: [Text]
timeStrings = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"Bucket" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&// Text -> Axis
s3Elem' Text
"CreationDate" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
times <- (Text -> m UTCTime) -> [Text] -> m [UTCTime]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Text -> m UTCTime
forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
timeStrings
  [BucketInfo] -> m [BucketInfo]
forall (m :: * -> *) a. Monad m => a -> m a
return ([BucketInfo] -> m [BucketInfo]) -> [BucketInfo] -> m [BucketInfo]
forall a b. (a -> b) -> a -> b
$ (Text -> UTCTime -> BucketInfo)
-> [Text] -> [UTCTime] -> [BucketInfo]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Text -> UTCTime -> BucketInfo
BucketInfo [Text]
names [UTCTime]
times

-- | Parse the response XML of a location request.
parseLocation :: (MonadIO m) => LByteString -> m Region
parseLocation :: LByteString -> m Text
parseLocation LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  let region :: Text
region = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Cursor -> [Text]
content
  Text -> m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool Text
"us-east-1" Text
region (Bool -> Text) -> Bool -> Text
forall a b. (a -> b) -> a -> b
$ Text
region Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
""

-- | Parse the response XML of an newMultipartUpload call.
parseNewMultipartUpload :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m UploadId
parseNewMultipartUpload :: LByteString -> m Text
parseNewMultipartUpload LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
  Text -> m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"UploadId" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

-- | Parse the response XML of completeMultipartUpload call.
parseCompleteMultipartUploadResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m ETag
parseCompleteMultipartUploadResponse :: LByteString -> m Text
parseCompleteMultipartUploadResponse LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
  Text -> m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"ETag" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

-- | Parse the response XML of copyObject and copyObjectPart
parseCopyObjectResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m (ETag, UTCTime)
parseCopyObjectResponse :: LByteString -> m (Text, UTCTime)
parseCopyObjectResponse LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      mtimeStr :: Text
mtimeStr = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"LastModified" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  UTCTime
mtime <- Text -> m UTCTime
forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime Text
mtimeStr
  (Text, UTCTime) -> m (Text, UTCTime)
forall (m :: * -> *) a. Monad m => a -> m a
return ([Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"ETag" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content, UTCTime
mtime)

-- | Parse the response XML of a list objects v1 call.
parseListObjectsV1Response ::
  (MonadReader env m, HasSvcNamespace env, MonadIO m) =>
  LByteString ->
  m ListObjectsV1Result
parseListObjectsV1Response :: LByteString -> m ListObjectsV1Result
parseListObjectsV1Response LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      hasMore :: Bool
hasMore = [Text
"true"] [Text] -> [Text] -> Bool
forall a. Eq a => a -> a -> Bool
== (Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"IsTruncated" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
      nextMarker :: Maybe Text
nextMarker = [Text] -> Maybe Text
forall a. [a] -> Maybe a
listToMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextMarker" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      prefixes :: [Text]
prefixes = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"CommonPrefixes" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Prefix" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      keys :: [Text]
keys = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Key" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      modTimeStr :: [Text]
modTimeStr = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"LastModified" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      etagsList :: [Text]
etagsList = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"ETag" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      -- if response xml contains empty etag response fill them with as
      -- many empty Text for the zip4 below to work as intended.
      etags :: [Text]
etags = [Text]
etagsList [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ Text -> [Text]
forall a. a -> [a]
repeat Text
""
      sizeStr :: [Text]
sizeStr = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Size" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
modTimes <- (Text -> m UTCTime) -> [Text] -> m [UTCTime]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Text -> m UTCTime
forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
modTimeStr
  [Int64]
sizes <- [Text] -> m [Int64]
forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals [Text]
sizeStr

  let objects :: [ObjectInfo]
objects =
        ((Text, UTCTime, Text, Int64, HashMap Text Text, HashMap Text Text)
 -> ObjectInfo)
-> [(Text, UTCTime, Text, Int64, HashMap Text Text,
     HashMap Text Text)]
-> [ObjectInfo]
forall a b. (a -> b) -> [a] -> [b]
map ((Text
 -> UTCTime
 -> Text
 -> Int64
 -> HashMap Text Text
 -> HashMap Text Text
 -> ObjectInfo)
-> (Text, UTCTime, Text, Int64, HashMap Text Text,
    HashMap Text Text)
-> ObjectInfo
forall a b c d e f g.
(a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 Text
-> UTCTime
-> Text
-> Int64
-> HashMap Text Text
-> HashMap Text Text
-> ObjectInfo
ObjectInfo) ([(Text, UTCTime, Text, Int64, HashMap Text Text,
   HashMap Text Text)]
 -> [ObjectInfo])
-> [(Text, UTCTime, Text, Int64, HashMap Text Text,
     HashMap Text Text)]
-> [ObjectInfo]
forall a b. (a -> b) -> a -> b
$
          [Text]
-> [UTCTime]
-> [Text]
-> [Int64]
-> [HashMap Text Text]
-> [HashMap Text Text]
-> [(Text, UTCTime, Text, Int64, HashMap Text Text,
     HashMap Text Text)]
forall a b c d e f.
[a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a, b, c, d, e, f)]
zip6 [Text]
keys [UTCTime]
modTimes [Text]
etags [Int64]
sizes (HashMap Text Text -> [HashMap Text Text]
forall a. a -> [a]
repeat HashMap Text Text
forall k v. HashMap k v
H.empty) (HashMap Text Text -> [HashMap Text Text]
forall a. a -> [a]
repeat HashMap Text Text
forall k v. HashMap k v
H.empty)

  ListObjectsV1Result -> m ListObjectsV1Result
forall (m :: * -> *) a. Monad m => a -> m a
return (ListObjectsV1Result -> m ListObjectsV1Result)
-> ListObjectsV1Result -> m ListObjectsV1Result
forall a b. (a -> b) -> a -> b
$ Bool -> Maybe Text -> [ObjectInfo] -> [Text] -> ListObjectsV1Result
ListObjectsV1Result Bool
hasMore Maybe Text
nextMarker [ObjectInfo]
objects [Text]
prefixes

-- | Parse the response XML of a list objects call.
parseListObjectsResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m ListObjectsResult
parseListObjectsResponse :: LByteString -> m ListObjectsResult
parseListObjectsResponse LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      hasMore :: Bool
hasMore = [Text
"true"] [Text] -> [Text] -> Bool
forall a. Eq a => a -> a -> Bool
== (Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"IsTruncated" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
      nextToken :: Maybe Text
nextToken = [Text] -> Maybe Text
forall a. [a] -> Maybe a
listToMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextContinuationToken" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      prefixes :: [Text]
prefixes = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"CommonPrefixes" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Prefix" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      keys :: [Text]
keys = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Key" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      modTimeStr :: [Text]
modTimeStr = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"LastModified" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      etagsList :: [Text]
etagsList = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"ETag" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      -- if response xml contains empty etag response fill them with as
      -- many empty Text for the zip4 below to work as intended.
      etags :: [Text]
etags = [Text]
etagsList [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ Text -> [Text]
forall a. a -> [a]
repeat Text
""
      sizeStr :: [Text]
sizeStr = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Size" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
modTimes <- (Text -> m UTCTime) -> [Text] -> m [UTCTime]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Text -> m UTCTime
forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
modTimeStr
  [Int64]
sizes <- [Text] -> m [Int64]
forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals [Text]
sizeStr

  let objects :: [ObjectInfo]
objects =
        ((Text, UTCTime, Text, Int64, HashMap Text Text, HashMap Text Text)
 -> ObjectInfo)
-> [(Text, UTCTime, Text, Int64, HashMap Text Text,
     HashMap Text Text)]
-> [ObjectInfo]
forall a b. (a -> b) -> [a] -> [b]
map ((Text
 -> UTCTime
 -> Text
 -> Int64
 -> HashMap Text Text
 -> HashMap Text Text
 -> ObjectInfo)
-> (Text, UTCTime, Text, Int64, HashMap Text Text,
    HashMap Text Text)
-> ObjectInfo
forall a b c d e f g.
(a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 Text
-> UTCTime
-> Text
-> Int64
-> HashMap Text Text
-> HashMap Text Text
-> ObjectInfo
ObjectInfo) ([(Text, UTCTime, Text, Int64, HashMap Text Text,
   HashMap Text Text)]
 -> [ObjectInfo])
-> [(Text, UTCTime, Text, Int64, HashMap Text Text,
     HashMap Text Text)]
-> [ObjectInfo]
forall a b. (a -> b) -> a -> b
$
          [Text]
-> [UTCTime]
-> [Text]
-> [Int64]
-> [HashMap Text Text]
-> [HashMap Text Text]
-> [(Text, UTCTime, Text, Int64, HashMap Text Text,
     HashMap Text Text)]
forall a b c d e f.
[a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a, b, c, d, e, f)]
zip6 [Text]
keys [UTCTime]
modTimes [Text]
etags [Int64]
sizes (HashMap Text Text -> [HashMap Text Text]
forall a. a -> [a]
repeat HashMap Text Text
forall k v. HashMap k v
H.empty) (HashMap Text Text -> [HashMap Text Text]
forall a. a -> [a]
repeat HashMap Text Text
forall k v. HashMap k v
H.empty)

  ListObjectsResult -> m ListObjectsResult
forall (m :: * -> *) a. Monad m => a -> m a
return (ListObjectsResult -> m ListObjectsResult)
-> ListObjectsResult -> m ListObjectsResult
forall a b. (a -> b) -> a -> b
$ Bool -> Maybe Text -> [ObjectInfo] -> [Text] -> ListObjectsResult
ListObjectsResult Bool
hasMore Maybe Text
nextToken [ObjectInfo]
objects [Text]
prefixes

-- | Parse the response XML of a list incomplete multipart upload call.
parseListUploadsResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m ListUploadsResult
parseListUploadsResponse :: LByteString -> m ListUploadsResult
parseListUploadsResponse LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      hasMore :: Bool
hasMore = [Text
"true"] [Text] -> [Text] -> Bool
forall a. Eq a => a -> a -> Bool
== (Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"IsTruncated" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
      prefixes :: [Text]
prefixes = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"CommonPrefixes" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Prefix" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      nextKey :: Maybe Text
nextKey = [Text] -> Maybe Text
forall a. [a] -> Maybe a
listToMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextKeyMarker" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      nextUpload :: Maybe Text
nextUpload = [Text] -> Maybe Text
forall a. [a] -> Maybe a
listToMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextUploadIdMarker" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      uploadKeys :: [Text]
uploadKeys = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Upload" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Key" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      uploadIds :: [Text]
uploadIds = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Upload" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"UploadId" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      uploadInitTimeStr :: [Text]
uploadInitTimeStr = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Upload" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Initiated" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
uploadInitTimes <- (Text -> m UTCTime) -> [Text] -> m [UTCTime]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Text -> m UTCTime
forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
uploadInitTimeStr

  let uploads :: [(Text, Text, UTCTime)]
uploads = [Text] -> [Text] -> [UTCTime] -> [(Text, Text, UTCTime)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Text]
uploadKeys [Text]
uploadIds [UTCTime]
uploadInitTimes

  ListUploadsResult -> m ListUploadsResult
forall (m :: * -> *) a. Monad m => a -> m a
return (ListUploadsResult -> m ListUploadsResult)
-> ListUploadsResult -> m ListUploadsResult
forall a b. (a -> b) -> a -> b
$ Bool
-> Maybe Text
-> Maybe Text
-> [(Text, Text, UTCTime)]
-> [Text]
-> ListUploadsResult
ListUploadsResult Bool
hasMore Maybe Text
nextKey Maybe Text
nextUpload [(Text, Text, UTCTime)]
uploads [Text]
prefixes

parseListPartsResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m ListPartsResult
parseListPartsResponse :: LByteString -> m ListPartsResult
parseListPartsResponse LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      hasMore :: Bool
hasMore = [Text
"true"] [Text] -> [Text] -> Bool
forall a. Eq a => a -> a -> Bool
== (Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"IsTruncated" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
      nextPartNumStr :: Maybe Text
nextPartNumStr = [Text] -> Maybe Text
forall a. [a] -> Maybe a
listToMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextPartNumberMarker" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      partNumberStr :: [Text]
partNumberStr = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Part" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"PartNumber" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      partModTimeStr :: [Text]
partModTimeStr = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Part" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"LastModified" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      partETags :: [Text]
partETags = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Part" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"ETag" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      partSizeStr :: [Text]
partSizeStr = Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Part" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Size" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
partModTimes <- (Text -> m UTCTime) -> [Text] -> m [UTCTime]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Text -> m UTCTime
forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
partModTimeStr
  [Int64]
partSizes <- [Text] -> m [Int64]
forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals [Text]
partSizeStr
  [PartNumber]
partNumbers <- [Text] -> m [PartNumber]
forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals [Text]
partNumberStr
  [Int]
nextPartNum <- [Text] -> m [Int]
forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals ([Text] -> m [Int]) -> [Text] -> m [Int]
forall a b. (a -> b) -> a -> b
$ Maybe Text -> [Text]
forall a. Maybe a -> [a]
maybeToList Maybe Text
nextPartNumStr

  let partInfos :: [ObjectPartInfo]
partInfos =
        ((PartNumber, Text, Int64, UTCTime) -> ObjectPartInfo)
-> [(PartNumber, Text, Int64, UTCTime)] -> [ObjectPartInfo]
forall a b. (a -> b) -> [a] -> [b]
map ((PartNumber -> Text -> Int64 -> UTCTime -> ObjectPartInfo)
-> (PartNumber, Text, Int64, UTCTime) -> ObjectPartInfo
forall a b c d e. (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
uncurry4 PartNumber -> Text -> Int64 -> UTCTime -> ObjectPartInfo
ObjectPartInfo) ([(PartNumber, Text, Int64, UTCTime)] -> [ObjectPartInfo])
-> [(PartNumber, Text, Int64, UTCTime)] -> [ObjectPartInfo]
forall a b. (a -> b) -> a -> b
$
          [PartNumber]
-> [Text]
-> [Int64]
-> [UTCTime]
-> [(PartNumber, Text, Int64, UTCTime)]
forall a b c d. [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
zip4 [PartNumber]
partNumbers [Text]
partETags [Int64]
partSizes [UTCTime]
partModTimes

  ListPartsResult -> m ListPartsResult
forall (m :: * -> *) a. Monad m => a -> m a
return (ListPartsResult -> m ListPartsResult)
-> ListPartsResult -> m ListPartsResult
forall a b. (a -> b) -> a -> b
$ Bool -> Maybe Int -> [ObjectPartInfo] -> ListPartsResult
ListPartsResult Bool
hasMore ([Int] -> Maybe Int
forall a. [a] -> Maybe a
listToMaybe [Int]
nextPartNum) [ObjectPartInfo]
partInfos

parseErrResponse :: (MonadIO m) => LByteString -> m ServiceErr
parseErrResponse :: LByteString -> m ServiceErr
parseErrResponse LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  let code :: Text
code = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Name -> Axis
element Name
"Code" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      message :: Text
message = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Name -> Axis
element Name
"Message" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
  ServiceErr -> m ServiceErr
forall (m :: * -> *) a. Monad m => a -> m a
return (ServiceErr -> m ServiceErr) -> ServiceErr -> m ServiceErr
forall a b. (a -> b) -> a -> b
$ Text -> Text -> ServiceErr
toServiceErr Text
code Text
message

parseNotification :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m Notification
parseNotification :: LByteString -> m Notification
parseNotification LByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- (env -> Text) -> m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks env -> Text
forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      qcfg :: [Node]
qcfg = (Cursor -> Node) -> [Cursor] -> [Node]
forall a b. (a -> b) -> [a] -> [b]
map Cursor -> Node
forall node. Cursor node -> node
node ([Cursor] -> [Node]) -> [Cursor] -> [Node]
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> Axis -> [Cursor]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"QueueConfiguration"
      tcfg :: [Node]
tcfg = (Cursor -> Node) -> [Cursor] -> [Node]
forall a b. (a -> b) -> [a] -> [b]
map Cursor -> Node
forall node. Cursor node -> node
node ([Cursor] -> [Node]) -> [Cursor] -> [Node]
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> Axis -> [Cursor]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"TopicConfiguration"
      lcfg :: [Node]
lcfg = (Cursor -> Node) -> [Cursor] -> [Node]
forall a b. (a -> b) -> [a] -> [b]
map Cursor -> Node
forall node. Cursor node -> node
node ([Cursor] -> [Node]) -> [Cursor] -> [Node]
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> Axis -> [Cursor]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"CloudFunctionConfiguration"
  [NotificationConfig]
-> [NotificationConfig] -> [NotificationConfig] -> Notification
Notification
    ([NotificationConfig]
 -> [NotificationConfig] -> [NotificationConfig] -> Notification)
-> m [NotificationConfig]
-> m ([NotificationConfig] -> [NotificationConfig] -> Notification)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Node -> m NotificationConfig) -> [Node] -> m [NotificationConfig]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Text -> Text -> Node -> m NotificationConfig
forall (m :: * -> *).
Monad m =>
Text -> Text -> Node -> m NotificationConfig
parseNode Text
ns Text
"Queue") [Node]
qcfg
    m ([NotificationConfig] -> [NotificationConfig] -> Notification)
-> m [NotificationConfig]
-> m ([NotificationConfig] -> Notification)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Node -> m NotificationConfig) -> [Node] -> m [NotificationConfig]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Text -> Text -> Node -> m NotificationConfig
forall (m :: * -> *).
Monad m =>
Text -> Text -> Node -> m NotificationConfig
parseNode Text
ns Text
"Topic") [Node]
tcfg
    m ([NotificationConfig] -> Notification)
-> m [NotificationConfig] -> m Notification
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Node -> m NotificationConfig) -> [Node] -> m [NotificationConfig]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Text -> Text -> Node -> m NotificationConfig
forall (m :: * -> *).
Monad m =>
Text -> Text -> Node -> m NotificationConfig
parseNode Text
ns Text
"CloudFunction") [Node]
lcfg
  where
    getFilterRule :: Text -> Cursor -> FilterRule
getFilterRule Text
ns Cursor
c =
      let name :: Text
name = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
c Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Name" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
          value :: Text
value = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
c Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Value" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
       in Text -> Text -> FilterRule
FilterRule Text
name Text
value
    parseNode :: Text -> Text -> Node -> m NotificationConfig
parseNode Text
ns Text
arnName Node
nodeData = do
      let c :: Cursor
c = Node -> Cursor
fromNode Node
nodeData
          itemId :: Text
itemId = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
c Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Id" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
          arn :: Text
arn = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
c Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
arnName Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
          events :: [Event]
events = (Text -> Maybe Event) -> [Text] -> [Event]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Text -> Maybe Event
textToEvent (Cursor
c Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Event" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
          rules :: [FilterRule]
rules =
            Cursor
c
              Cursor -> (Cursor -> [FilterRule]) -> [FilterRule]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Filter"
              Axis -> (Cursor -> [FilterRule]) -> Cursor -> [FilterRule]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Text -> Axis
s3Elem Text
ns Text
"S3Key"
              Axis -> (Cursor -> [FilterRule]) -> Cursor -> [FilterRule]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Text -> Axis
s3Elem Text
ns Text
"FilterRule"
              Axis -> (Cursor -> FilterRule) -> Cursor -> [FilterRule]
forall node a b.
(Cursor node -> [a]) -> (a -> b) -> Cursor node -> [b]
&| Text -> Cursor -> FilterRule
getFilterRule Text
ns
      NotificationConfig -> m NotificationConfig
forall (m :: * -> *) a. Monad m => a -> m a
return (NotificationConfig -> m NotificationConfig)
-> NotificationConfig -> m NotificationConfig
forall a b. (a -> b) -> a -> b
$
        Text -> Text -> [Event] -> Filter -> NotificationConfig
NotificationConfig
          Text
itemId
          Text
arn
          [Event]
events
          (FilterKey -> Filter
Filter (FilterKey -> Filter) -> FilterKey -> Filter
forall a b. (a -> b) -> a -> b
$ FilterRules -> FilterKey
FilterKey (FilterRules -> FilterKey) -> FilterRules -> FilterKey
forall a b. (a -> b) -> a -> b
$ [FilterRule] -> FilterRules
FilterRules [FilterRule]
rules)

parseSelectProgress :: MonadIO m => ByteString -> m Progress
parseSelectProgress :: ByteString -> m Progress
parseSelectProgress ByteString
xmldata = do
  Cursor
r <- LByteString -> m Cursor
forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot (LByteString -> m Cursor) -> LByteString -> m Cursor
forall a b. (a -> b) -> a -> b
$ ByteString -> LByteString
LB.fromStrict ByteString
xmldata
  let bScanned :: Text
bScanned = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Name -> Axis
element Name
"BytesScanned" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      bProcessed :: Text
bProcessed = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Name -> Axis
element Name
"BytesProcessed" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      bReturned :: Text
bReturned = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Cursor
r Cursor -> (Cursor -> [Text]) -> [Text]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Name -> Axis
element Name
"BytesReturned" Axis -> (Cursor -> [Text]) -> Cursor -> [Text]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
  Int64 -> Int64 -> Int64 -> Progress
Progress
    (Int64 -> Int64 -> Int64 -> Progress)
-> m Int64 -> m (Int64 -> Int64 -> Progress)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> m Int64
forall (m :: * -> *) a. (MonadIO m, Integral a) => Text -> m a
parseDecimal Text
bScanned
    m (Int64 -> Int64 -> Progress) -> m Int64 -> m (Int64 -> Progress)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> m Int64
forall (m :: * -> *) a. (MonadIO m, Integral a) => Text -> m a
parseDecimal Text
bProcessed
    m (Int64 -> Progress) -> m Int64 -> m Progress
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> m Int64
forall (m :: * -> *) a. (MonadIO m, Integral a) => Text -> m a
parseDecimal Text
bReturned