-- |
-- Module: NetSpider.RPL.JSONUtil
-- Description: 
-- Maintainer: Toshio Ito <debug.ito@gmail.com>
--
-- __This is an internal module. End-users should not use it.__
module NetSpider.RPL.JSONUtil
  ( optSnake,
    optCombinedNode,
    optCombinedLink
  ) where

import Control.Applicative ((*>), (<*), (<|>))
import qualified Data.Aeson as Aeson
import Data.Char (isUpper, toLower)
import qualified Text.Regex.Applicative as RE

toSnake :: String -> String
toSnake :: String -> String
toSnake = RE Char String -> String -> String
forall s. RE s [s] -> [s] -> [s]
RE.replace (RE Char String -> String -> String)
-> RE Char String -> String -> String
forall a b. (a -> b) -> a -> b
$ (Char -> Maybe String) -> RE Char String
forall s a. (s -> Maybe a) -> RE s a
RE.msym (\Char
c -> if Char -> Bool
isUpper Char
c then String -> Maybe String
forall a. a -> Maybe a
Just [Char
'_', Char -> Char
toLower Char
c] else Maybe String
forall a. Maybe a
Nothing)

optSnake :: Aeson.Options
optSnake :: Options
optSnake = Options
Aeson.defaultOptions { fieldLabelModifier :: String -> String
Aeson.fieldLabelModifier = String -> String
toSnake }

optCombinedNode :: Aeson.Options
optCombinedNode :: Options
optCombinedNode = Options
Aeson.defaultOptions { fieldLabelModifier :: String -> String
Aeson.fieldLabelModifier = String -> String
modifier }
  where
    modifier :: String -> String
modifier = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RE Char String -> String -> String
forall s. RE s [s] -> [s] -> [s]
RE.replace ((String -> String) -> RE Char String -> RE Char String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> String -> String
forall a b. a -> b -> a
const String
"") (RE Char String -> RE Char String)
-> RE Char String -> RE Char String
forall a b. (a -> b) -> a -> b
$ String -> RE Char String
forall a. Eq a => [a] -> RE a [a]
RE.string String
"attrs")

optCombinedLink :: Aeson.Options
optCombinedLink :: Options
optCombinedLink =
  Options
Aeson.defaultOptions
  { constructorTagModifier :: String -> String
Aeson.constructorTagModifier = String -> String
tag_modifier,
    sumEncoding :: SumEncoding
Aeson.sumEncoding =
      TaggedObject :: String -> String -> SumEncoding
Aeson.TaggedObject
      { tagFieldName :: String
Aeson.tagFieldName = String
"link_type",
        contentsFieldName :: String
Aeson.contentsFieldName = String
"link"
      }
  }
  where
    tag_modifier :: String -> String
tag_modifier = RE Char String -> String -> String
forall s. RE s [s] -> [s] -> [s]
RE.replace RE Char String
regex
    regex :: RE Char String
regex = (String -> String) -> RE Char String -> RE Char String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower) (String -> RE Char String
forall a. Eq a => [a] -> RE a [a]
RE.string String
"Combined" RE Char String -> RE Char String -> RE Char String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (String -> RE Char String
forall a. Eq a => [a] -> RE a [a]
RE.string String
"DIO" RE Char String -> RE Char String -> RE Char String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> RE Char String
forall a. Eq a => [a] -> RE a [a]
RE.string String
"DAO") RE Char String -> RE Char String -> RE Char String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> RE Char String
forall a. Eq a => [a] -> RE a [a]
RE.string String
"Link")