{- |
Copyright:  (c) 2021-2022 Kowainik
SPDX-License-Identifier: MPL-2.0
Maintainer:  Kowainik <xrom.xkov@gmail.com>
Stability:   Stable
Portability: Portable

Useful combinators to work with the data structures from @containers@ package
and 'Slist' together.

@since 0.2.0.0
-}
module Slist.Containers
    ( -- * Map
      mapToVals
    , mapToKeys
    , mapToPairs

      -- * Set
    , setToSlist
    ) where

import Data.Map.Strict (Map)
import Data.Set (Set)

import Slist.Size (Size (..))
import Slist.Type (Slist (..))

import qualified Data.Map.Strict as Map
import qualified Data.Set as Set


{- | @O(n)@.
Returns a 'Slist' of all values of the map in the ascending order of their keys.

@since 0.2.0.0
-}
mapToVals :: Map k v -> Slist v
mapToVals :: forall k v. Map k v -> Slist v
mapToVals Map k v
m = Slist
    { sList :: [v]
sList = Map k v -> [v]
forall k a. Map k a -> [a]
Map.elems Map k v
m
    , sSize :: Size
sSize = Int -> Size
Size (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ Map k v -> Int
forall k a. Map k a -> Int
Map.size Map k v
m
    }
{-# INLINE mapToVals #-}

{- | @O(n)@.
Returns a 'Slist' of all keys of the map in the ascending order.

@since 0.2.0.0
-}
mapToKeys :: Map k v -> Slist k
mapToKeys :: forall k v. Map k v -> Slist k
mapToKeys Map k v
m = Slist
    { sList :: [k]
sList = Map k v -> [k]
forall k a. Map k a -> [k]
Map.keys Map k v
m
    , sSize :: Size
sSize = Int -> Size
Size (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ Map k v -> Int
forall k a. Map k a -> Int
Map.size Map k v
m
    }
{-# INLINE mapToKeys #-}

{- | @O(n)@.
Returns a 'Slist' of all key-value pairs of the map in the ascending order of their keys.

@since 0.2.0.0
-}
mapToPairs :: Map k v -> Slist (k, v)
mapToPairs :: forall k v. Map k v -> Slist (k, v)
mapToPairs Map k v
m = Slist
    { sList :: [(k, v)]
sList = Map k v -> [(k, v)]
forall k a. Map k a -> [(k, a)]
Map.toAscList Map k v
m
    , sSize :: Size
sSize = Int -> Size
Size (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ Map k v -> Int
forall k a. Map k a -> Int
Map.size Map k v
m
    }
{-# INLINE mapToPairs #-}

{- | @O(n)@.
Returns a 'Slist' of all elements of the set in the ascending order.

@since 0.2.0.0
-}
setToSlist :: Set a -> Slist a
setToSlist :: forall a. Set a -> Slist a
setToSlist Set a
s = Slist
    { sList :: [a]
sList = Set a -> [a]
forall a. Set a -> [a]
Set.elems Set a
s
    , sSize :: Size
sSize = Int -> Size
Size (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ Set a -> Int
forall a. Set a -> Int
Set.size Set a
s
    }
{-# INLINE setToSlist #-}