Home > Software engineering >  What is the best way to access data within nested structs, all of which are Optional using MongoDB&#
What is the best way to access data within nested structs, all of which are Optional using MongoDB&#

Time:11-14

I have a set of structs that are nested, and all the data is optional. Structs are similar to the following (for simplicity I've removed some of the Optionals):

#[derive(Debug, Serialize, Deserialize)]
pub struct Device {
    #[serde(rename = "_id")]
    pub id: Option<bson::oid::ObjectId>,
    pub system: Option<System>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct System {
    pub id: Option<u32>,
    pub mac: Option<String>,
}

When I query the db, I get the data:

Ok(Some(Device { id: Some(ObjectId("...")),  system: Some(System { id: Some(123), mac: Some("1234") })}))

I am trying to access the id value within the System struct. I can access it easily with a few nested match statements, but I was wondering if there is an easier solution. I've been looking at unwrap_or, unwrap_or_else, but I haven't been able to get the syntax correct. Ideally returning a 0 will suffice, as that value is used to denote an error within the application structure. The nested match statements work fine - it is just a bit verbose.

Alternatively I could also just use the aggregation pipeline to get the value. I'm just curious about alternatives.

Thanks.

CodePudding user response:

You can use and_then to apply a function to the contained Ok value, and leave Nones unchanged. For example, imagine the following structure:

struct Foo {
    bar: Option<Bar>
}

struct Bar {
    baz: Option<Baz>
}

struct Baz {
    value: Option<i32>
}

You can then query the nested data like:

fn read_value(foo: Foo) -> Option<i32> {
    foo.bar
        .and_then(|bar| bar.baz) 
        .and_then(|baz| baz.value)
}

If any of the Option's are None, the whole expression will be None, otherwise it will be the contained Some(value)

  • Related