How to match Option<CustomStruct>?

Continuing from my question before: Nested "Match hell" in Rust?
I encountered almost the same problem later.

pub async fn from_id(id: &str, db: Database) -> Result<Item, ItemError> {
        let col = Self::get_collection(db);
        let filter = doc! {"_id": id};

        // the first function (find_one) returns Result<Option<T>, E>
        match col.find_one(filter, None).await {
            Ok(reply) => {

                // reply might be None. Return error if None
                // doc is mongodb::Document type 
                // and need to be parsed into Item struct. I use map_from_doc(doc)
                // to parse it
                match reply {
                    Some(doc) => Item.map_from_doc(doc),
                    None => Err(ItemError::NotFound),
                }
            }
           
            // database might return an error (database connection or wrong query)
            Err(_err) => Err(ItemError::MongodbError),
        }
    }

the compiler displays an error: expected value, found struct "Item". from Some(doc). here's the picture: Imgur: The magic of the Internet
What's wrong ? and how do you parse an Option<CustomStruct> in Rust ?

You did not post the full error, so I can't tell for sure whether I'm right, but I think it's because you need to use two colons rather than a dot since Item is a type not a value.

Anyway, since you talk about nested match hell, try something like this:

pub async fn from_id(id: &str, db: Database) -> Result<Item, ItemError> {
    let col = Self::get_collection(db);
    let filter = doc! {"_id": id};

    match col.find_one(filter, None).await {
        Ok(Some(doc)) => Item::map_from_doc(doc),
        Ok(None) => Err(ItemError::NotFound),
        Err(_err) => Err(ItemError::MongodbError),
    }
}

OK. it works!! I just found out that you can do this Ok(Some(doc)) => Item::map_from_doc(&doc).
This pattern makes more sense and easier for me to follow. Thank you