<commit_before>{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE LambdaCase #-}

--------------------------------------------------------------------
-- |
-- Module    : Data.Ruby.Marshal.RubyObject
-- Copyright : (c) <NAME>, 2015
-- License   : MIT
--
-- Maintainer:  <EMAIL>
-- Stability :  experimental
-- Portability: portable
--
-- Core RubyObject data representation.
--
--------------------------------------------------------------------

module Data.Ruby.Marshal.RubyObject (
    module Data.Ruby.Marshal.Encoding
  , module Data.Ruby.Marshal.RubyObject
) where

import Control.Applicative
import Data.Ruby.Marshal.Encoding
import Prelude

import Control.Arrow ((***))

import qualified Data.ByteString as BS
import qualified Data.Map.Strict as DM
import qualified Data.Vector     as V

-- | Representation of a Ruby object.
data RubyObject
  = RNil
    -- ^ represents @nil@
  | RBool                  !Bool
    -- ^ represents @true@ or @false@
  | RFixnum {-# UNPACK #-} !Int
    -- ^ represents a @Fixnum@
  | RArray                 !(V.Vector RubyObject)
    -- ^ represents an @Array@
  | RHash                  !(V.Vector (RubyObject, RubyObject))
    -- ^ represents an @Hash@
  | RIVar                  !(RubyObject, REncoding)
    -- ^ represents an @IVar@
  | RString                !BS.ByteString
    -- ^ represents a @String@
  | RFloat {-# UNPACK #-}  !Float
    -- ^ represents a @Float@
  | RSymbol                !BS.ByteString
    -- ^ represents a @Symbol@
  | RError                 !Error
    -- ^ represents an invalid object
  deriving (Eq, Ord, Show)

-- | Handy type alias for IVars.
type IVar = (BS.ByteString, REncoding)

-- | Convey when unsupported object encountered.
data Error
  = Unsupported
    -- ^ represents an unsupported Ruby object
  deriving (Eq, Ord, Show)

-- | Transform plain Haskell values to RubyObjects and back.
class Rubyable a where
  -- | Takes a plain Haskell value and lifts into RubyObject
  toRuby :: a -> RubyObject
  -- | Takes a RubyObject transforms it into a more general Haskell value.
  fromRuby :: RubyObject -> Maybe a

-- core instances

instance Rubyable RubyObject where
  toRuby = id
  fromRuby = Just

instance Rubyable () where
  toRuby _ = RNil
  fromRuby = \case
    RNil -> Just ()
    _    -> Nothing

instance Rubyable Bool where
  toRuby = RBool
  fromRuby = \case
    RBool x -> Just x
    _       -> Nothing

instance Rubyable Int where
  toRuby = RFixnum
  fromRuby = \case
    RFixnum x -> Just x
    _         -> Nothing

instance Rubyable a => Rubyable (V.Vector a) where
  toRuby = RArray . V.map toRuby
  fromRuby = \case
    RArray x -> V.mapM fromRuby x
    _        -> Nothing

instance (Rubyable a, Rubyable b) => Rubyable (V.Vector (a, b)) where
  toRuby x = RHash $ V.map (toRuby *** toRuby) x
  fromRuby = \case
    RHash x -> V.mapM (\(k, v) -> (,) <$> fromRuby k <*> fromRuby v) x
    _       -> Nothing

instance Rubyable BS.ByteString where
  toRuby = RSymbol
  fromRuby = \case
    RSymbol x -> Just x
    _         -> Nothing

instance Rubyable Float where
  toRuby = RFloat
  fromRuby = \case
    RFloat  x -> Just x
    _         -> Nothing

instance Rubyable (BS.ByteString, REncoding) where
  toRuby (x, y) = RIVar (RString x, y)
  fromRuby = \case
    RIVar (RString x, y) -> Just (x, y)
    _                    -> Nothing

-- nil like

instance Rubyable a => Rubyable (Maybe a) where
  toRuby = \case
    Just x  -> toRuby x
    Nothing -> RNil

  fromRuby = \case
    RNil -> Just Nothing
    x    -> fromRuby x

-- array like

instance Rubyable a => Rubyable [a] where
  toRuby = toRuby . V.fromList
  fromRuby x = V.toList <$> fromRuby x

-- map like

instance (Rubyable a, Rubyable b) => Rubyable [(a, b)] where
  toRuby = toRuby . V.fromList
  fromRuby x = V.toList <$> fromRuby x

instance (Rubyable a, Rubyable b, Ord a) => Rubyable (DM.Map a b) where
  toRuby = toRuby . DM.toList
  fromRuby x = DM.fromList <$> fromRuby x<commit_msg>replace rubyable with ruby.<commit_after>{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE LambdaCase #-}

--------------------------------------------------------------------
-- |
-- Module    : Data.Ruby.Marshal.RubyObject
-- Copyright : (c) <NAME>, 2015
-- License   : MIT
--
-- Maintainer:  <EMAIL>
-- Stability :  experimental
-- Portability: portable
--
-- Core RubyObject data representation.
--
--------------------------------------------------------------------

module Data.Ruby.Marshal.RubyObject (
    module Data.Ruby.Marshal.Encoding
  , module Data.Ruby.Marshal.RubyObject
) where

import Control.Applicative
import Data.Ruby.Marshal.Encoding
import Prelude

import Control.Arrow ((***))

import qualified Data.ByteString as BS
import qualified Data.Map.Strict as DM
import qualified Data.Vector     as V

-- | Representation of a Ruby object.
data RubyObject
  = RNil
    -- ^ represents @nil@
  | RBool                  !Bool
    -- ^ represents @true@ or @false@
  | RFixnum {-# UNPACK #-} !Int
    -- ^ represents a @Fixnum@
  | RArray                 !(V.Vector RubyObject)
    -- ^ represents an @Array@
  | RHash                  !(V.Vector (RubyObject, RubyObject))
    -- ^ represents an @Hash@
  | RIVar                  !(RubyObject, REncoding)
    -- ^ represents an @IVar@
  | RString                !BS.ByteString
    -- ^ represents a @String@
  | RFloat {-# UNPACK #-}  !Float
    -- ^ represents a @Float@
  | RSymbol                !BS.ByteString
    -- ^ represents a @Symbol@
  | RError                 !Error
    -- ^ represents an invalid object
  deriving (Eq, Ord, Show)

-- | Handy type alias for IVars.
type IVar = (BS.ByteString, REncoding)

-- | Convey when unsupported object encountered.
data Error
  = Unsupported
    -- ^ represents an unsupported Ruby object
  deriving (Eq, Ord, Show)

-- | Transform plain Haskell values to RubyObjects and back.
class Ruby a where
  -- | Takes a plain Haskell value and lifts into RubyObject
  toRuby :: a -> RubyObject
  -- | Takes a RubyObject transforms it into a more general Haskell value.
  fromRuby :: RubyObject -> Maybe a

-- core instances

instance Ruby RubyObject where
  toRuby = id
  fromRuby = Just

instance Ruby () where
  toRuby _ = RNil
  fromRuby = \case
    RNil -> Just ()
    _    -> Nothing

instance Ruby Bool where
  toRuby = RBool
  fromRuby = \case
    RBool x -> Just x
    _       -> Nothing

instance Ruby Int where
  toRuby = RFixnum
  fromRuby = \case
    RFixnum x -> Just x
    _         -> Nothing

instance Ruby a => Ruby (V.Vector a) where
  toRuby = RArray . V.map toRuby
  fromRuby = \case
    RArray x -> V.mapM fromRuby x
    _        -> Nothing

instance (Ruby a, Ruby b) => Ruby (V.Vector (a, b)) where
  toRuby x = RHash $ V.map (toRuby *** toRuby) x
  fromRuby = \case
    RHash x -> V.mapM (\(k, v) -> (,) <$> fromRuby k <*> fromRuby v) x
    _       -> Nothing

instance Ruby BS.ByteString where
  toRuby = RSymbol
  fromRuby = \case
    RSymbol x -> Just x
    _         -> Nothing

instance Ruby Float where
  toRuby = RFloat
  fromRuby = \case
    RFloat  x -> Just x
    _         -> Nothing

instance Ruby (BS.ByteString, REncoding) where
  toRuby (x, y) = RIVar (RString x, y)
  fromRuby = \case
    RIVar (RString x, y) -> Just (x, y)
    _                    -> Nothing

-- nil like

instance Ruby a => Ruby (Maybe a) where
  toRuby = \case
    Just x  -> toRuby x
    Nothing -> RNil

  fromRuby = \case
    RNil -> Just Nothing
    x    -> fromRuby x

-- array like

instance Ruby a => Ruby [a] where
  toRuby = toRuby . V.fromList
  fromRuby x = V.toList <$> fromRuby x

-- map like

instance (Ruby a, Ruby b) => Ruby [(a, b)] where
  toRuby = toRuby . V.fromList
  fromRuby x = V.toList <$> fromRuby x

instance (Ruby a, Ruby b, Ord a) => Ruby (DM.Map a b) where
  toRuby = toRuby . DM.toList
  fromRuby x = DM.fromList <$> fromRuby x
{'fraction_non_alphanumeric': 0.14229698962813053, 'fraction_numerical': 0.0010118897040222615, 'mean_word_length': 2.02834163155879, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5983399', 'n_tokens_mistral': 2722, 'n_tokens_neox': 2445, 'n_words': 822}