bag_of_things/
bag_of_things.rs1use orx_imp_vec::*;
2
3#[derive(Default)]
4struct Bag {
5 things: ImpVec<Thing>,
6}
7
8impl Bag {
9 fn push_thing(&self, name: &str) -> ThingInBag {
10 self.things.imp_push(Thing {
11 name: name.to_string(),
12 });
13 ThingInBag {
14 bag: self,
15 thing: &self.things[self.things.len() - 1],
16 }
17 }
18
19 fn things(&self) -> Vec<&str> {
20 self.things.iter().map(|x| x.name.as_str()).collect()
21 }
22}
23
24struct Thing {
25 name: String,
26}
27
28#[derive(Clone, Copy)]
29struct ThingInBag<'a> {
30 thing: &'a Thing,
31 bag: &'a Bag,
32}
33impl<'a> ThingInBag<'a> {
34 fn push_thing_in_same_bag(&self, name: &str) -> ThingInBag {
35 self.bag.push_thing(name)
36 }
37
38 fn is_in_bag(&self, bag: &Bag) -> bool {
39 let self_bag = self.bag as *const Bag;
40 let other_bag = bag as *const Bag;
41 self_bag == other_bag
42 }
43}
44impl<'a> PartialEq for ThingInBag<'a> {
45 fn eq(&self, other: &Self) -> bool {
46 let same_bag = self.bag as *const Bag == other.bag as *const Bag;
47 let same_thing = self.thing as *const Thing == other.thing as *const Thing;
48 same_bag && same_thing
49 }
50}
51
52fn main() {
53 let bag = Bag::default();
55
56 let pen = bag.push_thing("pen");
58 let cup = bag.push_thing("cup");
59 assert_eq!(bag.things(), ["pen", "cup"]);
60
61 pen.push_thing_in_same_bag("pencil");
63 cup.push_thing_in_same_bag("cupcake");
64 assert_eq!(bag.things(), ["pen", "cup", "pencil", "cupcake"]);
65
66 let other_bag = Bag::default();
68 let key = other_bag.push_thing("key");
69 let other_pen = other_bag.push_thing("pen");
70
71 assert_eq!(pen.is_in_bag(&bag), true);
73 assert_eq!(pen.is_in_bag(&other_bag), false);
74
75 assert_eq!(key.is_in_bag(&bag), false);
76 assert_eq!(key.is_in_bag(&other_bag), true);
77
78 assert!(pen != other_pen);
80}