HashMap<K,V>
multibinding
Similar to Vec<T> multibinding
,
a #[provides]
or
#[binds]
binding can
also be marked with
the #[into_map]
attribute, which collects the key-value pair into
a HashMap
While a map can be created by multibinding Vec<(K,V)>
or some other entry generating mechanisms,
the HashMap<K,V>
multibinding has additional compile time checks to make sure there are no key
collisions.
Map keys
The value type is specified by the binding method return value, but the key type and value needs to
be specified by a metadata in the #[into_map]
attribute.
string_key
string_key
specifies the map key is
a String
. The value must be a string
literal, lockjaw is unable to resolve more complex compile time constants.
This example binds to HashMap<String,String>
:
#[provides]
#[into_map(string_key: "1")]
pub fn provide_string1() -> String {
"string1".to_owned()
}
#[provides]
#[into_map(string_key: "2")]
pub fn provide_string2() -> String {
"string2".to_owned()
}
i32_key
i32_key
specifies the map key is an i32
. The value must be an i32 literal, lockjaw is unable to
resolve more complex compile time constants.
This example binds to HashMap<i32,String>
:
#[provides]
#[into_map(i32_key: 1)]
pub fn provide_i32_string1() -> String {
"string1".to_owned()
}
#[provides]
#[into_map(i32_key: 2)]
pub fn provide_i32_string2() -> String {
"string2".to_owned()
}
Other types are not implemented. i32
ought to be enough for everyone.
enum_key
i32_key
specifies the map key is an enum
. Since the enum
is going to be used as the map key,
it must satisfy the same constraints HashMap
gives, which is
implementing Eq
and Hash
. It also must be a simple enum with
no fields so Lockjaw knows how to compare them at compile time (meaning comparing the name is
enough).
#[derive(Eq, PartialEq, Hash)]
pub enum E {
Foo,
Bar,
}
This example binds to HashMap<E,String>
:
#[provides]
#[into_map(enum_key: E::Foo)]
pub fn provide_enum_string1() -> String {
"string1".to_owned()
}
#[provides]
#[into_map(enum_key: Bar)]
pub fn provide_enum_string2() -> String {
"string2".to_owned()
}
Lockjaw is able to infer the enum type (E
) if the value is imported (use E::Bar
), but the code
maybe be more readable if the type is explicitly spelled out, especially most IDEs today cannot
properly inspect tokens inside the metadata.
Qualifiers
#[into_map]
can also be #[qualified]
#[provides]
#[qualified(Q)]
#[into_map(string_key: "1")]
pub fn provide_q_string1() -> String {
"q_string1".to_owned()
}
Which result in #[qualified(Q)] HashMap<String, String>
. Note that the container is qualified
instead of the content.
Dynamic map entries
All bindings in #[into_map]
must be resolved at compile time, There are
no #[elements_into_vec]
equivalent such as #[elements_into_map]
.
However dynamic map entries can be achieved by rebinding Vec<(K,V)>
into a HashMap<K,V>
.
Examples
https://github.com/azureblaze/lockjaw/blob/main/tests/module_provides_into_map.rs