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

Buf/ButMut bounds should be ?Sized #934

Open
jrose-signal opened this issue Oct 18, 2023 · 2 comments
Open

Buf/ButMut bounds should be ?Sized #934

jrose-signal opened this issue Oct 18, 2023 · 2 comments

Comments

@jrose-signal
Copy link

&[u8] implements Buf and &mut [u8] implements BufMut, but you can't use either with Prost APIs because of the implicit Sized bound on generic parameters. Fortunately there's a workaround, &&buf and &mut &mut buf, but it would be nice™ to add ?Sized to all the uses of Buf and ButMut to make this unnecessary. Unfortunately, that's a breaking change for anyone who's manually implemented the methods on the Message trait, which somebody probably has.

(In my particular case I noticed this when trying to use encode_length_delimiter, which doesn't even need Message, but changing just the length delimiter APIs seems odd, since it'll leave the crate in an inconsistent state.)

@caspermeijn
Copy link
Collaborator

Can you provide a minimal, reproducible example for when this is a problem?

@jrose-signal
Copy link
Author

jrose-signal commented Feb 13, 2024

fn encode<T: AsRef<[u8]>>(
    items: impl Iterator<Item = T>,
    is_valid: impl Fn(&T) -> bool,
    handle_result: impl FnOnce(&[u8]),
) {
    let mut count = 0;
    let mut output: Vec<u8> = vec![0, 0]; // Reserve space for up to 1^14 items
    for item in items {
        if is_valid(&item) {
            count += 1;
            output.extend(item.as_ref());
        }
    }
    let result = match length_delimiter_len(count) {
        1 => {
            encode_length_delimiter(&mut output[1..][..1]).unwrap();
            &output[1..]
        }
        2 => {
            encode_length_delimiter(&mut output[..2]).unwrap();
            &output
        }
        _ => {
            panic!("too many items");
        }
    };
    handle_result(result);
}

A bit contrived but not too far off. I see how it could be instead done by writing to &mut &mut output[..2] and then adjusting after the fact, or using a second Vec, but I don't think what I have is unreasonable either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants