1
1
use std:: cmp;
2
2
3
3
use CliResult ;
4
+ use byteorder:: { ByteOrder , LittleEndian } ;
4
5
use config:: { Config , Delimiter } ;
5
6
use select:: SelectColumns ;
6
7
use util;
8
+ use rand:: { Rng , SeedableRng , StdRng } ;
7
9
use std:: str:: from_utf8;
8
10
9
11
use self :: Number :: { Float , Int } ;
@@ -21,6 +23,8 @@ sort options:
21
23
See 'xsv select --help' for the format details.
22
24
-N, --numeric Compare according to string numerical value
23
25
-R, --reverse Reverse order
26
+ --random Random order
27
+ --seed <number> RNG seed
24
28
25
29
Common options:
26
30
-h, --help Display this message
@@ -39,6 +43,8 @@ struct Args {
39
43
flag_select : SelectColumns ,
40
44
flag_numeric : bool ,
41
45
flag_reverse : bool ,
46
+ flag_random : bool ,
47
+ flag_seed : Option < usize > ,
42
48
flag_output : Option < String > ,
43
49
flag_no_headers : bool ,
44
50
flag_delimiter : Option < Delimiter > ,
@@ -48,6 +54,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
48
54
let args: Args = util:: get_args ( USAGE , argv) ?;
49
55
let numeric = args. flag_numeric ;
50
56
let reverse = args. flag_reverse ;
57
+ let random = args. flag_random ;
51
58
let rconfig = Config :: new ( & args. arg_input )
52
59
. delimiter ( args. flag_delimiter )
53
60
. no_headers ( args. flag_no_headers )
@@ -58,27 +65,42 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
58
65
let headers = rdr. byte_headers ( ) ?. clone ( ) ;
59
66
let sel = rconfig. selection ( & headers) ?;
60
67
68
+ // Seeding rng
69
+ let seed = args. flag_seed ;
70
+ let mut rng: StdRng = match seed {
71
+ None => {
72
+ StdRng :: from_rng ( rand:: thread_rng ( ) ) . unwrap ( )
73
+ }
74
+ Some ( seed) => {
75
+ let mut buf = [ 0u8 ; 32 ] ;
76
+ LittleEndian :: write_u64 ( & mut buf, seed as u64 ) ;
77
+ SeedableRng :: from_seed ( buf)
78
+ }
79
+ } ;
80
+
61
81
let mut all = rdr. byte_records ( ) . collect :: < Result < Vec < _ > , _ > > ( ) ?;
62
- match ( numeric, reverse) {
63
- ( false , false ) =>
82
+ match ( numeric, reverse, random) {
83
+ ( _, _, true ) =>
84
+ rng. shuffle ( & mut all) ,
85
+ ( false , false , false ) =>
64
86
all. sort_by ( |r1, r2| {
65
87
let a = sel. select ( r1) ;
66
88
let b = sel. select ( r2) ;
67
89
iter_cmp ( a, b)
68
90
} ) ,
69
- ( true , false ) =>
91
+ ( true , false , false ) =>
70
92
all. sort_by ( |r1, r2| {
71
93
let a = sel. select ( r1) ;
72
94
let b = sel. select ( r2) ;
73
95
iter_cmp_num ( a, b)
74
96
} ) ,
75
- ( false , true ) =>
97
+ ( false , true , false ) =>
76
98
all. sort_by ( |r1, r2| {
77
99
let a = sel. select ( r1) ;
78
100
let b = sel. select ( r2) ;
79
101
iter_cmp ( b, a)
80
102
} ) ,
81
- ( true , true ) =>
103
+ ( true , true , false ) =>
82
104
all. sort_by ( |r1, r2| {
83
105
let a = sel. select ( r1) ;
84
106
let b = sel. select ( r2) ;
0 commit comments