@@ -2,82 +2,147 @@ use libtest_lexarg::OutputFormat;
22
33use crate :: { cli, notify, Case , RunError , RunMode , TestContext } ;
44
5- pub struct Harness {
6- raw : std:: io:: Result < Vec < std:: ffi:: OsString > > ,
7- cases : Vec < Box < dyn Case > > ,
8- }
5+ pub trait HarnessState : sealed:: _HarnessState_is_Sealed { }
96
10- impl Harness {
11- pub fn with_env ( ) -> Self {
12- let raw = std:: env:: args_os ( ) ;
13- Self :: with_args ( raw)
14- }
7+ pub struct Harness < State : HarnessState > {
8+ state : State ,
9+ }
1510
16- pub fn with_args ( args : impl IntoIterator < Item = impl Into < std:: ffi:: OsString > > ) -> Self {
17- let raw = expand_args ( args) ;
18- Self { raw, cases : vec ! [ ] }
11+ pub struct StateInitial {
12+ start : std:: time:: Instant ,
13+ }
14+ impl HarnessState for StateInitial { }
15+ impl sealed:: _HarnessState_is_Sealed for StateInitial { }
16+
17+ impl Harness < StateInitial > {
18+ pub fn new ( ) -> Self {
19+ Self {
20+ state : StateInitial {
21+ start : std:: time:: Instant :: now ( ) ,
22+ } ,
23+ }
1924 }
2025
21- pub fn discover ( & mut self , cases : impl IntoIterator < Item = impl Case + ' static > ) {
22- for case in cases {
23- self . cases . push ( Box :: new ( case) ) ;
24- }
26+ pub fn with_env ( self ) -> std:: io:: Result < Harness < StateArgs > > {
27+ let raw = std:: env:: args_os ( ) ;
28+ self . with_args ( raw)
2529 }
2630
27- pub fn main ( self ) -> ! {
28- main ( self . raw , self . cases )
31+ pub fn with_args (
32+ self ,
33+ args : impl IntoIterator < Item = impl Into < std:: ffi:: OsString > > ,
34+ ) -> std:: io:: Result < Harness < StateArgs > > {
35+ let raw = expand_args ( args) ?;
36+ Ok ( Harness {
37+ state : StateArgs {
38+ start : self . state . start ,
39+ raw,
40+ } ,
41+ } )
2942 }
3043}
3144
32- const ERROR_EXIT_CODE : i32 = 101 ;
33-
34- fn main ( raw : std:: io:: Result < Vec < std:: ffi:: OsString > > , mut cases : Vec < Box < dyn Case > > ) -> ! {
35- let start = std:: time:: Instant :: now ( ) ;
45+ pub struct StateArgs {
46+ start : std:: time:: Instant ,
47+ raw : Vec < std:: ffi:: OsString > ,
48+ }
49+ impl HarnessState for StateArgs { }
50+ impl sealed:: _HarnessState_is_Sealed for StateArgs { }
51+
52+ impl Harness < StateArgs > {
53+ pub fn parse ( & self ) -> Result < Harness < StateParsed > , cli:: LexError < ' _ > > {
54+ let mut parser = cli:: Parser :: new ( & self . state . raw ) ;
55+ let opts = parse ( & mut parser) ?;
56+
57+ #[ cfg( feature = "color" ) ]
58+ match opts. color {
59+ libtest_lexarg:: ColorConfig :: AutoColor => anstream:: ColorChoice :: Auto ,
60+ libtest_lexarg:: ColorConfig :: AlwaysColor => anstream:: ColorChoice :: Always ,
61+ libtest_lexarg:: ColorConfig :: NeverColor => anstream:: ColorChoice :: Never ,
62+ }
63+ . write_global ( ) ;
3664
37- let raw = match raw {
38- Ok ( raw) => raw,
39- Err ( err) => {
65+ let notifier = notifier ( & opts) . unwrap_or_else ( |err| {
4066 eprintln ! ( "{err}" ) ;
4167 std:: process:: exit ( 1 )
42- }
43- } ;
44- let mut parser = cli:: Parser :: new ( & raw ) ;
45- let opts = parse ( & mut parser) . unwrap_or_else ( |err| {
46- eprintln ! ( "{err}" ) ;
47- std:: process:: exit ( 1 )
48- } ) ;
68+ } ) ;
69+
70+ Ok ( Harness {
71+ state : StateParsed {
72+ start : self . state . start ,
73+ opts,
74+ notifier,
75+ } ,
76+ } )
77+ }
78+ }
4979
50- #[ cfg( feature = "color" ) ]
51- match opts. color {
52- libtest_lexarg:: ColorConfig :: AutoColor => anstream:: ColorChoice :: Auto ,
53- libtest_lexarg:: ColorConfig :: AlwaysColor => anstream:: ColorChoice :: Always ,
54- libtest_lexarg:: ColorConfig :: NeverColor => anstream:: ColorChoice :: Never ,
80+ pub struct StateParsed {
81+ start : std:: time:: Instant ,
82+ opts : libtest_lexarg:: TestOpts ,
83+ notifier : Box < dyn notify:: Notifier > ,
84+ }
85+ impl HarnessState for StateParsed { }
86+ impl sealed:: _HarnessState_is_Sealed for StateParsed { }
87+
88+ impl Harness < StateParsed > {
89+ pub fn discover (
90+ mut self ,
91+ cases : impl IntoIterator < Item = impl Case + ' static > ,
92+ ) -> std:: io:: Result < Harness < StateDiscovered > > {
93+ let mut cases = cases
94+ . into_iter ( )
95+ . map ( |c| Box :: new ( c) as Box < dyn Case > )
96+ . collect ( ) ;
97+ discover (
98+ & self . state . start ,
99+ & self . state . opts ,
100+ & mut cases,
101+ self . state . notifier . as_mut ( ) ,
102+ ) ?;
103+ Ok ( Harness {
104+ state : StateDiscovered {
105+ start : self . state . start ,
106+ opts : self . state . opts ,
107+ notifier : self . state . notifier ,
108+ cases,
109+ } ,
110+ } )
55111 }
56- . write_global ( ) ;
112+ }
57113
58- let mut notifier = notifier ( & opts ) . unwrap_or_else ( |err| {
59- eprintln ! ( "{err}" ) ;
60- std :: process :: exit ( 1 )
61- } ) ;
62- discover ( & start , & opts , & mut cases, notifier . as_mut ( ) ) . unwrap_or_else ( |err| {
63- eprintln ! ( "{err}" ) ;
64- std :: process :: exit ( 1 )
65- } ) ;
114+ pub struct StateDiscovered {
115+ start : std :: time :: Instant ,
116+ opts : libtest_lexarg :: TestOpts ,
117+ notifier : Box < dyn notify :: Notifier > ,
118+ cases : Vec < Box < dyn Case > > ,
119+ }
120+ impl HarnessState for StateDiscovered { }
121+ impl sealed :: _HarnessState_is_Sealed for StateDiscovered { }
66122
67- if !opts. list {
68- match run ( & start, & opts, cases, notifier. as_mut ( ) ) {
69- Ok ( true ) => { }
70- Ok ( false ) => std:: process:: exit ( ERROR_EXIT_CODE ) ,
71- Err ( e) => {
72- eprintln ! ( "error: io error when listing tests: {e:?}" ) ;
73- std:: process:: exit ( ERROR_EXIT_CODE )
74- }
123+ impl Harness < StateDiscovered > {
124+ pub fn run ( mut self ) -> std:: io:: Result < bool > {
125+ if self . state . opts . list {
126+ Ok ( true )
127+ } else {
128+ run (
129+ & self . state . start ,
130+ & self . state . opts ,
131+ self . state . cases ,
132+ self . state . notifier . as_mut ( ) ,
133+ )
75134 }
76135 }
136+ }
77137
78- std:: process:: exit ( 0 )
138+ mod sealed {
139+ #[ allow( unnameable_types) ]
140+ #[ allow( non_camel_case_types) ]
141+ pub trait _HarnessState_is_Sealed { }
79142}
80143
144+ pub const ERROR_EXIT_CODE : i32 = 101 ;
145+
81146fn parse < ' p > ( parser : & mut cli:: Parser < ' p > ) -> Result < libtest_lexarg:: TestOpts , cli:: LexError < ' p > > {
82147 let mut test_opts = libtest_lexarg:: TestOptsBuilder :: new ( ) ;
83148
0 commit comments