{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module DiffRep (
DiffR (..),
) where
import Data.Functor.Identity
import qualified Data.Map as Map
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Vector (Vector)
import Data.Void
import Control.Lens
import Refined
import Category
import Deck
import Diff
import Util
newtype DiffR a = DiffR {unDiffR :: Text}
deriving stock (Show)
type instance DeckRep DiffR = Text
quote :: Text -> Text
quote content =
let escaped = Text.replace "\"" "\\\"" content
in flip Text.snoc '"' . Text.cons '"' $ escaped
line :: [Text] -> Text
line = Text.stripEnd . Text.unlines
instance DeckSYM DiffR where
empty = DiffR Text.empty
deck = DiffR
add cardname categoryname cardCopies content =
let entry =
[ "A"
, quote $ toText cardname
, Text.pack . show . toNumber @Int $ cardCopies
, quote $ toText categoryname
]
in DiffR $ line [unDiffR content, Text.intercalate " " entry]
remove cardname categoryname content =
let entry =
Text.intercalate
" "
[ "D"
, quote $ toText cardname
, quote $ toText categoryname
]
in DiffR $ line [unDiffR content, entry]
delete cardname content =
let entry =
Text.intercalate
" "
[ "D"
, quote $ toText cardname
]
in DiffR $ line [unDiffR content, entry]
insert card content =
let mappedCategories =
Map.foldrWithKey
( \key category acc ->
Text.intercalate
" "
[Text.pack . show . toNumber @Int $ category ^. copies, quote key]
: acc
)
[]
$ card ^. categories
entry =
Text.intercalate
" "
[ "A"
, quote . toText $ card ^. Deck.name
, Text.cons '[' . flip Text.snoc ']' $ Text.intercalate ", " mappedCategories
]
in DiffR $ line [unDiffR content, entry]
instance HunkSYM DiffR where
chunk cardname changes content =
let header = Text.append ">> " (quote $ toText cardname)
hunk = line $ foldr (\ch acc -> Text.append " " (unDiffR ch) : acc ) mempty changes
in DiffR $ Text.unlines [Text.stripEnd $ unDiffR content, Text.empty, header, hunk]
move fromCategory toCategory count =
let entry =
Text.intercalate
" "
[ "M"
, Text.pack . show . toNumber @Int $ count
, quote $ toText fromCategory
, quote $ toText toCategory
]
in DiffR entry
deltaCopies delta categoryname =
let entry =
Text.intercalate
" "
[ Text.pack . show $ delta
, quote $ toText categoryname
]
in DiffR entry