haskellari / postgresql-simple

Mid-level client library for accessing PostgreSQL from Haskell
Other
88 stars 46 forks source link

Add inet FromField and ToField instances #133

Open JonathanLorimer opened 9 months ago

JonathanLorimer commented 9 months ago

The inet type exists already here

postgresql-binary has examples of encoding and decoding

JonathanLorimer commented 9 months ago

Here is a candidate version that uses postgresql-binary

import Network.IP.Addr
import Database.PostgreSQL.Simple.ToField (ToField (..))
import Database.PostgreSQL.Simple.FromField (FromField (..), Field (..), returnError, ResultError (..))
import PostgreSQL.Binary.Encoding qualified as ENC
import PostgreSQL.Binary.Decoding qualified as DEC
import Database.PostgreSQL.Simple.TypeInfo.Static qualified as TI
import qualified Data.Text as T

instance ToField (NetAddr IP) where
    toField = toField . ENC.encodingBytes . ENC.inet
    {-# INLINE toField #-}

instance FromField (NetAddr IP) where
    fromField f mbs =
      if typeOid f /= TI.uuidOid
      then returnError Incompatible f ""
      else case mbs of
             Nothing -> returnError UnexpectedNull f ""
             Just bs ->
                 case DEC.valueParser DEC.inet bs of
                   Left t -> returnError ConversionFailed f $ "Invalid inet: " <>  T.unpack t
                   Right inet -> pure uuid