Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Create builders for `Metadata`, `Record`, and `Level`. #200

Merged

Conversation

Projects
None yet
4 participants
@omh1280
Copy link
Contributor

omh1280 commented Jun 20, 2017

Fixes #116.

Create builders to support the construction of Metadata, Record, and Level. I decided to take mut self as the parameter for each builder method because it allows:

let record = RecordBuilder::new().args(...).metadata(...).build()

Whereas taking &mut self leads to the temporary object created by RecordBuilder::new() being dropped before build().

Not done yet--still need to add examples/docs. Please review everything else!

src/lib.rs Outdated
/// the created object when `build` is called.
///
/// # Example
/// ```rust

This comment has been minimized.

@brson

brson Jul 6, 2017

Contributor

Nit: can you add a blank line here?

src/lib.rs Outdated
/// let my_record = RecordBuilder::new(&error_location)
/// .args(format_args!("Error!"))
/// .metadata(error_metadata)
/// .build();

This comment has been minimized.

@brson

brson Jul 6, 2017

Contributor

Example is missing closing backticks.

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jul 6, 2017

@omh1280 thank you.

This all looks right to me with the exception that the builder pattern we tend to prefer is with &mut self instead of self. Unless there's a exceptional reason to use self here can you switch them to &mut self?

cc @alexcrichton can you peek at this? Do you agree that the builders should be by ref?

src/lib.rs Outdated
/// let mut level_test = MetadataBuilder::new()
/// .level(Level::Debug)
/// .target(target)
/// .build();

This comment has been minimized.

@brson

brson Jul 6, 2017

Contributor

Ditto about the blank line and missing backticks.

src/lib.rs Outdated
/// takes a `&Location`.
///
/// # Example
/// ```rust

This comment has been minimized.

@brson

brson Jul 6, 2017

Contributor

Please add blank line here too.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 6, 2017

cc @alexcrichton can you peek at this? Do you agree that the builders should be by ref?

Ah yeah I agree that these should be &mut self across the board

@omh1280

This comment has been minimized.

Copy link
Contributor Author

omh1280 commented Jul 6, 2017

Gotcha. I'll update next time I get a chance!

@omh1280

This comment has been minimized.

Copy link
Contributor Author

omh1280 commented Jul 7, 2017

Fixed!

  • I had to add Copy and Clone to prevent cannot move out of borrowed content in the build functions. Is this OK? Is there a better way to do this?
  • As far as I can tell, RecordBuilder::new needs to take a reference to Location because it cannot create a default which has the appropriate lifetime.
  • Finally, is there any reason Record contains a reference to Location instead of owning it?

Thanks for the review 😄

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jul 15, 2017

Thanks @omh1280!

ping @alexcrichton

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jul 15, 2017

Oh, I guess I can continue the review myself...

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jul 15, 2017

I had to add Copy and Clone to prevent cannot move out of borrowed content in the build functions. Is this OK? Is there a better way to do this?

In this case, this seems fine. I don't see a reason for Record and Metadata not to be Copy/Clone. @alexcrichton what you think? An alternative would be for build to take self, but it looks to me like we prefer for builders to be reusable when possible.

As far as I can tell, RecordBuilder::new needs to take a reference to Location because it cannot create a default which has the appropriate lifetime.

Yes.

Finally, is there any reason Record contains a reference to Location instead of owning it?

I suspect this a subtle efficiency matter. This type is passed around during logging and copying one pointer is faster than copying the entire struct.

This patch looks fine to me now, but I'd be more confident if @alexcrichton took another look.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 17, 2017

I think we may want to remove Copy as it may be a bit restrictive, but adding Clone to these types seems fine by me!

Some other points I'd have:

  • In addition to RecordBuilder::new perhaps we could also have something like Record::builder()? I think @sfackler has pioneered this pattern in the past and it can sometimes help the ergonomics of importing less items.
  • Could you add to the documentation the default value for each builder method?
@omh1280

This comment has been minimized.

Copy link
Contributor Author

omh1280 commented Jul 20, 2017

Thanks Alex! Let me know if it still needs work (or if you want me to rebase to clean up commits)

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 21, 2017

Thanks @omh1280! @sfackler I'm curious, what do you think about the 3 builders here vs trying to collapse them all into one? Or perhaps having one builder with methods that delegate to the others?

src/lib.rs Outdated
pub fn new() -> LocationBuilder {
LocationBuilder {
location: Location {
__module_path: module_path!(),

This comment has been minimized.

@sfackler

sfackler Jul 22, 2017

Member

These defaults are not going to be particularly useful - I'd probably lean towards making them empty strings.

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Jul 22, 2017

I can't actually remember why Location exists as a separate construct from Record I'd probably say we just inline those fields?

It does seem nice to have forwarding methods from the Record builder to the Metadata builder though.

@omh1280

This comment has been minimized.

Copy link
Contributor Author

omh1280 commented Jul 24, 2017

To confirm:

  • Move __module_path, __file, and __line into Record and scrap Location? (and change macros etc.)
  • Add forwarding methods so RecordBuilder can build entirely without MetadataBuilder?
@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Jul 24, 2017

Yep!

If we're changing the macros, we may want to change the __log function to be publicly exposed and take a LogRecord directly, now that you can construct that with the public API.

@omh1280

This comment has been minimized.

Copy link
Contributor Author

omh1280 commented Aug 1, 2017

Sorry for the long wait--I'm in the middle of doing this I promise :)

@omh1280

This comment has been minimized.

Copy link
Contributor Author

omh1280 commented Aug 1, 2017

Updated!

This was a pretty big change, please let me know if I forgot something.

  • Remove Location completely
  • Inline module_path, line, and file into Record
  • Forward target and level functions in RecordBuilder to MetadataBuilder

You now don't have to use any builder structs:

use super::{Record, Level};
let record = Record::builder()
    .module_path("foo")
    .file("bar")
    .line(30)
    .target("myApp") // forwarded
    .level(Level::Error) // forwarded
    .build();

I didn't make __log public: I can do that if that's agreed on /cc @alexcrichton

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Aug 9, 2017

This looks great to me! I'll leave @sfackler to sign off though.

@omh1280 it looks like there may be some CI failures as well?

@omh1280

This comment has been minimized.

Copy link
Contributor Author

omh1280 commented Aug 9, 2017

Didn't see that--fixed!

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Aug 10, 2017

Looks good to me but it needs a rebase.

@omh1280 omh1280 force-pushed the omh1280:record_metadata_construction branch from 13f104e to f0e2403 Aug 10, 2017

@omh1280 omh1280 force-pushed the omh1280:record_metadata_construction branch from f0e2403 to 549f47c Aug 10, 2017

@omh1280

This comment has been minimized.

Copy link
Contributor Author

omh1280 commented Aug 10, 2017

Squashed + rebased

@sfackler sfackler merged commit 66ffd92 into rust-lang-nursery:master Aug 12, 2017

2 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.