~jplatte/turbo.fish

ref: 1abc1a8c4b60b6327462904669594f7123e35946 turbo.fish/src/random.rs -rw-r--r-- 1.9 KiB
1abc1a8c — Jonas Platte random: rewrite, add arrays and reference types 1 year, 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use rand::seq::SliceRandom;

const RECURSION_LIMIT: u8 = 1;

trait Type: Send + Sync {
    fn num_generic_params(&self) -> usize;
    fn stringify(&self, generic_params: &[String]) -> String;
}

impl Type for &'static str {
    fn num_generic_params(&self) -> usize {
        0
    }

    fn stringify(&self, _generic_params: &[String]) -> String {
        (*self).to_owned()
    }
}

impl Type for (&'static str, &'static str) {
    fn num_generic_params(&self) -> usize {
        1
    }

    fn stringify(&self, generic_params: &[String]) -> String {
        format!("{}{}{}", self.0, generic_params[0], self.1)
    }
}

impl Type for (&'static str, &'static str, &'static str) {
    fn num_generic_params(&self) -> usize {
        2
    }

    fn stringify(&self, generic_params: &[String]) -> String {
        format!(
            "{}{}{}{}{}",
            self.0, generic_params[0], self.1, generic_params[1], self.2
        )
    }
}

static TYPES: &[&dyn Type] = &[
    &"_",
    &"bool",
    &"char",
    &"i8",
    &"i16",
    &"i32",
    &"i64",
    &"isize",
    &"u8",
    &"u16",
    &"u32",
    &"u64",
    &"usize",
    &"f32",
    &"f64",
    &"&str",
    &"String",
    &"()",
    &("&", ""),
    &("&mut ", ""),
    &("[", "]"),
    &("Box<", ">"),
    &("Vec<", ">"),
    &("HashSet<", ">"),
    &("Result<", ", ", ">"),
    &("HashMap<", ", ", ">"),
];

pub fn random_type() -> String {
    random_type_depth(0)
}

fn random_type_depth(depth: u8) -> String {
    let ty = TYPES.choose(&mut rand::thread_rng()).unwrap();

    if depth == RECURSION_LIMIT {
        ty.stringify(
            &(0..ty.num_generic_params())
                .map(|_| "_".to_owned())
                .collect::<Vec<_>>(),
        )
    } else {
        ty.stringify(
            &(0..ty.num_generic_params())
                .map(|_| random_type_depth(depth + 1))
                .collect::<Vec<_>>(),
        )
    }
}