<commit_before>{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell       #-}

module ZoomHub.Types.ContentMIME
  ( ContentMIME
  , ContentMIME'(ContentMIME)
  , ContentMIMEColumn
  , pContentMIME
  , unContentMIME
  ) where

import           Codec.MIME.Parse                     (parseMIMEType)
import           Codec.MIME.Type                      (Type, showType)
import           Data.Aeson                           (ToJSON, Value (String),
                                                       toJSON)
import           Data.Profunctor.Product.TH           (makeAdaptorAndInstance)
import qualified Data.Text                            as T
import qualified Database.PostgreSQL.Simple.FromField as PGS
import           Database.SQLite.Simple               (SQLData (SQLText))
import           Database.SQLite.Simple.FromField     (FromField, ResultError (ConversionFailed),
                                                       fromField, returnError)
import           Database.SQLite.Simple.Internal      (Field (Field))
import           Database.SQLite.Simple.Ok            (Ok (Ok))
import           Database.SQLite.Simple.ToField       (ToField, toField)
import           Opaleye                              (Column, Nullable, PGText,
                                                       QueryRunnerColumnDefault,
                                                       fieldQueryRunnerColumn,
                                                       queryRunnerColumnDefault)


newtype ContentMIME' a = ContentMIME { unContentMIME :: a } deriving (Eq, Show)
type ContentMIME = ContentMIME' Type

toText :: ContentMIME -> T.Text
toText = showType . unContentMIME

-- SQLite
instance ToField ContentMIME where
  toField = SQLText . toText

instance FromField ContentMIME where
  fromField f@(Field (SQLText t) _) =
    case parseMIMEType t of
      Just r  -> Ok (ContentMIME r)
      Nothing -> returnError ConversionFailed f
        ("invalid content MIME type: " ++ T.unpack t)
  fromField f = returnError ConversionFailed f "invalid MIME type"

-- JSON
instance ToJSON ContentMIME where
  toJSON = String . toText

-- PostgreSQL
type ContentMIMEColumn = ContentMIME' (Column (Nullable PGText))
$(makeAdaptorAndInstance "pContentMIME" ''ContentMIME')

instance PGS.FromField ContentMIME where
  fromField f mdata = PGS.fromField f mdata >>= parseContentMIME
    where
      parseContentMIME t = case parseMIMEType t of
        Just r  -> return (ContentMIME r)
        Nothing -> PGS.returnError PGS.ConversionFailed f "invalid content MIME type"

instance QueryRunnerColumnDefault PGText ContentMIME where
  queryRunnerColumnDefault = fieldQueryRunnerColumn<commit_msg>Implement `Default Constant` instance for `ContentMIME`<commit_after>{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell       #-}

module ZoomHub.Types.ContentMIME
  ( ContentMIME
  , ContentMIME'(ContentMIME)
  , ContentMIMEColumn
  , pContentMIME
  , unContentMIME
  ) where

import           Codec.MIME.Parse                     (parseMIMEType)
import           Codec.MIME.Type                      (Type, showType)
import           Data.Aeson                           (ToJSON, Value (String),
                                                       toJSON)
import           Data.Profunctor.Product.Default      (Default, def)
import           Data.Profunctor.Product.TH           (makeAdaptorAndInstance)
import qualified Data.Text                            as T
import qualified Database.PostgreSQL.Simple.FromField as PGS
import           Database.SQLite.Simple               (SQLData (SQLText))
import           Database.SQLite.Simple.FromField     (FromField, ResultError (ConversionFailed),
                                                       fromField, returnError)
import           Database.SQLite.Simple.Internal      (Field (Field))
import           Database.SQLite.Simple.Ok            (Ok (Ok))
import           Database.SQLite.Simple.ToField       (ToField, toField)
import           Opaleye                              (Column,
                                                       Constant (Constant),
                                                       Nullable, PGText,
                                                       QueryRunnerColumnDefault,
                                                       fieldQueryRunnerColumn,
                                                       pgStrictText,
                                                       queryRunnerColumnDefault)


newtype ContentMIME' a = ContentMIME { unContentMIME :: a } deriving (Eq, Show)
type ContentMIME = ContentMIME' Type

toText :: ContentMIME -> T.Text
toText = showType . unContentMIME

-- SQLite
instance ToField ContentMIME where
  toField = SQLText . toText

instance FromField ContentMIME where
  fromField f@(Field (SQLText t) _) =
    case parseMIMEType t of
      Just r  -> Ok (ContentMIME r)
      Nothing -> returnError ConversionFailed f
        ("invalid content MIME type: " ++ T.unpack t)
  fromField f = returnError ConversionFailed f "invalid MIME type"

-- JSON
instance ToJSON ContentMIME where
  toJSON = String . toText

-- PostgreSQL
type ContentMIMEColumn = ContentMIME' (Column (Nullable PGText))
$(makeAdaptorAndInstance "pContentMIME" ''ContentMIME')

instance PGS.FromField ContentMIME where
  fromField f mdata = PGS.fromField f mdata >>= parseContentMIME
    where
      parseContentMIME t = case parseMIMEType t of
        Just r  -> return (ContentMIME r)
        Nothing -> PGS.returnError PGS.ConversionFailed f "invalid content MIME type"

instance QueryRunnerColumnDefault PGText ContentMIME where
  queryRunnerColumnDefault = fieldQueryRunnerColumn

instance Default Constant ContentMIME (Column PGText) where
  def = Constant $ pgStrictText . toText
{'fraction_non_alphanumeric': 0.06539833531510107, 'fraction_numerical': 0.0, 'mean_word_length': 1.8416988416988418, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4801805', 'n_tokens_mistral': 1475, 'n_tokens_neox': 1467, 'n_words': 402}