1+ use std:: fmt:: Display ;
2+
13use winnow:: ascii:: digit1;
24use winnow:: combinator:: alt;
35use winnow:: combinator:: opt;
@@ -23,10 +25,31 @@ pub struct CompilationSummary {
2325 /// The compilation result; whether compilation succeeded or failed.
2426 pub result : CompilationResult ,
2527 /// The count of modules loaded.
26- pub modules_loaded : usize ,
28+ pub modules_loaded : ModulesLoaded ,
29+ }
30+
31+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
32+ pub enum ModulesLoaded {
33+ /// The count of modules loaded.
34+ Count ( usize ) ,
35+ /// All modules were loaded, unknown count.
36+ All ,
37+ }
38+
39+ impl Display for ModulesLoaded {
40+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
41+ match self {
42+ ModulesLoaded :: Count ( n) => write ! ( f, "{n}" ) ,
43+ ModulesLoaded :: All => write ! ( f, "all" ) ,
44+ }
45+ }
2746}
2847
2948/// Parse a compilation summary, like `Ok, one module loaded.`.
49+ ///
50+ /// NB: This will definitely explode if you have `Opt_ShowLoadedModules` enabled.
51+ ///
52+ /// See: <https://gitlab.haskell.org/ghc/ghc/-/blob/6d779c0fab30c39475aef50d39064ed67ce839d7/ghc/GHCi/UI.hs#L2309-L2329>
3053pub fn compilation_summary ( input : & mut & str ) -> PResult < CompilationSummary > {
3154 let result = alt ( (
3255 "Ok" . map ( |_| CompilationResult :: Ok ) ,
@@ -35,6 +58,33 @@ pub fn compilation_summary(input: &mut &str) -> PResult<CompilationSummary> {
3558 . parse_next ( input) ?;
3659 let _ = ", " . parse_next ( input) ?;
3760
61+ let modules_loaded = alt ( (
62+ compilation_summary_no_modules,
63+ compilation_summary_unloaded_all,
64+ compilation_summary_count,
65+ ) )
66+ . parse_next ( input) ?;
67+
68+ let _ = '.' . parse_next ( input) ?;
69+ let _ = line_ending_or_eof. parse_next ( input) ?;
70+
71+ Ok ( CompilationSummary {
72+ result,
73+ modules_loaded,
74+ } )
75+ }
76+
77+ fn compilation_summary_no_modules ( input : & mut & str ) -> PResult < ModulesLoaded > {
78+ let _ = "no modules to be reloaded" . parse_next ( input) ?;
79+ Ok ( ModulesLoaded :: Count ( 0 ) )
80+ }
81+
82+ fn compilation_summary_unloaded_all ( input : & mut & str ) -> PResult < ModulesLoaded > {
83+ let _ = "unloaded all modules" . parse_next ( input) ?;
84+ Ok ( ModulesLoaded :: All )
85+ }
86+
87+ fn compilation_summary_count ( input : & mut & str ) -> PResult < ModulesLoaded > {
3888 // There's special cases for 0-6 modules!
3989 // https://gitlab.haskell.org/ghc/ghc/-/blob/288235bbe5a59b8a1bda80aaacd59e5717417726/ghc/GHCi/UI.hs#L2286-L2287
4090 // https://gitlab.haskell.org/ghc/ghc/-/blob/288235bbe5a59b8a1bda80aaacd59e5717417726/compiler/GHC/Utils/Outputable.hs#L1429-L1453
@@ -51,13 +101,10 @@ pub fn compilation_summary(input: &mut &str) -> PResult<CompilationSummary> {
51101 . parse_next ( input) ?;
52102 let _ = " module" . parse_next ( input) ?;
53103 let _ = opt ( "s" ) . parse_next ( input) ?;
54- let _ = " loaded." . parse_next ( input) ?;
55- let _ = line_ending_or_eof . parse_next ( input) ?;
104+ let _ = ' ' . parse_next ( input) ?;
105+ let _ = alt ( ( "loaded" , "reloaded" , "added" , "unadded" , "checked" ) ) . parse_next ( input) ?;
56106
57- Ok ( CompilationSummary {
58- result,
59- modules_loaded,
60- } )
107+ Ok ( ModulesLoaded :: Count ( modules_loaded) )
61108}
62109
63110#[ cfg( test) ]
@@ -75,7 +122,7 @@ mod tests {
75122 . unwrap( ) ,
76123 CompilationSummary {
77124 result: CompilationResult :: Ok ,
78- modules_loaded: 123 ,
125+ modules_loaded: ModulesLoaded :: Count ( 123 ) ,
79126 }
80127 ) ;
81128
@@ -85,7 +132,7 @@ mod tests {
85132 . unwrap( ) ,
86133 CompilationSummary {
87134 result: CompilationResult :: Ok ,
88- modules_loaded: 0 ,
135+ modules_loaded: ModulesLoaded :: Count ( 0 ) ,
89136 }
90137 ) ;
91138
@@ -95,7 +142,7 @@ mod tests {
95142 . unwrap( ) ,
96143 CompilationSummary {
97144 result: CompilationResult :: Ok ,
98- modules_loaded: 1 ,
145+ modules_loaded: ModulesLoaded :: Count ( 1 ) ,
99146 }
100147 ) ;
101148
@@ -105,7 +152,7 @@ mod tests {
105152 . unwrap( ) ,
106153 CompilationSummary {
107154 result: CompilationResult :: Ok ,
108- modules_loaded: 6 ,
155+ modules_loaded: ModulesLoaded :: Count ( 6 ) ,
109156 }
110157 ) ;
111158
@@ -115,7 +162,7 @@ mod tests {
115162 . unwrap( ) ,
116163 CompilationSummary {
117164 result: CompilationResult :: Err ,
118- modules_loaded: 7 ,
165+ modules_loaded: ModulesLoaded :: Count ( 7 )
119166 }
120167 ) ;
121168
@@ -125,7 +172,71 @@ mod tests {
125172 . unwrap( ) ,
126173 CompilationSummary {
127174 result: CompilationResult :: Err ,
128- modules_loaded: 1 ,
175+ modules_loaded: ModulesLoaded :: Count ( 1 ) ,
176+ }
177+ ) ;
178+
179+ // Other verbs.
180+ assert_eq ! (
181+ compilation_summary
182+ . parse( "Ok, 10 modules reloaded.\n " )
183+ . unwrap( ) ,
184+ CompilationSummary {
185+ result: CompilationResult :: Ok ,
186+ modules_loaded: ModulesLoaded :: Count ( 10 ) ,
187+ }
188+ ) ;
189+
190+ assert_eq ! (
191+ compilation_summary
192+ . parse( "Ok, 10 modules added.\n " )
193+ . unwrap( ) ,
194+ CompilationSummary {
195+ result: CompilationResult :: Ok ,
196+ modules_loaded: ModulesLoaded :: Count ( 10 ) ,
197+ }
198+ ) ;
199+
200+ assert_eq ! (
201+ compilation_summary
202+ . parse( "Ok, 10 modules unadded.\n " )
203+ . unwrap( ) ,
204+ CompilationSummary {
205+ result: CompilationResult :: Ok ,
206+ modules_loaded: ModulesLoaded :: Count ( 10 ) ,
207+ }
208+ ) ;
209+
210+ assert_eq ! (
211+ compilation_summary
212+ . parse( "Ok, 10 modules checked.\n " )
213+ . unwrap( ) ,
214+ CompilationSummary {
215+ result: CompilationResult :: Ok ,
216+ modules_loaded: ModulesLoaded :: Count ( 10 ) ,
217+ }
218+ ) ;
219+
220+ // Special cases!
221+ assert_eq ! (
222+ compilation_summary
223+ . parse( "Ok, no modules to be reloaded.\n " )
224+ . unwrap( ) ,
225+ CompilationSummary {
226+ result: CompilationResult :: Ok ,
227+ modules_loaded: ModulesLoaded :: Count ( 0 ) ,
228+ }
229+ ) ;
230+
231+ // Literally just for the 'unloaded' message. You can definitely reload all modules too,
232+ // but whatever.
233+ assert_eq ! (
234+ compilation_summary
235+ . parse( "Ok, unloaded all modules.\n " )
236+ . unwrap( ) ,
237+ CompilationSummary {
238+ result: CompilationResult :: Ok ,
239+ modules_loaded: ModulesLoaded :: All ,
129240 }
130241 ) ;
131242
0 commit comments