packages feed

hw-ip-2.3.1.1: app/App/Commands/TextToWord.hs

{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}

module App.Commands.TextToWord
  ( cmdTextToWord
  ) where

import Control.Lens
import Data.Generics.Product.Any
import Data.Maybe                (catMaybes)
import Data.Semigroup            ((<>))
import Options.Applicative       hiding (columns)
import Text.Read

import qualified App.Commands.Types                as Z
import qualified Data.Binary.Builder               as B
import qualified Data.ByteString.Lazy              as LBS
import qualified HaskellWorks.Data.Network.Ip.Ipv4 as IPv4
import qualified System.IO                         as IO

{-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}
{-# ANN module ("HLint: ignore Redundant do"        :: String) #-}

runTextToWord :: Z.TextToWordOptions -> IO ()
runTextToWord opts = do
  contents <- IO.readFile (opts ^. the @"input")
  let as  = lines contents
  let ips = catMaybes (fmap (readMaybe @IPv4.IpAddress) as)
  let ws  = fmap (^. the @"word") ips
  LBS.writeFile (opts ^. the @"output") (B.toLazyByteString (foldMap B.putWord32le ws))

optsTextToWord :: Parser Z.TextToWordOptions
optsTextToWord = Z.TextToWordOptions
  <$> strOption
        (   long "input"
        <>  short 'i'
        <>  help "Input line seprate IP addresses in text"
        <>  metavar "FILE"
        )
  <*> strOption
        (   long "output"
        <>  short 'o'
        <>  help "Packed IPs as little-endian Word32s"
        <>  metavar "FILE"
        )

cmdTextToWord :: Mod CommandFields (IO ())
cmdTextToWord = command "text-to-word"  $ flip info idm $ runTextToWord <$> optsTextToWord