packages feed

squeeze-1.0.2.0: src/Squeeze/Data/CommandOptions.hs

{-
	Copyright (C) 2010 Dr. Alistair Ward

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
-}
{- |
 [@AUTHOR@]	Dr. Alistair Ward

 [@DESCRIPTION@]

	* Defines options for program-operation, which are expected to be set from the command-line.

	* Defines an appropriate default value.

	* Self-validates.
-}

module Squeeze.Data.CommandOptions(
-- * Types
-- ** Data-types
	CommandOptions(
--		MkCommandOptions,
		bisectionRatio,
		maximumBytes,
		minimumUsageRatio,
		verbose
	),
-- * Functions
	fileSizeBounds,
	minimumBytes,
	setVerbose
) where

import qualified	Factory.Data.Interval	as Data.Interval
import qualified	Squeeze.Data.File	as Data.File
import qualified	ToolShed.Defaultable	as Defaultable
import qualified	ToolShed.SelfValidate	as SelfValidate

{- |
	* Declare a record to contain command-line options.

	* This data-type is polymorphic, but the constraint is only applied at the level of individual functions.
-}
data CommandOptions ratio	= MkCommandOptions {
	bisectionRatio		:: ratio,		-- ^ The file-list is bisected at LHS/Total, and combinations from the LHS are concatenated with each of those from the RHS.
	maximumBytes		:: Data.File.FileSize,	-- ^ The maximum space (in bytes) available in which to store a subset of the specified files.
	minimumUsageRatio	:: ratio,		-- ^ The minimum acceptable usage of 'maximumBytes'.
	verbose			:: Bool			-- ^ Output ancillary information.
} deriving Show

instance Fractional f => Defaultable.Defaultable (CommandOptions f)	where
	defaultValue	= MkCommandOptions {
		bisectionRatio		= recip 2,	--Bisection the file-list into equal halves.
		maximumBytes		= 4700000000,	--DVD-size; just under 4.4GiB.
		minimumUsageRatio	= 99 / 100,	--99% full.
		verbose			= False
	}

instance (Num f, Ord f) => SelfValidate.SelfValidator (CommandOptions f)	where
	isValid commandOptions	= all ($ commandOptions) [
		(>= 0) . bisectionRatio,
		(<= 1) . bisectionRatio,
		(>= 0) . maximumBytes,
		(>= 0) . minimumUsageRatio,
		(<= 1) . minimumUsageRatio
	 ]

-- | Derives the minimum number of bytes, from other options.
minimumBytes :: RealFrac f => CommandOptions f -> Data.File.FileSize
minimumBytes commandOptions	= floor $ minimumUsageRatio commandOptions * realToFrac (maximumBytes commandOptions)

-- | The permissible bounds on the size of a file, or set of files.
fileSizeBounds :: RealFrac f => CommandOptions f -> Data.Interval.Interval Data.File.FileSize
fileSizeBounds commandOptions	= (minimumBytes commandOptions, maximumBytes commandOptions)

-- | Mutator.
setVerbose :: CommandOptions f -> CommandOptions f
setVerbose commandOptions	= commandOptions { verbose = True }