]> gitweb.michael.orlitzky.com - dead/halcyon.git/blob - src/CommandLine.hs
Whitespace cleanup.
[dead/halcyon.git] / src / CommandLine.hs
1 -- The CommandLine module handles parsing of the command-line options.
2 -- It should more or less be a black box, providing Main with only the
3 -- information it requires.
4
5 module CommandLine
6 ( help_set,
7 help_text,
8 from_email_address,
9 to_email_address,
10 parse_errors,
11 parse_usernames
12 ) where
13
14 import Data.Maybe (isJust, isNothing)
15 import System.Console.GetOpt
16 import System.Environment (getArgs)
17
18
19
20 -- A record containing values for all available options.
21 data Options = Options { opt_help :: Bool,
22 opt_from :: Maybe String,
23 opt_to :: Maybe String }
24
25
26 -- This constructs an instance of Options, with each of its members
27 -- set to default values.
28 default_options :: Options
29 default_options = Options { opt_help = False,
30 opt_from = Nothing,
31 opt_to = Nothing }
32
33
34 -- The options list that we construct associates a function with each
35 -- option. This function is responsible for updating an Options record
36 -- with the appropriate value.
37 --
38 -- For more information and an example of this idiom, see,
39 --
40 -- http://www.haskell.org/haskellwiki/High-level_option_handling_with_GetOpt
41 --
42 options :: [OptDescr (Options -> IO Options)]
43 options =
44 [ Option ['h'][] (NoArg set_help) "Prints this help message.",
45 Option ['t'][] (ReqArg set_to "email_address") "Send tweets TO email_address.",
46 Option ['f'][] (ReqArg set_from "email_address") "Send tweets FROM email_address."
47 ]
48
49
50 set_help :: Options -> IO Options
51 set_help opts = do
52 return opts { opt_help = True }
53
54 set_to :: String -> Options -> IO Options
55 set_to arg opts = do
56 return opts { opt_to = Just arg }
57
58 set_from :: String -> Options -> IO Options
59 set_from arg opts = do
60 return opts { opt_from = Just arg }
61
62
63 -- The usage header.
64 usage :: String
65 usage = "Usage: twat [-t to_address] [-f from_address] <username1> [username2, [username3]...]"
66
67
68 -- The usage header, and all available flags (as generated by GetOpt)
69 help_text :: String
70 help_text = usageInfo usage options
71
72
73 -- Return a list of options.
74 parse_options :: IO Options
75 parse_options = do
76 argv <- getArgs
77 let (actions, _, _) = getOpt Permute options argv
78
79 -- This will execute each of the functions contained in our options
80 -- list, one after another, on a default_options record. The end
81 -- result should be an Options instance with all of its members set
82 -- correctly.
83 opts <- foldl (>>=) (return default_options) actions
84
85 return opts
86
87
88 username_errors :: IO [String]
89 username_errors = do
90 argv <- getArgs
91 let (_, usernames, _) = getOpt Permute options argv
92
93 if (null usernames)
94 then return ["No usernames provided."]
95 else return []
96
97
98 to_errors :: IO [String]
99 to_errors = do
100 toaddr <- to_email_address
101 fromaddr <- from_email_address
102 if (isNothing toaddr) && (isJust fromaddr)
103 then return ["\"From\" address specified without \"To\" address."]
104 else return []
105
106 from_errors :: IO [String]
107 from_errors = do
108 toaddr <- to_email_address
109 fromaddr <- from_email_address
110 if (isJust toaddr) && (isNothing fromaddr)
111 then return ["\"To\" address specified without \"From\" address."]
112 else return []
113
114
115 format_error :: String -> String
116 format_error err = "ERROR: " ++ err ++ "\n"
117
118
119 -- Return a list of errors.
120 parse_errors :: IO [String]
121 parse_errors = do
122 argv <- getArgs
123 let (_, _, errors) = getOpt Permute options argv
124 errs_username <- username_errors
125 errs_to <- to_errors
126 errs_from <- from_errors
127 return $ map format_error (errors ++ errs_username ++ errs_to ++ errs_from)
128
129 -- Is the help option set?
130 help_set :: IO Bool
131 help_set = do
132 opts <- parse_options
133 return (opt_help opts)
134
135
136 to_email_address :: IO (Maybe String)
137 to_email_address = do
138 opts <- parse_options
139 return (opt_to opts)
140
141 from_email_address :: IO (Maybe String)
142 from_email_address = do
143 opts <- parse_options
144 return (opt_from opts)
145
146
147 parse_usernames :: IO [String]
148 parse_usernames = do
149 argv <- getArgs
150 let (_, usernames, _) = getOpt Permute options argv
151 return usernames