```rust use degenericmacros::{Degeneric, namedrequirement}; use std::marker::PhantomData;
named_requirement!(FactoryFn
struct Container
fn my_fact() -> String { format!("hello world!") }
let c = Container::builder() .witha(myfact) .withb(true) .withc(20) .with__t(Default::default()) .build();
fn dosomething(c: impl ContainerTrait) {}
fn accessinnertypes
Degeneric is a utility library that solves the common problem of having too many generics.
Let's say we want to construct a dependency container like this:
```rust
struct Container
let container = Container { logger: String::from("logger"), client: String::from("http"), };
acceptscontainer(container);
// now to consume such a container, one needs to write the function like this:
fn acceptscontainer
This creates a problem of ever growing list of generics in all functions that touch the container and pollutes APIs with unnecessary generics.
Degeneric proposes solution to this problem by creating a trait and stuffing all of the generic types into the trait as associated types. Instead of the pattern above, you'll end up with this: ```rust use degeneric_macros::Degeneric;
struct Container
let c = Container::builder() .withlogger(String::from("logger")) .withclient(String::from("http")) .build();
acceptscontainer(c); fn acceptscontainer(c: impl ContainerTrait) {} ```
How is this different, you ask? Instead of accepting a whole lot of generic arguments, I can now write
the function without even using angular brackets and I think that's beautiful.
What is even more beautiful is that you can add more generics without having to modify the
signature of accepts_container
.