@@ -154,6 +154,79 @@ pub trait Progress: Send + Sync {
154
154
}
155
155
}
156
156
157
+ /// An object-safe trait for describing hierarchical progress.
158
+ ///
159
+ /// This will be automatically implemented for any type that implements
160
+ /// [`Progress`].
161
+ pub trait DynProgress : Send + Sync + impls:: Sealed {
162
+ /// See [`Progress::add_child`]
163
+ fn add_child ( & mut self , name : String ) -> BoxedDynProgress ;
164
+
165
+ /// See [`Progress::add_child_with_id`]
166
+ fn add_child_with_id ( & mut self , name : String , id : Id ) -> BoxedDynProgress ;
167
+
168
+ /// See [`Progress::init`]
169
+ fn init ( & mut self , max : Option < progress:: Step > , unit : Option < Unit > ) ;
170
+
171
+ /// See [`Progress::set`]
172
+ fn set ( & mut self , step : progress:: Step ) ;
173
+
174
+ /// See [`Progress::unit`]
175
+ fn unit ( & self ) -> Option < Unit > ;
176
+
177
+ /// See [`Progress::max`]
178
+ fn max ( & self ) -> Option < progress:: Step > ;
179
+
180
+ /// See [`Progress::set_max`]
181
+ fn set_max ( & mut self , _max : Option < progress:: Step > ) -> Option < progress:: Step > ;
182
+
183
+ /// See [`Progress::step`]
184
+ fn step ( & self ) -> progress:: Step ;
185
+
186
+ /// See [`Progress::inc_by`]
187
+ fn inc_by ( & mut self , step : progress:: Step ) ;
188
+
189
+ /// See [`Progress::inc`]
190
+ fn inc ( & mut self ) ;
191
+
192
+ /// See [`Progress::set_name`]
193
+ fn set_name ( & mut self , name : String ) ;
194
+
195
+ /// See [`Progress::name`]
196
+ fn name ( & self ) -> Option < String > ;
197
+
198
+ /// See [`Progress::id`]
199
+ fn id ( & self ) -> Id ;
200
+
201
+ /// See [`Progress::message`]
202
+ fn message ( & self , level : MessageLevel , message : String ) ;
203
+
204
+ /// See [`Progress::counter`]
205
+ fn counter ( & self ) -> Option < StepShared > ;
206
+
207
+ /// See [`Progress::info`]
208
+ fn info ( & self , message : String ) ;
209
+
210
+ /// See [`Progress::done`]
211
+ fn done ( & self , message : String ) ;
212
+
213
+ /// See [`Progress::fail`]
214
+ fn fail ( & self , message : String ) ;
215
+
216
+ /// See [`Progress::show_throughput`]
217
+ fn show_throughput ( & self , start : Instant ) ;
218
+
219
+ /// See [`Progress::show_throughput_with`]
220
+ fn show_throughput_with ( & self , start : Instant , step : progress:: Step , unit : Unit , level : MessageLevel ) ;
221
+ }
222
+
223
+ /// An opaque type for storing [`DynProgress`].
224
+ pub struct BoxedDynProgress ( Box < dyn DynProgress > ) ;
225
+
226
+ /// A bridge type that implements [`Progress`] for any type that implements
227
+ /// [`DynProgress`].
228
+ pub struct DynProgressToProgressBridge < T : ?Sized > ( T ) ;
229
+
157
230
/// A trait for describing non-hierarchical progress.
158
231
///
159
232
/// It differs by not being able to add child progress dynamically, but in turn is object safe. It's recommended to
@@ -345,13 +418,15 @@ mod impls {
345
418
time:: Instant ,
346
419
} ;
347
420
348
- use crate :: traits:: RawProgress ;
349
421
use crate :: {
350
422
messages:: MessageLevel ,
351
423
progress:: { Id , Step , StepShared } ,
352
- Progress , Unit ,
424
+ traits:: RawProgress ,
425
+ BoxedDynProgress , DynProgress , DynProgressToProgressBridge , Progress , Unit ,
353
426
} ;
354
427
428
+ pub trait Sealed { }
429
+
355
430
impl < T > RawProgress for T
356
431
where
357
432
T : Progress ,
@@ -515,4 +590,267 @@ mod impls {
515
590
self . deref ( ) . show_throughput_with ( start, step, unit, level)
516
591
}
517
592
}
593
+
594
+ impl < T > Sealed for T where T : Progress + ?Sized { }
595
+
596
+ impl < T , SubP > DynProgress for T
597
+ where
598
+ T : Progress < SubProgress = SubP > + ?Sized ,
599
+ SubP : Progress + ' static ,
600
+ {
601
+ fn add_child ( & mut self , name : String ) -> BoxedDynProgress {
602
+ BoxedDynProgress :: new ( self . add_child ( name) )
603
+ }
604
+
605
+ fn add_child_with_id ( & mut self , name : String , id : Id ) -> BoxedDynProgress {
606
+ BoxedDynProgress :: new ( self . add_child_with_id ( name, id) )
607
+ }
608
+
609
+ fn init ( & mut self , max : Option < Step > , unit : Option < Unit > ) {
610
+ self . init ( max, unit)
611
+ }
612
+
613
+ fn set ( & mut self , step : Step ) {
614
+ self . set ( step)
615
+ }
616
+
617
+ fn unit ( & self ) -> Option < Unit > {
618
+ self . unit ( )
619
+ }
620
+
621
+ fn max ( & self ) -> Option < Step > {
622
+ self . max ( )
623
+ }
624
+
625
+ fn set_max ( & mut self , max : Option < Step > ) -> Option < Step > {
626
+ self . set_max ( max)
627
+ }
628
+
629
+ fn step ( & self ) -> Step {
630
+ self . step ( )
631
+ }
632
+
633
+ fn inc_by ( & mut self , step : Step ) {
634
+ self . inc_by ( step)
635
+ }
636
+
637
+ fn inc ( & mut self ) {
638
+ self . inc ( )
639
+ }
640
+
641
+ fn set_name ( & mut self , name : String ) {
642
+ self . set_name ( name)
643
+ }
644
+
645
+ fn name ( & self ) -> Option < String > {
646
+ self . name ( )
647
+ }
648
+
649
+ fn id ( & self ) -> Id {
650
+ self . id ( )
651
+ }
652
+
653
+ fn message ( & self , level : MessageLevel , message : String ) {
654
+ self . message ( level, message)
655
+ }
656
+
657
+ fn counter ( & self ) -> Option < StepShared > {
658
+ self . counter ( )
659
+ }
660
+
661
+ fn info ( & self , message : String ) {
662
+ self . info ( message)
663
+ }
664
+ fn done ( & self , message : String ) {
665
+ self . done ( message)
666
+ }
667
+ fn fail ( & self , message : String ) {
668
+ self . fail ( message)
669
+ }
670
+
671
+ fn show_throughput ( & self , start : Instant ) {
672
+ self . show_throughput ( start)
673
+ }
674
+ fn show_throughput_with ( & self , start : Instant , step : Step , unit : Unit , level : MessageLevel ) {
675
+ self . show_throughput_with ( start, step, unit, level)
676
+ }
677
+ }
678
+
679
+ impl BoxedDynProgress {
680
+ /// Create new boxed dyn Progress
681
+ pub fn new ( progress : impl DynProgress + ' static ) -> Self {
682
+ Self ( Box :: new ( progress) )
683
+ }
684
+ }
685
+
686
+ impl Progress for BoxedDynProgress {
687
+ type SubProgress = Self ;
688
+
689
+ fn add_child ( & mut self , name : impl Into < String > ) -> Self :: SubProgress {
690
+ self . 0 . add_child ( name. into ( ) )
691
+ }
692
+
693
+ fn add_child_with_id ( & mut self , name : impl Into < String > , id : Id ) -> Self :: SubProgress {
694
+ self . 0 . add_child_with_id ( name. into ( ) , id)
695
+ }
696
+
697
+ fn init ( & mut self , max : Option < Step > , unit : Option < Unit > ) {
698
+ self . 0 . init ( max, unit)
699
+ }
700
+
701
+ fn set ( & mut self , step : Step ) {
702
+ self . 0 . set ( step)
703
+ }
704
+
705
+ fn unit ( & self ) -> Option < Unit > {
706
+ self . 0 . unit ( )
707
+ }
708
+
709
+ fn max ( & self ) -> Option < Step > {
710
+ self . 0 . max ( )
711
+ }
712
+
713
+ fn set_max ( & mut self , max : Option < Step > ) -> Option < Step > {
714
+ self . 0 . set_max ( max)
715
+ }
716
+
717
+ fn step ( & self ) -> Step {
718
+ self . 0 . step ( )
719
+ }
720
+
721
+ fn inc_by ( & mut self , step : Step ) {
722
+ self . 0 . inc_by ( step)
723
+ }
724
+
725
+ fn inc ( & mut self ) {
726
+ self . 0 . inc ( )
727
+ }
728
+
729
+ fn set_name ( & mut self , name : impl Into < String > ) {
730
+ self . 0 . set_name ( name. into ( ) )
731
+ }
732
+
733
+ fn name ( & self ) -> Option < String > {
734
+ self . 0 . name ( )
735
+ }
736
+
737
+ fn id ( & self ) -> Id {
738
+ self . 0 . id ( )
739
+ }
740
+
741
+ fn message ( & self , level : MessageLevel , message : impl Into < String > ) {
742
+ self . 0 . message ( level, message. into ( ) )
743
+ }
744
+
745
+ fn counter ( & self ) -> Option < StepShared > {
746
+ self . 0 . counter ( )
747
+ }
748
+
749
+ fn info ( & self , message : impl Into < String > ) {
750
+ self . 0 . info ( message. into ( ) )
751
+ }
752
+
753
+ fn done ( & self , message : impl Into < String > ) {
754
+ self . 0 . done ( message. into ( ) )
755
+ }
756
+
757
+ fn fail ( & self , message : impl Into < String > ) {
758
+ self . 0 . fail ( message. into ( ) )
759
+ }
760
+
761
+ fn show_throughput ( & self , start : Instant ) {
762
+ self . 0 . show_throughput ( start)
763
+ }
764
+
765
+ fn show_throughput_with ( & self , start : Instant , step : Step , unit : Unit , level : MessageLevel ) {
766
+ self . 0 . show_throughput_with ( start, step, unit, level)
767
+ }
768
+ }
769
+
770
+ impl < T > Progress for DynProgressToProgressBridge < T >
771
+ where
772
+ T : DynProgress + ?Sized ,
773
+ {
774
+ type SubProgress = BoxedDynProgress ;
775
+
776
+ fn add_child ( & mut self , name : impl Into < String > ) -> Self :: SubProgress {
777
+ self . 0 . add_child ( name. into ( ) )
778
+ }
779
+
780
+ fn add_child_with_id ( & mut self , name : impl Into < String > , id : Id ) -> Self :: SubProgress {
781
+ self . 0 . add_child_with_id ( name. into ( ) , id)
782
+ }
783
+
784
+ fn init ( & mut self , max : Option < Step > , unit : Option < Unit > ) {
785
+ self . 0 . init ( max, unit)
786
+ }
787
+
788
+ fn set ( & mut self , step : Step ) {
789
+ self . 0 . set ( step)
790
+ }
791
+
792
+ fn unit ( & self ) -> Option < Unit > {
793
+ self . 0 . unit ( )
794
+ }
795
+
796
+ fn max ( & self ) -> Option < Step > {
797
+ self . 0 . max ( )
798
+ }
799
+
800
+ fn set_max ( & mut self , max : Option < Step > ) -> Option < Step > {
801
+ self . 0 . set_max ( max)
802
+ }
803
+
804
+ fn step ( & self ) -> Step {
805
+ self . 0 . step ( )
806
+ }
807
+
808
+ fn inc_by ( & mut self , step : Step ) {
809
+ self . 0 . inc_by ( step)
810
+ }
811
+
812
+ fn inc ( & mut self ) {
813
+ self . 0 . inc ( )
814
+ }
815
+
816
+ fn set_name ( & mut self , name : impl Into < String > ) {
817
+ self . 0 . set_name ( name. into ( ) )
818
+ }
819
+
820
+ fn name ( & self ) -> Option < String > {
821
+ self . 0 . name ( )
822
+ }
823
+
824
+ fn id ( & self ) -> Id {
825
+ self . 0 . id ( )
826
+ }
827
+
828
+ fn message ( & self , level : MessageLevel , message : impl Into < String > ) {
829
+ self . 0 . message ( level, message. into ( ) )
830
+ }
831
+
832
+ fn counter ( & self ) -> Option < StepShared > {
833
+ self . 0 . counter ( )
834
+ }
835
+
836
+ fn info ( & self , message : impl Into < String > ) {
837
+ self . 0 . info ( message. into ( ) )
838
+ }
839
+
840
+ fn done ( & self , message : impl Into < String > ) {
841
+ self . 0 . done ( message. into ( ) )
842
+ }
843
+
844
+ fn fail ( & self , message : impl Into < String > ) {
845
+ self . 0 . fail ( message. into ( ) )
846
+ }
847
+
848
+ fn show_throughput ( & self , start : Instant ) {
849
+ self . 0 . show_throughput ( start)
850
+ }
851
+
852
+ fn show_throughput_with ( & self , start : Instant , step : Step , unit : Unit , level : MessageLevel ) {
853
+ self . 0 . show_throughput_with ( start, step, unit, level)
854
+ }
855
+ }
518
856
}
0 commit comments