hyperium / mime

MIMEs in Rust
https://docs.rs/mime
MIT License
174 stars 76 forks source link

Propose Tenets/Values #154

Open seanmonstar opened 1 year ago

seanmonstar commented 1 year ago

This is my attempt at writing up some design tenets for the mime crate. I've tried a few times to create a good library, and have failed to find time to come up with a design to fit these (see #153). Hopefully writing these up will allow others to discuss and create a proposal and then implement one.

Note that these values aren't necessarily in the right order yet, but I think they largely match what is important.

Parse, don't validate

Construct a media type should parse it, ensuring the values are legal characters and the structure is correct. It should not be possible to build one manually without verification, so that other functions and libraries may rely on the value only containing legal characters.

This would imply that the internal fields are all private.

Easy construction

It would be preferable that constructing a media type were "easy", such that it didn't require a bunch of type imports. Fluid, type-safe construction is a plus, but only if it is convenient.

Specifically, it must be possible to construct a media type as a compile-time constant. We aren't going to have a full registry of all the possible types, and if someone knows their media type beforehand, it should be cheap/free to construct it.

Expressive matching

Besides creating parsed/valid media types, another significant reason to do so is to allow for expressive matching. Rust has power pattern matching, it would be a shame if we could do something to the effect of:

match mt.substance() {
    (Text, Plain) => (),
    (Text, _) => (),
    _ => (),
}

Another possible way of being expressive is using traits. Then, someone could restrict a media type further, by saying "only text media types, such as download<M: mime::Text>(m: M). Could be over-engineering, though.

Types vs Ranges

Some implementations conflate the concepts of a media types and media ranges. For instance, text/* is valid media range for an Accept header, but it is not a valid type to send in a Content-Type header.

Thus, it would make sense to make the common */* and such illegal, or be required to be a separate type, such as a MediaRange.

However, dealing with q-values is likely out of scope for this crate. (q-values are a more general concept that apply to several kinds of Accept-* headers).

Performance

It is preferable that parsing media types and rendering mime types be as fast as possible. The easiest thing to do would be to construct a bunch of separated Strings, but we should prefer less allocating and copying. This is another reason it would be wise to keep the fields and internals private; we can do performance optimizations freely.

Tpt commented 1 year ago

Thank you for that!

Two suggestions:

wiiznokes commented 4 months ago

Some ideas: