Motivation

We already have features, which allow for additional code to be compiled, only if the user needs it. In a case, where two libraries depend on such a library, one library might need a feature the other library does not need. The solution is to compile all requested features, which is only guaranteed to work if every feature is purely additive. However, suppose you want to write a graphics library with support for different backends. The most common solution is to use traits and type parameters in order to allow this, which leads to over-generalization (who wants to use multiple backends at the same time) and often, a dependent library uses type definitions (like type Window = graphics::Window<GlBackend> ). What would be helpful here, is an option to select a backend in the Cargo.toml . This is what flavors are about.

Design

Note: Just some rough ideas to start the discussion

Add a new table to Cargo.toml , [flavors]

, Every flavor is another table

If flavors conflict, link to the library twice (like cargo is already doing for two incompatible versions)

Drawbacks

Not yet resolved / depending on design choices

Bigger executable size if incompatible flavors are used Are flavors mostly used in libraries with just a single dependent library? Can we minimize code duplication if a library has multiple flavors, all with structs / functions they have in common? Should the a library foo offering flavors provide all common items in a dependent library, foo-core ?



Alternatives

In some situations, traits & type parameters not possible to provide different functionality eventually more complex code

Code duplication: GlWindow , VkWindow , DxWindow … may be macro-provided

, , … features, not keeping their promises

one library per flavor

Unresolved question

Which guarantees does a library make about flavors? Should another flavor always provide the same items (checked by the compiler)? -> you cannot forget anything more limited, flavors cannot offer different functionality

Should there be just one set of flavors or multiple flavors like this:

[flavors.backend] flavors = ["opengl", "vulkan"] [flavors.threadpool] flavors = ["rayon", "rust-threadpool"]

How do flavors work together with features? How to specify dependencies of a flavor?

What drawbacks are there?

Many, many more

Thanks for reading this, feel free to make suggestions on how to improve this.