File: basic_cascades.rs

package info (click to toggle)
rust-cascade 1.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 108 kB
  • sloc: makefile: 4
file content (126 lines) | stat: -rw-r--r-- 3,380 bytes parent folder | download
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#[macro_use]
extern crate cascade;

#[derive(Clone, Debug)]
struct Person {
    name: String,
    age: u32,
    height: u32,
}

impl Person {
    pub fn blank() -> Person {
        Person {
            name: "".to_string(),
            age: 0,
            height: 0,
        }
    }
}

#[derive(Clone, Debug)]
struct Chain {
    links: Vec<u32>,
}

impl Chain {
    fn blank() -> Chain {
        Chain { links: vec![] }
    }
    fn add(mut self, link: u32) -> Self {
        self.links.push(link);
        self
    }
}

#[allow(unused)]
fn main() {
    // Cascades can be used recursively!
    let people = cascade! {
       Vec::new();
       ..push(cascade! {
           Person::blank();
           ..name = "John Smith".to_string();
           ..height = 72; // 6 feet, or 72 inches tall
           ..age = 34;
       });
       // This is what an expanded cascade looks like.
       ..push({
          let mut __tmp = Person::blank();
          __tmp.name = "Jason Smith".to_string();
          __tmp.height = 64;
          __tmp.age = 34;
          __tmp
       });
    };
    // Any expression works as the first statement of a cascade.
    let other_person = cascade! {
       people[0].clone();
       ..name = "Bob Smith".to_string();
       ..height = 66;
    };
    // You can also use +=, -=, *=, /= for operators
    let another_person = cascade! {
       other_person.clone();
       ..name = "Joan Smith".to_string();
       ..age += 3;
       ..height -= 4;
    };
    // You can put regular statements inside of a cascade macro
    let yet_another_person = cascade! {
       people[0].clone();
       ..name = "James Smith".to_string();
       ..age = 27;
       println!("Cascades in Rust are cool!");
       ..height -= 3;
    };
    // You can bind the initial value of the cascade to an identifier, which reflects the current state of the cascaded value.
    let one_more_person = cascade! {
      let person = people[0].clone();
      println!("'person' was equal to: {:?}", person);
      ..name = "James Smith".to_string();
      ..height = ((person.height as f32) * 0.8) as u32;
      println!("'person' is now equal to: {:?}", person);
    };
    // As of version 0.1.2, you can also chain methods together. Observe:
    let method_chain_example = cascade! {
      let ch = Chain::blank();
      ..add(5).add(6).add(7); // In this case, ch is consumed here. So we have to shadow ch to avoid an error. Obviously, this isn't the most useful way to method-chain.
      let ch = ();
    };

    // You can have nested blocks within the cascade
    let block_example = cascade! {
      Vec::new();
      ..push(1);
      ..push(2);
    };

    let has_more_than_three_elements = cascade! {
        let v = vec![1,2,3];
        ..push(4);
        v.len() > 3
    };

    println!("{}", cascade! {
        vec![1,2,3];
        ..push(4);
        ..into_iter().fold(0, |acc, x| acc + x)
    });

    cascade! {
        let _: Vec<u32> = vec![1,2,3].into_iter().map(|x| x + 1).collect();
        ..push(1);
    };

    option_cascade_test().unwrap().unwrap();
}

// As of version 0.1.3, you can use the ? operator after a .. statement.
fn option_cascade_test() -> Result<Result<(), ()>, ()> {
    let question_mark_operator_example: Result<Result<(), ()>, ()> = cascade! {
      Ok(Ok(()));
      ..unwrap()?;
    };
    return question_mark_operator_example;
}