ilmoi
ilmoi

Reputation: 2544

Passing both <Vec<Value>> and <Vec<&Value>> as arguments to a function

I have the following code:

        match media_objects {
            Some(media_obj) => {
                let filtered_media_obj = media_obj
                    .iter()
                    .filter(|&mo| {
                        media_ks
                            .iter()
                            .any(|mk| mo["media_key"].as_str().unwrap() == mk.as_str().unwrap())
                    })
                    .collect::<Vec<&Value>>();
                store_all_media(&pool, tweet_id, filtered_media_obj).await?;
            }
            None => {
                let fake_media_obj = media_ks
                    .iter()
                    .map(|mk| {
                        json!({
                            "media_key": mk.as_str().unwrap()
                        })
                    })
                    .collect::<Vec<Value>>();

                // todo ugly
                let fake_media_obj_2 = fake_media_obj.iter().map(|mo| mo).collect::<Vec<&Value>>();

                store_all_media(&pool, tweet_id, fake_media_obj_2).await?;
            }
        }

The issue is that store_all_media expects a <Vec<&Value>>:

pub async fn store_all_media(
    pool: &PgPool,
    tweet_id: &str,
    media_objects: Vec<&Value>,
) -> Result<(), sqlx::error::Error>;

The first leg of the match statement correctly produces that, but the second leg, because it's generating json!() on the fly, produces <Vec<Value>>, which I can't pass to the store function.

I've come up with a dirty workaround, but I'm wondering what's the right way to do this? Do I:

Sorry if this is obvious to the more experienced out there, as a newcommer from dynamic languages this feels like a big challenge:)

Upvotes: 0

Views: 84

Answers (1)

Masklinn
Masklinn

Reputation: 42502

Depending on the exact needs of store_all_media, one option might be to use &[T] where T: Borrow<V>:

  • Vec trivially derefs to &[]
  • being generic over Borrow<V> means the method can accept both Vs and &Vs, in fact that's one use-case for Borrow as it has blanket implementations of Borrow<&T> for T and Borrow<&T> for &T.

Upvotes: 3

Related Questions