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
Add binding for git_message_trailers
#749
Add binding for git_message_trailers
#749
Conversation
I don’t know how to fix the current error from the CI. The output on my machine:
The C function at line 18438 in that file: const git_message_trailer** __test_field_type_git_message_trailer_array_trailers(git_message_trailer_array* b) {
return &b->trailers;
} The error output from the CI is better than the one on my machine:
How can I provide a better type in |
That looks like a difference of |
Fix error from `cargo run --manifest-path systest/Cargo.toml;`. You can’t just mix and match `*mut` and `*const` like that.
Oh wow. Yep, that was it. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again for this! I left some comments but otherwise this is looking pretty good!
src/message.rs
Outdated
/// Collection of trailer key–value pairs. | ||
/// | ||
/// Use `iter()` to get access to the values. | ||
pub struct MessageTrailers<'pair> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that this is a uniquely owned value, so I don't think that a 'pair
lifetime parameter here is necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See rev. f6fd4b7
src/message.rs
Outdated
} | ||
} | ||
|
||
impl<'pair> Binding for MessageTrailers<'pair> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this may not actually be necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See rev. b0015cc
src/message.rs
Outdated
/// A borrowed iterator. | ||
pub struct MessageTrailersIterator<'pair> { | ||
trailers: &'pair MessageTrailers<'pair>, | ||
counter: usize, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I might recommend is to change this to Range<usize>
so that way next()
is easy to implement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never heard of, but I like it!
See rev. e94008a
src/message.rs
Outdated
} | ||
} | ||
|
||
struct Trailer<'pair> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a one-off struct just for the method below so I think it's fine to remove this and just inline the method into the iterator implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See rev. 55ea909
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add implementations for size_hint
and ExactSizeIterator
here as well? (which would also necessitate DoubleEndedIterator
, and the implementations should be relatively easy if the counter
field is changed to a Range
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented len()
for ExactSizeIterator
. The doc says that size_hint()
can be derived from it. I couldn’t implement size_hint()
myself.
The doc says that len()
has a default implementation, but I guess just returning the value directly wouldn’t be less efficient than whatever the default impl. is.
See rev. e7b0306
Suggested-by: Alex Crichton <alex@alexcrichton.com> See: #749 (comment)
Suggested-by: Alex Crichton <alex@alexcrichton.com> See: #749 (comment)
I love it. Suggested-by: Alex Crichton <alex@alexcrichton.com> See: #749 (comment)
Suggested-by: Alex Crichton <alex@alexcrichton.com> See: #749 (comment)
Also change `to_str_tuple(…)` in order to share more code between two of the iterators. Suggested-by: Alex Crichton <alex@alexcrichton.com> See: #749 (comment)
What are your preferences with regards to rebase? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This'll get rebased when merged so no need to worry about manual rebasing!
src/message.rs
Outdated
_marker: marker::PhantomData<c_char>, | ||
} | ||
|
||
impl<'pair> MessageTrailers { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the type doesn't have a lifetime parameter any more this shoudl move down to the iter
method itself, but even on the iter method it can be elided and it can return MessageTrailersIterator<'_>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See rev e450945
src/message.rs
Outdated
/// Use `iter()` to get access to the values. | ||
pub struct MessageTrailers { | ||
raw: raw::git_message_trailer_array, | ||
_marker: marker::PhantomData<c_char>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This I don't believe is necessary any longer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See rev a0bd026
} | ||
|
||
impl<'pair> Iterator for MessageTrailersIterator<'pair> { | ||
type Item = (&'pair str, &'pair str); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this perhaps be an iterator of &[u8]
instead of &str
to allow for non-utf8 messages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve gone back and forth on the UTF-8 issue. I think I ended up trying to do what message_prettify(…)
does, and that function seems to assume that it gets a UTF-8 string back. It seems though that it can send in a non-UTF-8 string since it passes in a IntoCString
(as does message_trailers(…)
), in which case it would error out when it gets non-UTF-8 strings back (if I’ve read the code correctly).
Supporting &[u8]
seems good, but what about both types? It seems inconvenient to send in a UTF-8 string to C, get back &[u8]
values that you know are UTF-8 and then having to convert or assert that they are also valid as &str
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eh I could also go either way on this. I don't think the bindings are super principled so far, some of the time it tries to give you bytes and other times it gives you strings. I don't really mind either way on this, we can always add a separate iterator in the future specifically for bytes if strings becomes a problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See rev 70b7ebd
src/message.rs
Outdated
|
||
impl ExactSizeIterator for MessageTrailersIterator<'_> { | ||
fn len(&self) -> usize { | ||
self.range.end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This'll want to be self.range.len()
since the length changes over time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See rev 34fa7b5
self.range | ||
.next() | ||
.map(|index| to_str_tuple(&self.trailers, index, marker::PhantomData)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add size_hint
here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay I think I understand now. I confused myself thought that size_hint()
was part of ExactSizeIterator
.
See rev 16321f3
src/message.rs
Outdated
} | ||
} | ||
|
||
#[inline(always)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This annotation isn't necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See rev 023fb92
Better than the default implementation. See: #749 (comment)
Support both raw bytes messages as well as normal (UTF-8) messages by making two iterators. See: #749 (comment)
(cherry picked from commit cd4c2db)
Something unrelated: diff --git a/src/util.rs b/src/util.rs
index 1c6001ddbf60..a31e63bce2c3 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -204,7 +204,7 @@ pub fn c_cmp_to_ordering(cmp: c_int) -> Ordering {
pub fn path_to_repo_path(path: &Path) -> Result<CString, Error> {
macro_rules! err {
($msg:literal, $path:expr) => {
- return Err(Error::from_str(&format!($msg, $path.display())))
+ return Err(Error::from_str(&format!($msg, $path.display())));
};
}
match path.components().next() { But that causes one of the CI checks to fail (corrected in f35b68f and cd4c2db). This is also what Are you supposed to give an option/argument to |
This all looks great to me, thanks! No worries about the extra change, we just bow to whatever the rustfmt gods say we should do. |
No description provided.