let documents = vec![
doc! {"name": "Maisey", "breed": "Treeing Walker Coonhound"},
doc! {"name": "Ramsay", "breed": "Native American Indian Dog"},
doc! {"name": "Comet", "breed": "Whippet"},
];
coll.insert_many(documents, None).await?;
This does not. Is there a way to get insert_many to work with an array instead of a vector?
let documents: [Document; 3] = [
doc! {"name": "Maisey", "breed": "Treeing Walker Coonhound"},
doc! {"name": "Ramsay", "breed": "Native American Indian Dog"},
doc! {"name": "Comet", "breed": "Whippet"},
];
coll.insert_many(&documents, None).await?;
The error is:
type mismatch resolving <&[mongodb::bson::Document; 3] as IntoIterator>::Item == mongodb::bson::Document
I know that the array type does implement IntoIterator so I thought this would work.
It does not, for now. It's slice, i.e. &[T], which implements IntoIterator, but, since this is the reference and not an owned container, iterator over it can yield only &Ts, not Ts, which insert_many requests.
How should I have inferred from that that it isn't arrays that implement IntoIterator, but only slices of arrays. Doesn't the syntax &[T; N] indicate a reference to an array?
Doesn't &[T; N] just mean a reference to an array?
I tried passing a reference to my array, but it still says:
type mismatch resolving <&[mongodb::bson::Document; 3] as IntoIterator>::Item == mongodb::bson::Document"
It seems like the issue is that it doesn't know that the type of the items in the array is mongodb::bson::Document, but I did specify that in the type of the array.
Am I trying to do something that just is not possible or is there a way to get this to work with an array reference?
You're right that &[T; N] implements IntoIterator, but there's one small detail we should pay attention to – &[T; N]'s IntoIterator impl has Type = &T, which is &bson::Document, but your insert_many expects IntoIterator<Type = bson::Document> – with no reference.
So that's a known limitation of arrays, but there are a few workarounds to get a Item=T iterator from an array:
[…].iter().cloned()
on nightly: std::array::IntoIter::new([…])
using array of Options: [Some(…), Some(…), …].iter_mut().map(Option::take).map(Option::unwrap)
Thinking about this, I'd actually open an issue about insert_many requiring owned documents. That shouldn't be the case – it doesn't need ownership of the documents, because MongoDB runs in a separate server process, and documents are transferred between client and server by serializing them into a binary format and sending a bunch of bytes through a TCP socket. So moving ownership shouldn't be necessary, and the current API design seems overly demanding.
I tried your first suggestion of using documents.iter().cloned() and it worked!
I don't really have a reason to not take the easy path and just use a vector.
I just wanted to understand if it is was possible to use an array instead.