@@ -64,7 +64,8 @@ fn main() {
6464fn run ( ) -> Result < ( ) > {
6565 let matches = app:: create_app ( ) . get_matches ( ) ;
6666
67- match matches. subcommand ( ) {
67+ // enforces that each branch must return a PrintToken as proof of having printed the output
68+ let _printed: PrintToken = match matches. subcommand ( ) {
6869 ( "checkstyle" , Some ( matches) ) => {
6970 let exercise_path = matches. value_of ( "exercise-path" ) . unwrap ( ) ;
7071 let exercise_path = Path :: new ( exercise_path) ;
@@ -437,11 +438,11 @@ fn run() -> Result<()> {
437438 }
438439 ( "core" , Some ( matches) ) => run_core ( matches) ?,
439440 _ => unreachable ! ( ) ,
440- }
441+ } ;
441442 Ok ( ( ) )
442443}
443444
444- fn run_core ( matches : & ArgMatches ) -> Result < ( ) > {
445+ fn run_core ( matches : & ArgMatches ) -> Result < PrintToken > {
445446 let root_url =
446447 env:: var ( "TMC_LANGS_ROOT_URL" ) . unwrap_or_else ( |_| "https://tmc.mooc.fi" . to_string ( ) ) ;
447448 let client_name = matches. value_of ( "client-name" ) . unwrap ( ) ;
@@ -462,7 +463,8 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
462463 percent_done : update. percent_done ,
463464 data : None ,
464465 } ;
465- print_output ( & output) . map_err ( |e| e. into ( ) )
466+ print_output ( & output) ?;
467+ Ok ( ( ) )
466468 } ) ;
467469
468470 // set token if a credentials.json is found for the client name
@@ -491,7 +493,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
491493 }
492494 } ;
493495
494- match matches. subcommand ( ) {
496+ let printed : PrintToken = match matches. subcommand ( ) {
495497 ( "login" , Some ( matches) ) => {
496498 let email = matches. value_of ( "email" ) ;
497499 let set_access_token = matches. value_of ( "set-access-token" ) ;
@@ -555,7 +557,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
555557 percent_done : 1.0 ,
556558 data : None ,
557559 } ;
558- print_output ( & output) ?;
560+ print_output ( & output) ?
559561 }
560562 ( "logout" , Some ( _matches) ) => {
561563 if credentials_path. exists ( ) {
@@ -574,7 +576,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
574576 percent_done : 1.0 ,
575577 data : None ,
576578 } ;
577- print_output ( & output) ?;
579+ print_output ( & output) ?
578580 }
579581 ( "logged-in" , Some ( _matches) ) => {
580582 if credentials_path. exists ( ) {
@@ -597,7 +599,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
597599 percent_done : 1.0 ,
598600 data : Some ( token) ,
599601 } ;
600- print_output ( & output) ?;
602+ print_output ( & output) ?
601603 } else {
602604 let output = Output :: < ( ) > {
603605 status : Status :: Successful ,
@@ -606,7 +608,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
606608 percent_done : 1.0 ,
607609 data : None ,
608610 } ;
609- print_output ( & output) ?;
611+ print_output ( & output) ?
610612 }
611613 }
612614 ( "get-organizations" , Some ( _matches) ) => {
@@ -621,7 +623,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
621623 percent_done : 1.0 ,
622624 data : Some ( orgs) ,
623625 } ;
624- print_output ( & output) ?;
626+ print_output ( & output) ?
625627 }
626628 ( "get-organization" , Some ( matches) ) => {
627629 let organization_slug = matches. value_of ( "organization" ) . unwrap ( ) ;
@@ -636,7 +638,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
636638 percent_done : 1.0 ,
637639 data : Some ( org) ,
638640 } ;
639- print_output ( & output) ?;
641+ print_output ( & output) ?
640642 }
641643 ( "download-or-update-exercises" , Some ( matches) ) => {
642644 let mut exercise_args = matches. values_of ( "exercise" ) . unwrap ( ) ;
@@ -658,7 +660,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
658660 percent_done : 1.0 ,
659661 data : None ,
660662 } ;
661- print_output ( & output) ?;
663+ print_output ( & output) ?
662664 }
663665 ( "get-course-details" , Some ( matches) ) => {
664666 let course_id = matches. value_of ( "course-id" ) . unwrap ( ) ;
@@ -675,7 +677,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
675677 percent_done : 1.0 ,
676678 data : Some ( course_details) ,
677679 } ;
678- print_output ( & output) ?;
680+ print_output ( & output) ?
679681 }
680682 ( "get-courses" , Some ( matches) ) => {
681683 let organization_slug = matches. value_of ( "organization" ) . unwrap ( ) ;
@@ -690,7 +692,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
690692 percent_done : 1.0 ,
691693 data : Some ( courses) ,
692694 } ;
693- print_output ( & output) ?;
695+ print_output ( & output) ?
694696 }
695697 ( "get-course-settings" , Some ( matches) ) => {
696698 let course_id = matches. value_of ( "course-id" ) . unwrap ( ) ;
@@ -704,7 +706,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
704706 percent_done : 1.0 ,
705707 data : Some ( course) ,
706708 } ;
707- print_output ( & output) ?;
709+ print_output ( & output) ?
708710 }
709711 ( "get-course-exercises" , Some ( matches) ) => {
710712 let course_id = matches. value_of ( "course-id" ) . unwrap ( ) ;
@@ -720,7 +722,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
720722 percent_done : 1.0 ,
721723 data : Some ( course) ,
722724 } ;
723- print_output ( & output) ?;
725+ print_output ( & output) ?
724726 }
725727 ( "get-exercise-details" , Some ( matches) ) => {
726728 let exercise_id = matches. value_of ( "exercise-id" ) . unwrap ( ) ;
@@ -736,7 +738,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
736738 percent_done : 1.0 ,
737739 data : Some ( course) ,
738740 } ;
739- print_output ( & output) ?;
741+ print_output ( & output) ?
740742 }
741743 ( "paste" , Some ( matches) ) => {
742744 let submission_url = matches. value_of ( "submission-url" ) . unwrap ( ) ;
@@ -769,7 +771,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
769771 percent_done : 1.0 ,
770772 data : Some ( new_submission) ,
771773 } ;
772- print_output ( & output) ?;
774+ print_output ( & output) ?
773775 }
774776 ( "run-checkstyle" , Some ( matches) ) => {
775777 let exercise_path = matches. value_of ( "exercise-path" ) . unwrap ( ) ;
@@ -788,7 +790,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
788790 percent_done : 1.0 ,
789791 data : Some ( validation_result) ,
790792 } ;
791- print_output ( & output) ?;
793+ print_output ( & output) ?
792794 }
793795 ( "run-tests" , Some ( matches) ) => {
794796 let exercise_path = matches. value_of ( "exercise-path" ) . unwrap ( ) ;
@@ -805,7 +807,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
805807 percent_done : 1.0 ,
806808 data : Some ( run_result) ,
807809 } ;
808- print_output ( & output) ?;
810+ print_output ( & output) ?
809811 }
810812 ( "send-feedback" , Some ( matches) ) => {
811813 let feedback_url = matches. value_of ( "feedback-url" ) . unwrap ( ) ;
@@ -833,7 +835,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
833835 percent_done : 1.0 ,
834836 data : Some ( response) ,
835837 } ;
836- print_output ( & output) ?;
838+ print_output ( & output) ?
837839 }
838840 ( "submit" , Some ( matches) ) => {
839841 let submission_url = matches. value_of ( "submission-url" ) . unwrap ( ) ;
@@ -864,7 +866,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
864866 data : Some ( new_submission) ,
865867 } ;
866868
867- print_output ( & output) ?;
869+ print_output ( & output) ?
868870 } else {
869871 // same as wait-for-submission
870872 let submission_url = new_submission. submission_url ;
@@ -881,7 +883,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
881883 percent_done : 1.0 ,
882884 data : Some ( submission_finished) ,
883885 } ;
884- print_output ( & output) ?;
886+ print_output ( & output) ?
885887 }
886888 }
887889 ( "get-exercise-submissions" , Some ( matches) ) => {
@@ -898,7 +900,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
898900 percent_done : 1.0 ,
899901 data : Some ( submissions) ,
900902 } ;
901- print_output ( & output) ?;
903+ print_output ( & output) ?
902904 }
903905 ( "wait-for-submission" , Some ( matches) ) => {
904906 let submission_url = matches. value_of ( "submission-url" ) . unwrap ( ) ;
@@ -915,7 +917,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
915917 percent_done : 1.0 ,
916918 data : Some ( submission_finished) ,
917919 } ;
918- print_output ( & output) ?;
920+ print_output ( & output) ?
919921 }
920922 ( "get-exercise-updates" , Some ( matches) ) => {
921923 let course_id = matches. value_of ( "course-id" ) . unwrap ( ) ;
@@ -940,7 +942,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
940942 percent_done : 1.0 ,
941943 data : Some ( update_result) ,
942944 } ;
943- print_output ( & output) ?;
945+ print_output ( & output) ?
944946 }
945947 ( "mark-review-as-read" , Some ( matches) ) => {
946948 let review_update_url = matches. value_of ( "review-update-url" ) . unwrap ( ) ;
@@ -954,7 +956,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
954956 percent_done : 1.0 ,
955957 data : None ,
956958 } ;
957- print_output ( & output) ?;
959+ print_output ( & output) ?
958960 }
959961 ( "get-unread-reviews" , Some ( matches) ) => {
960962 let reviews_url = matches. value_of ( "reviews-url" ) . unwrap ( ) ;
@@ -971,7 +973,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
971973 percent_done : 1.0 ,
972974 data : Some ( reviews) ,
973975 } ;
974- print_output ( & output) ?;
976+ print_output ( & output) ?
975977 }
976978 ( "request-code-review" , Some ( matches) ) => {
977979 let submission_url = matches. value_of ( "submission-url" ) . unwrap ( ) ;
@@ -1005,7 +1007,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
10051007 percent_done : 1.0 ,
10061008 data : Some ( new_submission) ,
10071009 } ;
1008- print_output ( & output) ?;
1010+ print_output ( & output) ?
10091011 }
10101012 ( "download-model-solution" , Some ( matches) ) => {
10111013 let solution_download_url = matches. value_of ( "solution-download-url" ) . unwrap ( ) ;
@@ -1024,7 +1026,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
10241026 percent_done : 1.0 ,
10251027 data : None ,
10261028 } ;
1027- print_output ( & output) ?;
1029+ print_output ( & output) ?
10281030 }
10291031 ( "reset-exercise" , Some ( matches) ) => {
10301032 let exercise_path = matches. value_of ( "exercise-path" ) . unwrap ( ) ;
@@ -1049,7 +1051,7 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
10491051 percent_done : 1.0 ,
10501052 data : None ,
10511053 } ;
1052- print_output ( & output) ?;
1054+ print_output ( & output) ?
10531055 }
10541056 ( "download-old-submission" , Some ( matches) ) => {
10551057 let exercise_id = matches. value_of ( "exercise-id" ) . unwrap ( ) ;
@@ -1081,19 +1083,19 @@ fn run_core(matches: &ArgMatches) -> Result<()> {
10811083 percent_done : 1.0 ,
10821084 data : None ,
10831085 } ;
1084- print_output ( & output) ?;
1086+ print_output ( & output) ?
10851087 }
10861088 _ => unreachable ! ( ) ,
1087- }
1089+ } ;
10881090
1089- Ok ( ( ) )
1091+ Ok ( printed )
10901092}
10911093
1092- fn print_output < T : Serialize + Debug > ( output : & Output < T > ) -> Result < ( ) > {
1094+ fn print_output < T : Serialize + Debug > ( output : & Output < T > ) -> Result < PrintToken > {
10931095 let result = serde_json:: to_string ( & output)
10941096 . with_context ( || format ! ( "Failed to convert {:?} to JSON" , output) ) ?;
10951097 println ! ( "{}" , result) ;
1096- Ok ( ( ) )
1098+ Ok ( PrintToken )
10971099}
10981100
10991101fn write_result_to_file_as_json < T : Serialize > ( result : & T , output_path : & Path ) -> Result < ( ) > {
@@ -1186,3 +1188,5 @@ fn run_checkstyle_write_results(
11861188 }
11871189 Ok ( check_result)
11881190}
1191+
1192+ struct PrintToken ;
0 commit comments