-- |
-- Module      :  Data.Lists.FLines
-- Copyright   :  (c) OleksandrZhabenko 2020-2023
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  oleksandr.zhabenko@yahoo.com
--
-- Additional data and structures to some 'String'-related lists.
--

{-# LANGUAGE CPP, FlexibleInstances, MultiParamTypeClasses, NoImplicitPrelude #-}

module Data.Lists.FLines where

import GHC.Base
import Data.String
import Text.Show
import GHC.Num
import GHC.List (null)
import System.IO

-- | Auxiliary printing function to define the line ending needed to be shown and printed. Is primarily defined in the @uniqueness-periods-vector-general@ package (https://hackage.haskell.org/package/uniqueness-periods-vector-general).
newLineEnding :: String
newLineEnding :: String
newLineEnding
  | Newline
nativeNewline forall a. Eq a => a -> a -> Bool
== Newline
LF = String
"\n"
  | Bool
otherwise = String
"\r\n"

data FLines a = F1 a | FL [a] deriving FLines a -> FLines a -> Bool
forall a. Eq a => FLines a -> FLines a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FLines a -> FLines a -> Bool
$c/= :: forall a. Eq a => FLines a -> FLines a -> Bool
== :: FLines a -> FLines a -> Bool
$c== :: forall a. Eq a => FLines a -> FLines a -> Bool
Eq

type Flines = FLines String

-- | Is intended to be printed and so adds the new line ending.
instance Show (FLines String) where
  show :: FLines String -> String
show (F1 String
xs) = forall a. Monoid a => [a] -> a
mconcat [String
xs, String
newLineEnding]
  show (FL (String
xs:[String]
xss)) = forall a. Monoid a => [a] -> a
mconcat (String
xsforall a. a -> [a] -> [a]
:String
newLineEndingforall a. a -> [a] -> [a]
:[forall a. Show a => a -> String
show (forall a. [a] -> FLines a
FL [String]
xss)])
  show FLines String
_ = String
newLineEnding

class GetN a b where
  getN :: Int -> a -> Maybe b

instance GetN (FLines String) String where
  getN :: Int -> FLines String -> Maybe String
getN Int
n (F1 String
xs)
    | forall a. [a] -> Bool
null String
xs = forall a. Maybe a
Nothing
    | Int
n forall a. Eq a => a -> a -> Bool
== Int
1 = forall a. a -> Maybe a
Just String
xs
    | Bool
otherwise = forall a. Maybe a
Nothing
  getN Int
n (FL (String
xs:[String]
xss))
   | Int
n forall a. Eq a => a -> a -> Bool
== Int
1 = if forall a. [a] -> Bool
null String
xs then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just String
xs
   | forall a. Ord a => a -> a -> Ordering
compare Int
n Int
1 forall a. Eq a => a -> a -> Bool
== Ordering
LT = forall a. Maybe a
Nothing
   | Bool
otherwise = forall a b. GetN a b => Int -> a -> Maybe b
getN (Int
n forall a. Num a => a -> a -> a
- Int
1) (forall a. [a] -> FLines a
FL [String]
xss)
  getN Int
_ FLines String
_ = forall a. Maybe a
Nothing

class GetNTrans a b where
  getNT :: Int -> (b -> b) -> a -> Maybe b

instance GetNTrans (FLines String) String where
  getNT :: Int -> ShowS -> FLines String -> Maybe String
getNT Int
n ShowS
g (F1 String
xs)
    | forall a. [a] -> Bool
null (ShowS
g String
xs) = forall a. Maybe a
Nothing
    | Int
n forall a. Eq a => a -> a -> Bool
== Int
1  = forall a. a -> Maybe a
Just (ShowS
g String
xs)
    | Bool
otherwise = forall a. Maybe a
Nothing
  getNT Int
n ShowS
g (FL (String
xs:[String]
xss))
   | Int
n forall a. Eq a => a -> a -> Bool
== Int
1 = if forall a. [a] -> Bool
null (ShowS
g String
xs) then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (ShowS
g String
xs)
   | forall a. Ord a => a -> a -> Ordering
compare Int
n Int
1 forall a. Eq a => a -> a -> Bool
== Ordering
LT = forall a. Maybe a
Nothing
   | Bool
otherwise = forall a b. GetNTrans a b => Int -> (b -> b) -> a -> Maybe b
getNT (Int
n forall a. Num a => a -> a -> a
- Int
1) ShowS
g (forall a. [a] -> FLines a
FL [String]
xss)
  getNT Int
_ ShowS
_ FLines String
_ = forall a. Maybe a
Nothing

class GetTransL a b where
  getTL :: (b -> b) -> a -> b