mediatype icon indicating copy to clipboard operation
mediatype copied to clipboard

Relationship between `MediaType` and `MediaTypeBuf`

Open WhyNotHugo opened this issue 2 years ago • 4 comments

I tried to think of MediaType and MediaTypeBuf as analogous to Path and PathBuf or &str and String, but they don't seen to interact in the same way.

Notably, I can write a function that takes either &str or String:

fn func<S: AsRef<str>>(string: S) {
    println!("{}", string.as_ref());
}

Or a function that takes Path and PathBuf

fn func2<P: AsRef<Path>>(path: P) {
    println!("{:?}", path.as_ref());
}

But I don't quite see the relationship between MediaType and MediaTypeBuf. There don't seem to be any methods to cast between one to the other. MediaType also doesn't have a to_str() or similar function.

I'm trying to write a function where a mime type needs to be passed as parameter. Currently it takes mime_type: MimeType, where MimeType: AsRef<[u8]>.

Do you have any insight for me on this case? Do you think that mediatype is a good fit here, or am I trying to fix square peg into round hole?

WhyNotHugo avatar Jun 27 '23 09:06 WhyNotHugo

Looking closer at the implementation, I see that MediaType does actually have any reference to a string (or bytes) with the mime type; only separate bits which are non-continuous.

So I guess that there's no way to get a &str or &[u8] without more expensive shuffling.

WhyNotHugo avatar Jun 27 '23 09:06 WhyNotHugo

OTOH, MediaTypeBuf cannot be constructed in a const context, so one can't have a few const variables for the commonly used types in a crate.

So using MediaTypeBuf is flexible with consumers for the unusual case, but more expensive for the common case.

I guess the real tricky part is the inability to cast between the two. Are they mostly incompatible implementations?

WhyNotHugo avatar Jun 27 '23 09:06 WhyNotHugo

@WhyNotHugo MediaTypeBuf and MediaType have very different inner structures so I could not implement AsRef. You can convert MediaTypeBuf to MediaType using MediaTypeBuf::to_ref.

picoHz avatar Jul 02 '23 10:07 picoHz

I made the two separate types for different situations because it is impossible to accomplish both const-constructibility and owned-type in a single type. You can cast between MediaTypeBuf and MediaType but it's not same as str and String.

let text_plain = MediaType::parse("text/plain; charset=UTF-8").unwrap();
let text_plain: MediaTypeBuf = text_plain.into();
let text_plain_ref: MediaType = text_plain.to_ref();
let text_plain_ref: MediaType = (&text_plain).into();

I'm trying to write a function where a mime type needs to be passed as parameter. Currently it takes mime_type: MimeType, where MimeType: AsRef<[u8]>.

Do you have any insight for me on this case? Do you think that mediatype is a good fit here, or am I trying to fix square peg into round hole?

For the function parameter, I recommend to use MediaType. You can construct it from an arbitrary string using MediaType::parse.

picoHz avatar Jul 02 '23 11:07 picoHz