@@ -6,20 +6,28 @@ use argyle::{
66 FlagsBuilder ,
77 KeyWordsBuilder ,
88} ;
9+ use fyi_ansi:: {
10+ ansi,
11+ csi,
12+ } ;
913use fyi_msg:: {
1014 Msg ,
1115 MsgKind ,
1216} ;
13- use std:: path:: {
14- Path ,
15- PathBuf ,
17+ use std:: {
18+ borrow:: Cow ,
19+ collections:: {
20+ BTreeMap ,
21+ BTreeSet ,
22+ } ,
23+ fmt:: Write as _,
24+ fs:: File ,
25+ io:: Write ,
26+ path:: PathBuf ,
1627} ;
1728
1829
1930
20- /// # Generic Help.
21- const HELP : & str = include_str ! ( "help/help.txt" ) ;
22-
2331/// # Manifest.
2432const MANIFEST : & str = include_str ! ( env!( "CARGO_MANIFEST_PATH" ) ) ;
2533
@@ -42,100 +50,8 @@ fn main() {
4250 // Build the flags.
4351 write_flags ( ) ;
4452
45- // Handle the top.
46- write_help (
47- help_path ( "top" ) ,
48- format ! (
49- r#"
50- ;\
51- |' \
52- _ ; : ;
53- / `-. /: : |
54- | ,-.`-. ,': : |
55- \ : `. `. ,'-. : |
56- \ ; ; `-.__,' `-.| {}{}{}
57- \ ; ; ::: ,::'`:. `. Simple CLI status messages.
58- \ `-. : ` :. `. \
59- \ \ , ; ,: (\
60- \ :., :. ,'o)): ` `-.
61- ,/,' ;' ,::"'`.`---' `. `-._
62- ,/ : ; '" `;' ,--`.
63- ;/ :; ; ,:' ( ,:)
64- ,.,:. ; ,:., ,-._ `. \""'/
65- '::' `:'` ,'( \`._____.-'"'
66- ;, ; `. `. `._`-. \\
67- ;:. ;: `-._`-.\ \`.
68- '`:. : |' `. `\ ) \
69- ` ;: | `--\__,'
70- '` ,'
71- ,-'
72- "# ,
73- "\x1b [38;5;199mFYI\x1b [0;38;5;69m v" ,
74- env!( "CARGO_PKG_VERSION" ) ,
75- "\x1b [0m"
76- ) . as_bytes ( )
77- ) ;
78-
79- // A few files are already static; let's just copy them to the "generated"
80- // directory for consistency.
81- copy_path ( "blank" ) ;
82- copy_path ( "confirm" ) ;
83- copy_path ( "help" ) ;
84- copy_path ( "print" ) ;
85- copy_path ( "generic-bottom" ) ;
86-
87- // The rest get manually built.
88- for kind in MsgKind :: ALL {
89- // Before we get to work, let's make sure we remembered to add
90- // manual and subcommand entries for it in the Cargo.toml manifest.
91- let cmd = kind. command ( ) ;
92- if ! cmd. is_empty ( ) {
93- assert ! (
94- MANIFEST . contains( & format!( r#"cmd = "{cmd}""# ) ) ,
95- "Manifest missing subcommand entry for {cmd}." ,
96- ) ;
97- assert ! (
98- MANIFEST . contains( & format!( r#""../release/man/fyi-{cmd}.1.gz""# ) ) ,
99- "Manifest missing manual entry for {cmd}." ,
100- ) ;
101- }
102-
103- // Some of the kinds are already accounted for and can be skipped.
104- if kind. is_empty ( ) || matches ! ( kind, MsgKind :: Confirm ) { continue ; }
105- let name = kind. as_str ( ) ;
106-
107- // Let's double-check there's a mention in the top-level help's
108- // SUBCOMMANDS section for this kind.
109- assert ! (
110- HELP . contains( & format!( "{name}: Hello World" ) ) ,
111- "Top-level help is missing subcommand entry for {name}." ,
112- ) ;
113-
114- // And generate the help!
115- write_help (
116- help_path ( & name. to_ascii_lowercase ( ) ) ,
117- format ! (
118- include_str!( "./help/generic.txt" ) ,
119- name,
120- Msg :: new( kind, "Hello World" ) . as_str( ) ,
121- name. to_lowercase( ) ,
122- ) . as_bytes ( )
123- ) ;
124- }
125- }
126-
127- /// # Out path.
128- fn copy_path ( name : & str ) {
129- write_help ( help_path ( name) , & std:: fs:: read ( format ! ( "help/{name}.txt" ) ) . expect ( "Failed to open file." ) ) ;
130- }
131-
132- /// # Output path (help).
133- fn help_path ( name : & str ) -> PathBuf {
134- PathBuf :: from ( format ! (
135- "{}/help-{}.txt" ,
136- std:: env:: var( "OUT_DIR" ) . expect( "Missing OUT_DIR" ) ,
137- name
138- ) )
53+ // Build the help.
54+ write_help ( ) ;
13955}
14056
14157/// # Output Path.
@@ -200,13 +116,120 @@ fn write_flags() {
200116 . save ( out_path ( "flags.rs" ) ) ;
201117}
202118
203- /// # Write file.
204- fn write_help < P > ( path : P , data : & [ u8 ] )
205- where P : AsRef < Path > {
119+ /// # Write Help.
120+ fn write_help ( ) {
121+ let mut help_text = BTreeMap :: new ( ) ;
122+ help_text. insert ( "Blank" , Cow :: Borrowed ( include_str ! ( "help/blank.txt" ) ) ) ;
123+ help_text. insert ( "Custom" , Cow :: Borrowed ( include_str ! ( "help/print.txt" ) ) ) ;
124+ help_text. insert ( "Confirm" , Cow :: Borrowed ( include_str ! ( "help/confirm.txt" ) ) ) ;
125+
126+ let mut help_subcommands = BTreeSet :: new ( ) ;
127+
128+ // The rest get manually built.
129+ for kind in MsgKind :: ALL {
130+ // Before we get to work, let's make sure we remembered to add
131+ // manual and subcommand entries for it in the Cargo.toml manifest.
132+ let cmd = kind. command ( ) ;
133+ if ! cmd. is_empty ( ) {
134+ assert ! (
135+ MANIFEST . contains( & format!( r#"cmd = "{cmd}""# ) ) ,
136+ "Manifest missing subcommand entry for {cmd}." ,
137+ ) ;
138+ assert ! (
139+ MANIFEST . contains( & format!( r#""../release/man/fyi-{cmd}.1.gz""# ) ) ,
140+ "Manifest missing manual entry for {cmd}." ,
141+ ) ;
142+ }
143+
144+ // Some of the kinds are already accounted for and can be skipped.
145+ if kind. is_empty ( ) || matches ! ( kind, MsgKind :: Confirm ) { continue ; }
146+ let name = kind. as_str ( ) ;
147+
148+ // SUBCOMMANDS in the main help.
149+ help_subcommands. insert ( format ! ( " {cmd:<12}{name}: Hello World" ) ) ;
150+
151+ assert ! (
152+ help_text. insert( kind. as_str( ) , Cow :: Owned ( format!(
153+ include_str!( "./help/generic.txt" ) ,
154+ name,
155+ Msg :: new( kind, "Hello World" ) . as_str( ) ,
156+ cmd,
157+ ) ) ) . is_none( ) ,
158+ "BUG: duplicate kind help: {kind}" ,
159+ ) ;
160+ }
161+
162+ // Finish the main help, and add it to the list.
163+ let mut main = include_str ! ( "./help/help.txt" ) . trim ( ) . to_owned ( ) ;
164+ main. push ( '\n' ) ;
165+ for line in help_subcommands {
166+ main. push_str ( & line) ;
167+ main. push ( '\n' ) ;
168+ }
169+ help_text. insert ( "None" , Cow :: Owned ( main) ) ;
170+
171+ // Finally, make some code!
172+ let mut out = format ! (
173+ "#[cold]
174+ /// # Help Page.
175+ ///
176+ /// Print the appropriate help screen given the CLI arguments used.
177+ fn helper(cmd: MsgKind) {{
206178 use std::io::Write;
207179
208- let mut file = std:: fs:: File :: create ( path) . expect ( "Unable to create file." ) ;
209- file. write_all ( data) . expect ( "Write failed." ) ;
210- file. write_all ( b"\n " ) . expect ( "Write failed." ) ;
211- file. flush ( ) . expect ( "Flush failed." ) ;
180+ let mut handle = std::io::stdout().lock();
181+
182+ // The top is always the same.
183+ handle.write_all({help_top:?}.as_bytes()).unwrap();
184+
185+ // The middle varies by command.
186+ handle.write_all(match cmd {{" ,
187+ help_top=concat!(
188+ r#"
189+ ;\
190+ |' \
191+ _ ; : ;
192+ / `-. /: : |
193+ | ,-.`-. ,': : |
194+ \ : `. `. ,'-. : |
195+ \ ; ; `-.__,' `-.| "# , ansi!( ( 199 ) ~ ( cornflower_blue) "FYI" ) , " v" , env!( "CARGO_PKG_VERSION" ) , csi!( ) , r#"
196+ \ ; ; ::: ,::'`:. `. Simple CLI status messages.
197+ \ `-. : ` :. `. \
198+ \ \ , ; ,: (\
199+ \ :., :. ,'o)): ` `-.
200+ ,/,' ;' ,::"'`.`---' `. `-._
201+ ,/ : ; '" `;' ,--`.
202+ ;/ :; ; ,:' ( ,:)
203+ ,.,:. ; ,:., ,-._ `. \""'/
204+ '::' `:'` ,'( \`._____.-'"'
205+ ;, ; `. `. `._`-. \\
206+ ;:. ;: `-._`-.\ \`.
207+ '`:. : |' `. `\ ) \
208+ ` ;: | `--\__,'
209+ '` ,'
210+ ,-'
211+
212+ "# ) ,
213+ ) ;
214+ for ( kind, help) in help_text {
215+ writeln ! ( & mut out, "\t \t MsgKind::{kind} => {help:?}," ) . unwrap ( ) ;
216+ }
217+ writeln ! (
218+ & mut out,
219+ "\t }}.as_bytes()).unwrap();
220+
221+ // The bottom is _usually_ the same.
222+ if ! matches!(cmd, MsgKind::Blank | MsgKind::Confirm | MsgKind::Custom | MsgKind::None) {{
223+ handle.write_all({help_bottom:?}.as_bytes()).unwrap();
224+ }}
225+
226+ let _res = handle.flush();
227+ }}" ,
228+ help_bottom=include_str!( "help/generic-bottom.txt" ) ,
229+ ) . unwrap ( ) ;
230+
231+ // Save it.
232+ File :: create ( out_path ( "help.rs" ) )
233+ . and_then ( |mut f| f. write_all ( out. as_bytes ( ) ) . and_then ( |( ) | f. flush ( ) ) )
234+ . expect ( "Unable to save help.rs." ) ;
212235}
0 commit comments