module Turtle.Options.Scale
( Scale(..)
, optScale
, defScaleHelp
, scale
) where
import Turtle (ArgName, ShortName, HelpMessage, opt)
import Data.Optional (Optional)
import qualified Turtle
import qualified Data.Text as Text
import Control.Applicative ((<$>), (<*>), (*>), (<*))
import Text.Parsec
import Turtle.Options.Parsers (Parser, percent, float)
data Scale =
Percentage Float
| Size (Int, Int)
| Width Int
| Height Int
deriving (Eq, Show)
defScaleHelp :: Optional HelpMessage
defScaleHelp = "Scale option. SCALE can be a percentage (20%), a size (480x320), a width (480x) or a height (x320)"
width :: Parser Scale
width = Width . read <$> try (many1 digit <* char 'x')
height :: Parser Scale
height = Height . read <$> try (char 'x' *> many1 digit)
size :: Parser Scale
size = Size <$> try (do
w <- read <$> many1 digit <* char 'x'
h <- read <$> many1 digit
return (w, h))
percentage :: Parser Scale
percentage = choice [try p, f]
where
f = do
v <- float
case v < 0 of
True -> error "Error parsing scale: can't have a negative scale"
False -> return $ Percentage v
p = do
v <- percent
case v < 0 of
True -> error "Error parsing scale percentage: can't have a negative value"
False -> return $ Percentage v
scale :: Parser Scale
scale = choice [size, percentage, width, height]
readScale :: String -> Maybe Scale
readScale str = case (parse scale "Scale" str) of
Left err -> error $ "Error parsing scale: " ++ (show err)
Right s -> Just s
optScale :: ArgName -> ShortName -> Optional HelpMessage -> Turtle.Parser Scale
optScale = opt (readScale . Text.unpack)