Skip to content

Expose Utf8LossyChunksIter #54

Closed
Closed

Description

@dylni

Proposal

Problem statement

When Utf8Error::valid_up_to and Utf8Error::error_len are used, their results will almost always be used to get substrings of the original string. However, since Utf8Error does not have a reference to the original string, it cannot have methods to return the substrings.

Utf8LossyChunksIter is also much easier to use.

Motivation, use-cases

This is useful when creating a custom byte string formatter. UTF-8 portions are usually output using the Display implementation for str or str::escape_debug, but invalid portions might require custom formatting.

Example

Code using str::from_utf8 (requires unsafe):

while !string.is_empty() {
    let (valid, invalid) = match str::from_utf8(string) {
        Ok(string) => (string, &[][..]),
        Err(error) => {
            let valid_len = error.valid_up_to();
            let valid = unsafe { str::from_utf8_unchecked(&string[..valid_len]) };
            let mut invalid = &string[valid_len..];
            if let Some(invalid_len) = error.error_len() {
                invalid = &invalid[..invalid_len];
            }
            (valid, invalid)
        }
    };
    // formatting for `valid` and `invalid`
    string = &string[valid.len() + invalid.len()..];
}

Code using the new API:

for chunk in Utf8Chunks::new(string) {
    let valid = chunk.valid();
    let invalid = chunk.invalid();
    // formatting for `valid` and `invalid`
}

Solution sketches

Make the following changes, and change the feature for these structs from str_internals to utf8_chunks.

Links and related work

What happens now?

This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.

Activity

  1. m-ou-se commented on Jun 20, 2022

    @m-ou-se
    Member

    The bstr crate has a similar API, which also exposes another field/method on the chunks: incomplete, to check whether the incomplete sequence might still become valid if more bytes are added: https://docs.rs/bstr/latest/bstr/struct.Utf8Chunk.html

  2. m-ou-se commented on Jun 20, 2022

    @m-ou-se
    Member

    Regardless of that minor detail, I'm in favor of working towards exposing this as a public API!

  3. added
    initial-comment-periodWill be merged/postponed/closed in ~10 calendar days unless new substational objections are raised.
    disposition-mergeThis RFC is in PFCP or FCP with a disposition to merge it.
    on Jun 20, 2022
  4. dylni commented on Jun 20, 2022

    @dylni
    Author

    Great! I agree that basing the API off bstr would be sensible, so I have updated the issue. The changes were actually surprisingly close already, but providing methods instead of fields will be better for future compatibility.

    I'm leaving out the incomplete method for now, since that can be added later and I don't personally need it. However, I can add it back if it seems useful.

    Also, it might be worth discussing if the constructor should be <[u8]>::utf8_chunks or UtfChunks::new. If I understand the process correctly, that discussion can happen on the tracking issue.

  5. dylni commented on Jul 17, 2022

    @dylni
    Author

    @m-ou-se Is this proposal ready for a PR? It still has the "initial-comment-period" label, so I'm not sure if it's been agreed that this should be added.

  6. m-ou-se commented on Jul 20, 2022

    @m-ou-se
    Member

    @dylni Sorry! We don't have this processs automated yet. Yes, feel free to go ahead and open a tracking issue for this new unstable feature and send a PR for its implementation.

  7. added
    finished-initial-comment-periodThe initial comment period is finished for this API change proposal.
    and removed
    initial-comment-periodWill be merged/postponed/closed in ~10 calendar days unless new substational objections are raised.
    on Jul 20, 2022
  8. dylni commented on Jul 21, 2022

    @dylni
    Author

    Thanks!

    Tracking issue: rust-lang/rust#99543

  9. added a commit that references this issue on Aug 20, 2022
  10. dylni commented on Aug 20, 2022

    @dylni
    Author

    This has been merged: rust-lang/rust#99544

  11. added
    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)
    and removed
    disposition-mergeThis RFC is in PFCP or FCP with a disposition to merge it.
    finished-initial-comment-periodThe initial comment period is finished for this API change proposal.
    on Nov 23, 2023
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

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)api-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions