-
Notifications
You must be signed in to change notification settings - Fork 223
Add writeable::adapters::Concatenate and writeable::concatenate! #6929
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
base: main
Are you sure you want to change the base?
Conversation
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. |
/gemini review |
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.
Pull Request Overview
This PR adds a new Concat
adapter and concatenate!
macro to the writeable crate for efficiently concatenating multiple Writeable
implementations. The changes provide a performant alternative to string concatenation by implementing the concatenation directly at the Writeable
trait level.
Key changes:
- Introduces
Concat
struct that implementsWriteable
andTryWriteable
for concatenating two writeables - Adds
concatenate!
macro for convenient concatenation of multiple writeables - Updates documentation with examples showing how to use the new functionality
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
utils/writeable/src/lib.rs | Adds module declaration and public exports for the new concat functionality |
utils/writeable/src/concat.rs | Implements the core Concat adapter struct and concatenate! macro with full trait implementations |
utils/writeable/src/cmp.rs | Adds documentation example demonstrating usage of concatenate! macro with comparison functions |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Co-authored-by: Copilot <[email protected]>
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.
Code Review
This pull request introduces writeable::adapters::Concat
and the writeable::concatenate!
macro, providing an efficient way to concatenate multiple Writeable
items. The implementation is solid and the new functionality is well-integrated. My review focuses on improving documentation clarity and addressing minor code style issues in the new concat.rs
file and related documentation.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
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 like this
use core::fmt; | ||
|
||
pub use cmp::{cmp_str, cmp_utf8}; | ||
pub use concat::concatenate; |
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.
question: do we think this should be toplevel or under adapters? I think either is fine, just calling out the choice.
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 writeable::concatenate!
is nice, similar to writeable::cmp_str()
, but not sure if we should worry about conflicts when people glob-import
utils/writeable/src/cmp.rs
Outdated
/// | ||
/// assert_eq!( | ||
/// Ordering::Less, | ||
/// writeable::cmp_str(&writeable::concatenate!("en", '-', "AU"), "en-US") |
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 doesn't actually require concatenate
(just write "en-AU"), can you use an example that does?
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.
done
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 prefer the example you have on the Concatenate
type that combines impl Writeable for str
with impl Writeable for i32
. even with your update this does not really need concat.
/// ``` | ||
#[macro_export] | ||
#[doc(hidden)] // macro | ||
macro_rules! __concatenate { |
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 should be concat
: https://doc.rust-lang.org/stable/std/?search=concat
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.
concat
breaks use writeable::*
unfortunately because std::concat is in the default prelude. You can see the errors in an earlier commit on the branch:
https://github.com/unicode-org/icu4x/actions/runs/17571159926/job/49907497551
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.
(Open to suggestions on other names.)
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.
join?
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.
concat_writeable
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.
writeable::concat_writeable!
is redundant but maybe ok?
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 assume it's mostly going to be imported
/// ``` | ||
/// | ||
/// This function can be combined with `writeable::concatenate!` to make an efficient | ||
/// string-substring comparison: |
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 don't understand how this gives you a string-substring comparison, the examples certainly don't show that
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.
Hm? The example is comparing a string to a list of substrings.
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.
to me a string substring comparison is either eq("foo", 1, 2, "oo")
or "foo".contains("oo")
.
the thing that concatenate!
is doing is just concatenating Writeable
s without materializing them to String
s. I don't really see the main selling point as "string-substring comparison".
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.
.
/// fn try_write_to_parts<W: writeable::PartsWrite + ?Sized>(&self, _sink: &mut W) -> Result<Result<(), Self::Error>, core::fmt::Error> { | ||
/// // Unreachable panic: the first Writeable errors, | ||
/// // so the second Writeable is not evaluated. | ||
/// panic!() |
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.
it's weird to make the TryWriteable
panic, because it has a non-panicking error mechanism. why not use that?
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 demonstrating that this code is unreachable for test; no one should write a TryWriteable like this.
But since it is in the docs of the writeable crate, I see your point that people may copy and paste this and think it is what they are supposed to do.
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.
maybe use unreachable!
then!
Alternative to #6921