progquester
progquester

Reputation: 1806

How to get an enum reference from a reference to a child type of the enum?

I have an enum type Shape that contains two types Rect and Circle. now there is a function that can find &Rect or &Circle objects, how can I get them to return as &Shape?

#[derive(Debug)]
struct Rect {}

#[derive(Debug)]
struct Circle {}

#[derive(Debug)]
enum Shape {
    R(Rect),
    C(Circle),
}

struct Container {
    rects: Vec<(usize, Rect)>,
    circls: Vec<(usize, Circle)>,
}

impl Container {
    fn find_shape(&self, id: usize) -> Option<&Shape> {
        let optr = self.rects.iter().find(|x| x.0 == id);
        if let Some((_, r)) = optr {
            return Some(&Shape::R(r)); // expected struct `Rect`, found `&Rect`
        }
        let optc = self.circls.iter().find(|x| x.0 == id);
        if let Some((_, c)) = optc {
            return Some(c); // expected enum `Option<&Shape>` found reference `&Circle`
        }
        return None;
    }
}

fn main() {
    let cont = Container {
        rects: vec![(0, Rect {}), (2, Rect {})],
        circls: vec![(1, Circle {}), (3, Circle {})],
    };
    let s = cont.find_shape(1).unwrap();
    println!("shape is {:?}", s);
}

Upvotes: 1

Views: 155

Answers (1)

Masklinn
Masklinn

Reputation: 42632

now there is a function that can find &Rect or &Circle objects, how can I get them to return as &Shape?

It can't, in the same way you can't get e.g. an &Option<String> from an &String.

Shape is, in essence,

struct Shape {
    discr: u8,
    content: union { _1: Rect, _2: Circle }
}

The solution is to either modify Shape to store references, or to have a secondary type which does that (e.g. ShapeRef).

The latter is quite common.

Upvotes: 4

Related Questions