... by deleting most files. By the theory of evolution, the remaining ones will get stronger over the next commits. That's how it works, isn't it?
77 lines
2.1 KiB
Haskell
77 lines
2.1 KiB
Haskell
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
module Mima.Format
|
|
( ToText(..)
|
|
, toBin
|
|
, toDec
|
|
, toHex
|
|
, negative
|
|
, chunkedBy
|
|
, chunkyBin
|
|
, chunkyDec
|
|
, chunkyHex
|
|
, fixWidthBin
|
|
, fixWidthDec
|
|
, fixWidthHex
|
|
) where
|
|
|
|
import qualified Data.Text as T
|
|
import Numeric
|
|
|
|
-- | A class for types that can be converted to 'T.Text'.
|
|
--
|
|
-- This class does not mean to convert elements to text in a
|
|
-- standardized way. It is just to reduce the clutter of functions
|
|
-- with names like @somethingToText@.
|
|
--
|
|
-- Only create an instance of this class when there is an obvious,
|
|
-- preferrable way of converting something to text! If there are
|
|
-- multiple "obvious" options, create no instance of this class and
|
|
-- instead name the functions individually.
|
|
class ToText a where
|
|
toText :: a -> T.Text
|
|
|
|
toBin :: (Integral a, Show a) => a -> T.Text
|
|
toBin a
|
|
| a < 0 = "-" <> toBin (- a)
|
|
toBin 0 = "0"
|
|
toBin a = T.reverse $ T.pack $ toBin' a
|
|
where
|
|
toBin' :: (Integral a, Show a) => a -> String
|
|
toBin' 0 = []
|
|
toBin' n = (if n `mod` 2 == 0 then '0' else '1') : toBin' (n `div` 2)
|
|
|
|
toDec :: (Integral a, Show a ) => a -> T.Text
|
|
toDec = T.pack . show
|
|
|
|
toHex :: (Integral a, Show a) => a -> T.Text
|
|
toHex a = T.pack $ showHex a ""
|
|
|
|
-- | @'negative' a@ interprets @a@ as @a - 'maxBound' - 1@ if @a@ is greater
|
|
-- than @'maxBound' `div` 2@, and as a positive number otherwise. 'minBound' is
|
|
-- ignored.
|
|
negative :: (Integral a, Bounded a, Show a) => (a -> T.Text) -> a -> T.Text
|
|
negative f a
|
|
| a > maxBound `div` 2 = "-" <> f (-(a - maxBound - 1))
|
|
| otherwise = f a
|
|
|
|
chunkedBy :: T.Text -> Int -> T.Text -> T.Text
|
|
chunkedBy sep n = T.reverse . T.intercalate sep . T.chunksOf n . T.reverse
|
|
|
|
chunkyBin :: T.Text -> T.Text
|
|
chunkyBin = chunkedBy " " 4
|
|
|
|
chunkyDec :: T.Text -> T.Text
|
|
chunkyDec = chunkedBy " " 3
|
|
|
|
chunkyHex :: T.Text -> T.Text
|
|
chunkyHex = chunkedBy " " 2
|
|
|
|
fixWidthBin :: Int -> T.Text -> T.Text
|
|
fixWidthBin n = T.justifyRight n '0'
|
|
|
|
fixWidthDec :: Int -> T.Text -> T.Text
|
|
fixWidthDec n = T.justifyRight n ' '
|
|
|
|
fixWidthHex :: Int -> T.Text -> T.Text
|
|
fixWidthHex n = T.justifyRight n '0'
|