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

Propose Tenets/Values #154

Open
Tracked by #153
seanmonstar opened this issue Aug 21, 2023 · 2 comments
Open
Tracked by #153

Propose Tenets/Values #154

seanmonstar opened this issue Aug 21, 2023 · 2 comments

Comments

@seanmonstar
Copy link
Member

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
Copy link

Tpt commented Aug 24, 2023

Thank you for that!

Two suggestions:

  • normalize either on the "media type" or the "MIME type" naming. mime::MediaRange looks a bit confusing to me.
  • choose which specification to follow, the web browsers one or just the IETF one. I would tend to suggest following the web browsers one that is more "practical" and reflects what web browsers are actually doing.

@wiiznokes
Copy link

Some ideas:

  • use this web site (or another one) to generate all known mime types.
  • Allow passing a path through ENV variable pointing to a file with mime types defined with the same format, to add some mime types that weren't inside the external source
  • parsing the string using a finite automata, generated at compile time

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

3 participants