{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK show-extensions #-}

-- |
--
-- Module      : Network.AWS.ARN.S3
-- Copyright   : (C) 2020-2023 Bellroy Pty Ltd
-- License     : BSD-3-Clause
-- Maintainer  : Bellroy Tech Team <haskell@bellroy.com>
-- Stability   : experimental
module Network.AWS.ARN.S3
  ( -- * S3 Object
    Object (..),
    parseObject,
    renderObject,

    -- * S3 Bucket
    Bucket (..),
    parseBucket,
    renderBucket,

    -- ** Prisms
    _Object,
    _Bucket,
  )
where

import Data.Hashable (Hashable)
import Data.Text (Text)
import qualified Data.Text as T
import GHC.Generics (Generic)
import Lens.Micro.Pro (Prism', prism')

-- $setup
-- >>> :set -XOverloadedStrings
-- >>> import Lens.Micro.Pro ((^?))

-- | An AWS S3 object, made of a bucket and an object key.
--
-- >>> "bucket-name/my/object" ^? _Object
-- Just (Object {bucket = Bucket {bucketName = "bucket-name"}, objectKey = "my/object"})
--
-- >>> "bucket-name" ^? _Object
-- Nothing
--
-- >>> bucket <$> "bucket-name/my/object" ^? _Object
-- Just (Bucket {bucketName = "bucket-name"})
--
-- @since 0.3.1.0
data Object = Object
  { Object -> Bucket
bucket :: Bucket,
    Object -> Text
objectKey :: Text
  }
  deriving (Object -> Object -> Bool
(Object -> Object -> Bool)
-> (Object -> Object -> Bool) -> Eq Object
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Object -> Object -> Bool
== :: Object -> Object -> Bool
$c/= :: Object -> Object -> Bool
/= :: Object -> Object -> Bool
Eq, Eq Object
Eq Object =>
(Object -> Object -> Ordering)
-> (Object -> Object -> Bool)
-> (Object -> Object -> Bool)
-> (Object -> Object -> Bool)
-> (Object -> Object -> Bool)
-> (Object -> Object -> Object)
-> (Object -> Object -> Object)
-> Ord Object
Object -> Object -> Bool
Object -> Object -> Ordering
Object -> Object -> Object
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Object -> Object -> Ordering
compare :: Object -> Object -> Ordering
$c< :: Object -> Object -> Bool
< :: Object -> Object -> Bool
$c<= :: Object -> Object -> Bool
<= :: Object -> Object -> Bool
$c> :: Object -> Object -> Bool
> :: Object -> Object -> Bool
$c>= :: Object -> Object -> Bool
>= :: Object -> Object -> Bool
$cmax :: Object -> Object -> Object
max :: Object -> Object -> Object
$cmin :: Object -> Object -> Object
min :: Object -> Object -> Object
Ord, Eq Object
Eq Object =>
(Int -> Object -> Int) -> (Object -> Int) -> Hashable Object
Int -> Object -> Int
Object -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Object -> Int
hashWithSalt :: Int -> Object -> Int
$chash :: Object -> Int
hash :: Object -> Int
Hashable, Int -> Object -> ShowS
[Object] -> ShowS
Object -> String
(Int -> Object -> ShowS)
-> (Object -> String) -> ([Object] -> ShowS) -> Show Object
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Object -> ShowS
showsPrec :: Int -> Object -> ShowS
$cshow :: Object -> String
show :: Object -> String
$cshowList :: [Object] -> ShowS
showList :: [Object] -> ShowS
Show, (forall x. Object -> Rep Object x)
-> (forall x. Rep Object x -> Object) -> Generic Object
forall x. Rep Object x -> Object
forall x. Object -> Rep Object x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Object -> Rep Object x
from :: forall x. Object -> Rep Object x
$cto :: forall x. Rep Object x -> Object
to :: forall x. Rep Object x -> Object
Generic)

-- | @since 0.3.1.0
parseObject :: Text -> Maybe Object
parseObject :: Text -> Maybe Object
parseObject Text
t = case HasCallStack => Text -> Text -> (Text, Text)
Text -> Text -> (Text, Text)
T.breakOn Text
"/" Text
t of
  (Text
"", Text
_) -> Maybe Object
forall a. Maybe a
Nothing
  (Text
_, Text
"") -> Maybe Object
forall a. Maybe a
Nothing
  (Text
bucketName, Text
object) -> Object -> Maybe Object
forall a. a -> Maybe a
Just (Object -> Maybe Object) -> Object -> Maybe Object
forall a b. (a -> b) -> a -> b
$ Bucket -> Text -> Object
Object (Text -> Bucket
Bucket Text
bucketName) (Int -> Text -> Text
T.drop Int
1 Text
object)

-- | @since 0.3.1.0
renderObject :: Object -> Text
renderObject :: Object -> Text
renderObject Object {Bucket
$sel:bucket:Object :: Object -> Bucket
bucket :: Bucket
bucket, Text
$sel:objectKey:Object :: Object -> Text
objectKey :: Text
objectKey} =
  Bucket -> Text
renderBucket Bucket
bucket Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
objectKey

-- | @since 0.3.1.0
_Object :: Prism' Text Object
_Object :: Prism' Text Object
_Object = (Object -> Text) -> (Text -> Maybe Object) -> Prism' Text Object
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' Object -> Text
renderObject Text -> Maybe Object
parseObject

-- | An AWS S3 bucket, without an object key.
--
-- >>> "bucket-name" ^? _Bucket
-- Just (Bucket {bucketName = "bucket-name"})
--
-- >>> "bucket-name/my/object" ^? _Bucket
-- Nothing
--
-- >>> let b = Bucket "my-bucket" in renderObject . Object b <$> ["obj1", "obj2"]
-- ["my-bucket/obj1","my-bucket/obj2"]
--
-- @since 0.3.1.0
newtype Bucket = Bucket {Bucket -> Text
bucketName :: Text}
  deriving stock (Bucket -> Bucket -> Bool
(Bucket -> Bucket -> Bool)
-> (Bucket -> Bucket -> Bool) -> Eq Bucket
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Bucket -> Bucket -> Bool
== :: Bucket -> Bucket -> Bool
$c/= :: Bucket -> Bucket -> Bool
/= :: Bucket -> Bucket -> Bool
Eq, Eq Bucket
Eq Bucket =>
(Bucket -> Bucket -> Ordering)
-> (Bucket -> Bucket -> Bool)
-> (Bucket -> Bucket -> Bool)
-> (Bucket -> Bucket -> Bool)
-> (Bucket -> Bucket -> Bool)
-> (Bucket -> Bucket -> Bucket)
-> (Bucket -> Bucket -> Bucket)
-> Ord Bucket
Bucket -> Bucket -> Bool
Bucket -> Bucket -> Ordering
Bucket -> Bucket -> Bucket
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Bucket -> Bucket -> Ordering
compare :: Bucket -> Bucket -> Ordering
$c< :: Bucket -> Bucket -> Bool
< :: Bucket -> Bucket -> Bool
$c<= :: Bucket -> Bucket -> Bool
<= :: Bucket -> Bucket -> Bool
$c> :: Bucket -> Bucket -> Bool
> :: Bucket -> Bucket -> Bool
$c>= :: Bucket -> Bucket -> Bool
>= :: Bucket -> Bucket -> Bool
$cmax :: Bucket -> Bucket -> Bucket
max :: Bucket -> Bucket -> Bucket
$cmin :: Bucket -> Bucket -> Bucket
min :: Bucket -> Bucket -> Bucket
Ord, Int -> Bucket -> ShowS
[Bucket] -> ShowS
Bucket -> String
(Int -> Bucket -> ShowS)
-> (Bucket -> String) -> ([Bucket] -> ShowS) -> Show Bucket
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Bucket -> ShowS
showsPrec :: Int -> Bucket -> ShowS
$cshow :: Bucket -> String
show :: Bucket -> String
$cshowList :: [Bucket] -> ShowS
showList :: [Bucket] -> ShowS
Show, (forall x. Bucket -> Rep Bucket x)
-> (forall x. Rep Bucket x -> Bucket) -> Generic Bucket
forall x. Rep Bucket x -> Bucket
forall x. Bucket -> Rep Bucket x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Bucket -> Rep Bucket x
from :: forall x. Bucket -> Rep Bucket x
$cto :: forall x. Rep Bucket x -> Bucket
to :: forall x. Rep Bucket x -> Bucket
Generic)
  deriving anyclass (Eq Bucket
Eq Bucket =>
(Int -> Bucket -> Int) -> (Bucket -> Int) -> Hashable Bucket
Int -> Bucket -> Int
Bucket -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Bucket -> Int
hashWithSalt :: Int -> Bucket -> Int
$chash :: Bucket -> Int
hash :: Bucket -> Int
Hashable)

-- | @since 0.3.1.0
parseBucket :: Text -> Maybe Bucket
parseBucket :: Text -> Maybe Bucket
parseBucket Text
t = case HasCallStack => Text -> Text -> (Text, Text)
Text -> Text -> (Text, Text)
T.breakOn Text
"/" Text
t of
  (Text
bucket, Text
"") -> Bucket -> Maybe Bucket
forall a. a -> Maybe a
Just (Bucket -> Maybe Bucket) -> Bucket -> Maybe Bucket
forall a b. (a -> b) -> a -> b
$ Text -> Bucket
Bucket Text
bucket
  (Text, Text)
_ -> Maybe Bucket
forall a. Maybe a
Nothing

-- | @since 0.3.1.0
renderBucket :: Bucket -> Text
renderBucket :: Bucket -> Text
renderBucket Bucket {Text
$sel:bucketName:Bucket :: Bucket -> Text
bucketName :: Text
bucketName} = Text
bucketName

-- | @since 0.3.1.0
_Bucket :: Prism' Text Bucket
_Bucket :: Prism' Text Bucket
_Bucket = (Bucket -> Text) -> (Text -> Maybe Bucket) -> Prism' Text Bucket
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' Bucket -> Text
renderBucket Text -> Maybe Bucket
parseBucket