Skip to content

Tracking Issue for utf8_chunks #99543

Closed
Closed

Description

@dylni

Feature gate: #![feature(utf8_chunks)]

This is a tracking issue for an improved API for str::from_utf8.

Public API

// core::str

pub struct Utf8Chunks<'a> { ... }

impl<'a> Utf8Chunks<'a> {
    pub fn new(bytes: &'a [u8]) -> Self;
}

impl<'a> Iterator for Utf8Chunks<'a> {
    type Item = Utf8Chunk<'a>;
}

impl<'a> Clone for Utf8Chunks<'a>;
impl<'a> Debug for Utf8Chunks<'a>;
impl<'a> FusedIterator for Utf8Chunks<'a>;


pub struct Utf8Chunk<'a> { ... }

impl<'a> Utf8Chunk<'a> {
    pub fn valid(&self) -> &'a str;
    pub fn invalid(&self) -> &'a [u8];
}

impl<'a> Clone for Utf8Chunk<'a>;
impl<'a> Debug for Utf8Chunk<'a>;
impl<'a> PartialEq for Utf8Chunk<'a>;
impl<'a> Eq for Utf8Chunk<'a>;

Steps / History

Unresolved Questions

  • Should the constructor be Utf8Chunks::new or <[u8]>::utf8_chunks?
  • Should Utf8Chunks::debug or a similar method be exposed?

Footnotes

  1. https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html ↩

Activity

  1. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    T-libs-api[DEPRECATED; DO NOT USE]
    on Jul 21, 2022
  2. added a commit that references this issue on Aug 20, 2022
  3. dtolnay commented on Nov 24, 2023

    @dtolnay
    Member

    I'd be interested in using this to implement Display and Debug for CxxString in the cxx crate. Here is the current implementation without Utf8Chunks:

    Here is what it looks like using Utf8Chunks as currently exists in nightly:

    Are there other known use cases so far that we could look at before an FCP? One thing I am interested in is how the current Utf8Chunks API compares with this alternative one, not based on Iterator, with just 1 type:

    pub struct Utf8Chunks<'a>;
    
    impl<'a> Utf8Chunks<'a> {
        pub fn next_valid(&mut self) -> &'a str;
        pub fn next_invalid(&mut self) -> &'a [u8];
    }
  4. dylni commented on Dec 16, 2023

    @dylni
    ContributorAuthor

    @dtolnay I am currently waiting on this ACP for stabilization.

    Are there other known use cases so far that we could look at before an FCP?

    I am aware of the following use cases.

    • Lossy conversion (String::from_utf8_lossy)
    • Debug formatting (as you mentioned)

    I was originally going to use this feature in os_str_bytes for Debug formatting, but invalid returning individual "sequences" made this usage cumbersome. OsStr cannot be assumed to have the same invalid sequences. However, the individual sequences are required for lossy conversion to work with Utf8Chunks in its current form within libstd.

    One thing I am interested in is how the current Utf8Chunks API compares with this alternative one, not based on Iterator, with just 1 type:

    My concern is that the alternate API is easier to misuse (e.g., calling next_valid twice for two valid chunks). It also requires parsing each invalid sequence twice.

  5. Dylan-DPC commented on Mar 6, 2024

    @Dylan-DPC
    Member

    @dylni generally, you don't need an ACP for this to stabilise (unless the team explicitly asked for it which I don't think happened in this case).
    The next step is an FCP. In which case, you can submit a stabilisation pr for it linking this issue and preferably putting the report you shared here in that pr and then the team will run an fcp either in the pr or the issue.

  6. dylni commented on Mar 9, 2024

    @dylni
    ContributorAuthor

    @Dylan-DPC Right, but the problem is that the ACP would change the API. Stabilizing at this point would prevent the API change from landing.

  7. dtolnay commented on Apr 11, 2024

    @dtolnay
    Member

    @rust-lang/libs-api:
    @rfcbot fcp merge

    I propose stabilizing core::str::Utf8Chunks and core::str::Utf8Chunk ❗with the minor modification described in rust-lang/libs-team#190 ❗.

    I recently wanted this API for C++ string Debug impls in cxx as described in #99543 (comment), and also in libproc_macro for synthesizing C-string literals in #123769.

  8. rfcbot commented on Apr 11, 2024

    @rfcbot

    Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members:

    No concerns currently listed.

    Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

    See this document for info about what commands tagged team members can give me.

  9. added
    proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
    disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    and removed
    proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
    on Apr 11, 2024
  10. rfcbot commented on Apr 11, 2024

    @rfcbot

    🔔 This is now entering its final comment period, as per the review above. 🔔

  11. BurntSushi commented on Apr 11, 2024

    @BurntSushi
    Member

    Note that this same API, under the same name, is also in bstr. See also Utf8Chunks and Utf8Chunk. I can only identify two differences:

    • bstr doesn't have a Utf8Chunks::new constructor. This seems okay.
    • Utf8Chunk in std lacks bstr's Utf8Chunk::incomplete method. This seems okay and something we can add later if the use cases arise.

    With that said, does this mean we also have an itertools situation here? bstr works by defining methods on [u8] via an extension trait.

  12. 4 remaining items

  13. BurntSushi commented on Apr 15, 2024

    @BurntSushi
    Member

    I don't have a specific example to point to unfortunately. But it's similar in concept at least to Utf8Error::error_len. My guess is that if you can find a real world use case for Utf8Error::error_len, then it would also serve as a use case for Utf8Chunk::incomplete. That is, it's useful in a streaming context where a single codepoint might straddle chunk boundaries. @m-ou-se actually added it to bstr long ago: BurntSushi/bstr#68

  14. m-ou-se commented on Apr 15, 2024

    @m-ou-se
    Member

    I don't remember exactly what I needed that function for, but I'm sure I sent that PR because I actually needed it. I can't find any uses of it in any of the code I currently have checked out, but it looks like at that time I was working on two relevant (never finished) projects where I might have needed this: 1. a terminal emulator, and 2. some embedded project with serial communication in chunks.

    There is some separate discussion on use cases in this issue: BurntSushi/bstr#42

  15. added a commit that references this issue on Apr 15, 2024
  16. coolreader18 commented on Apr 18, 2024

    @coolreader18
    Contributor

    Unless Utf8Chunks::new is intended as a temporary solution until there can be a utf8_chunks method on [u8] (à la array::IntoIter::new) I feel like I would expect the construction function to be core::str::utf8_chunks(&[u8]) -> Utf8Chunks<'_>. This is a different type of operation, but for example, std::fs::read_dir() returns std::fs::ReadDir, you don't call std::fs::ReadDir::new(). new implies an operation, just like any other function, and it semantically makes sense to me to create a new Vec or Cell or io::Error, but not to create a new Utf8Chunks. It's, like... a behavior type, not a data type.

  17. dtolnay commented on Apr 19, 2024

    @dtolnay
    Member

    GitHub search for "chunk.incomplete()" (guessing a likely variable name) shows 0 hits. GitHub search for ".incomplete()" shows 123 hits, of which I looked through all of them and 0 are related to utf8 chunks. In #123909, crater uncovered 0 uses of incomplete across crates.io and GitHub.

    As such, I recommend that we do not import bstr's incomplete into core until such time as it is better justified.

    Crater showed a single occurrence of the second type of expected break in #99543 (comment). The affected crate is actively developed (within the past 5 days) and is not depended on by any other crate on crates.io. This breakage is allowed by the standard library's API evolution policy (https://rust-lang.github.io/rfcs/1105-api-evolution.html#minor-change-adding-any-inherent-items).

    I recommend that we move forward with #123909 as written (when the FCP completes in 2 days, of course).

  18. added
    to-announceAnnounce this issue on triage meeting
    and removed
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    on Apr 21, 2024
  19. rfcbot commented on Apr 21, 2024

    @rfcbot

    The final comment period, with a disposition to merge, as per the review above, is now complete.

    As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

    This will be merged soon.

  20. added a commit that references this issue on Apr 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libs-api[DEPRECATED; DO NOT USE]disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions