Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Implemented Default for Bson, Document, and ObjectId #82

Merged
merged 8 commits into from
Sep 30, 2017

Conversation

NathanFlurry
Copy link
Contributor

Implemented Default for Bson, Document, and ObjectId. I also fixed some warnings with the tests.

@zonyitoo
Copy link
Contributor

Looks great actually. I will merge now. cc @kyeah

@kyeah
Copy link
Contributor

kyeah commented Sep 29, 2017

OID default should generate a new id via .new, i believe; what do yall think?

@zonyitoo
Copy link
Contributor

Well, it depends on what you need for Default. Could @NathanFlurry tell us why you need Default for those structs?

@saghm
Copy link
Contributor

saghm commented Sep 29, 2017

I'm actually a bit unsure that having Default for ObjectId is a good idea. At least in terms of usage with MongoDB, an all-zero value of ObjectId seems like a very bad idea (you can just use regular integers as your _id fields if you want to have control over the value), and having it generate a new one seems a little weird also given that two calls to ObjectId::default() won't return the same thing, which I feel like violates how Default is expected to behave.

@NathanFlurry
Copy link
Contributor Author

NathanFlurry commented Sep 29, 2017

@zonyitoo I implemented Default for these structures so I can use methods like unwrap_or_default() on them.
I agree that the implementation for ObjectId is a bit odd, but I did it that way because I believe that the result of default() should always be the same and not generate different values every time, like ObjectId::new() does. Maybe Default just doesn't fit on ObjectId at all.
Edit: After looking at the implementation for RandomState, I guess it's fine for Default to have a random value.

@saghm
Copy link
Contributor

saghm commented Sep 29, 2017

I'm not certain it's really worth it just to avoid having to do opt_oid.unwrap_or_else(ObjectId::new()). Another common use of default I can think of is to save having to explicitly initialize every field of a struct (e.g. Foo { x: 1, y: 2, .. Default::default() }, but that doesn't apply here either. I think it's fairly obvious to a user that something called RandomState won't be the same every time it's created, whereas ObjectId might not be as obvious to someone who isn't familiar with the implementation (which is by design not required knowledge for using BSON/MongoDB).

The only argument in favor of implementing ObjectId::default I can think of is so that users can derive Default on structs that they want to serialize/deserialize to and from the database. This is also a pretty clear argument against having it being initialized to all zeroes. I don't think it would actually be terrible to implement it as a wrapper around ObjectId::new for this purpose, but I think it's a good idea to add a (doc) comment mentioning that it won't always return the same value.

src/oid.rs Outdated
/// method will be different every time it is executed.
fn default() -> ObjectId {
// Attempt to create a new `ObjectId`; if that fails return an empty `ObjectId`
ObjectId::new().unwrap_or(ObjectId::with_bytes([0; 12]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unwrap_or_else would be better

@saghm
Copy link
Contributor

saghm commented Sep 30, 2017

Oh geez, I had forgotten that ObjectId::new returns a Result. Given that the only reason I can think of to even have Default on ObjectId is to be able to serialize/deserialize structs, it seems extremely risky to just have silent failures; I can't imagine that many people would bother checking the resulting struct/bson doc to see if the ObjectId is all zeros even if we told them to, especially given that there isn't any easy way to do so, as the array field is (correctly) non-public. I think I'm back to recommending against having Default implemented for ObjectId, only more strongly than before.

@NathanFlurry
Copy link
Contributor Author

I agree, too much unexpected behavior and I guess it doesn't really fit in this situation.

@zonyitoo
Copy link
Contributor

I am Ok with that. How about @saghm @kyeah

@saghm
Copy link
Contributor

saghm commented Sep 30, 2017

LGTM. Thanks for bearing with me when I kept changing my mind!

Copy link
Contributor

@kyeah kyeah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Completely agree with the conversation today -- too much unpredictable behavior for a Default implementation. Was out today, so appeeciate y'all talking this one through to it's conclusion.

@zonyitoo zonyitoo merged commit 9e51763 into mongodb:master Sep 30, 2017
@zonyitoo
Copy link
Contributor

Will be released tonight (GMT+8)

lrlna pushed a commit to lrlna/bson-rs that referenced this pull request Feb 27, 2019
)

Added `Default` implementations
    * `Bson`, `Document`
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants