1. A lot of modules have to use if Code.ensure_loaded statements introducing additional nesting
2. Users of a library with optional dependencies have to include all optional dependencies in their mix.exs
3. Users might include bad varsions of optional dependencies
My proposal is to enhance API for optional dependencies basing on the API provided by Cargo in Rust.
The main idea is that the user of a library with optional dependencies specify which "features" it is willing to have. For example, in membrane_rtc_engine library, which allows you to exchange audio/video using different multimedia protocols, we have a lot of optional dependencies depending on what protocol the user is willing to use. When the user wants to receive media via webrtc and convert it to the HLS to broadcast it to the broader audience it has to include all of those dependencies
# Optional deps for HLS endpoint
{:membrane_aac_plugin, "~> 0.13.0", optional: true},
{:membrane_opus_plugin, "~> 0.16.0", optional: true},
{:membrane_aac_fdk_plugin, "~> 0.14.0", optional: true},
{:membrane_generator_plugin, "~> 0.8.0", optional: true},
{:membrane_realtimer_plugin, "~> 0.6.0", optional: true},
{:membrane_audio_mix_plugin, "~> 0.12.0", optional: true},
{:membrane_raw_audio_format, "~> 0.10.0", optional: true},
{:membrane_h264_ffmpeg_plugin, "~> 0.25.2", optional: true},
{:membrane_audio_filler_plugin, "~> 0.1.0", optional: true},
{:membrane_video_compositor_plugin, "~> 0.2.1", optional: true},
{:membrane_http_adaptive_stream_plugin, "~> 0.11.0", optional: true},
Instead of this, I would love to say to the user, hi if you want to use HLS just specify it in the feature list. For example:
{:membrane_rtc_engine, "~> 0.10.0", features: [:hls]}
It would also be nice to somehow get rid of "if Code.ensure_loaded" statements. I am not sure how yet but Rust do this that way
// This conditionally includes a module which implements WEBP support.
#[cfg(feature = "webp")]
pub mod webp;What comes to my mind is that in mix.exs we can specify "features", their dependencies and a list of modules. When someone asks for the feature, those dependencies are autmatically downloaded and listed modules are compiled.
The final proposal is:
# library side
# mix.exs
features: [
hls: [
dependencies: [],
modules: []
]
]
# user side
# mix.exs
{:membrane_rtc_engine, "~> 0.10.0", features: [:hls]}
I would love to help in implementing those features if you decide they are valuable
Rust reference:
https://doc.rust-lang.org/cargo/reference/features.html#features