Skip to content

Commit 6770b25

Browse files
authored
Merge pull request #8 from greyblake/kind-trait
Add Kind trait
2 parents af707f4 + 52ff2cd commit 6770b25

File tree

5 files changed

+50
-18
lines changed

5 files changed

+50
-18
lines changed

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,12 @@ impl Kinded for Drink {
6262

6363
The `Kinded` trait allows to build abstract functions that can be used with different enum types.
6464

65-
## Iterating
65+
## Get all kind variants
6666

67-
The kind type gets implementation of `::all()` associated function, which returns an iterator over all kind variants.
68-
For example:
67+
The kind type gets implementation of `::all()` associated function, which returns a vector with all kind variants:
6968

7069
```rs
71-
let all_drink_kinds: Vec<_> = DrinkKind::all().collect();
72-
assert_eq!(all_drink_kinds, vec![DrinkKind::Mate, DrinkKind::Coffee, DrinkKind::Tea]);
70+
assert_eq!(DrinkKind::all(), vec![DrinkKind::Mate, DrinkKind::Coffee, DrinkKind::Tea]);
7371
```
7472

7573

kinded/src/lib.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,9 @@
6161
//!
6262
//! The `Kinded` trait allows to build abstract functions that can be used with different enum types.
6363
//!
64-
//! ## Iterating
64+
//! ## Get all kind variants
6565
//!
66-
//! The kind type gets implementation of `::all()` associated function, which returns an iterator over all kind variants.
67-
//! For example:
66+
//! The kind type gets implementation of `::all()` associated function, which returns a vector with all kind variants:
6867
//!
6968
//! ```
7069
//! use kinded::Kinded;
@@ -76,8 +75,7 @@
7675
//! Tea { variety: String, caffeine: bool }
7776
//! }
7877
//!
79-
//! let all_drink_kinds: Vec<_> = DrinkKind::all().collect();
80-
//! assert_eq!(all_drink_kinds, vec![DrinkKind::Mate, DrinkKind::Coffee, DrinkKind::Tea]);
78+
//! assert_eq!(DrinkKind::all(), vec![DrinkKind::Mate, DrinkKind::Coffee, DrinkKind::Tea]);
8179
//! ```
8280
//!
8381
//! ## Attributes
@@ -194,4 +192,4 @@ mod traits;
194192

195193
pub use errors::ParseKindError;
196194
pub use kinded_macros::Kinded;
197-
pub use traits::Kinded;
195+
pub use traits::{Kind, Kinded};

kinded/src/traits.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ use ::core::fmt::Debug;
33
/// A trait that can be implemented by a main enum type.
44
/// Typically should be derived with `#[derive(kinded::Kinded)]`.
55
pub trait Kinded {
6-
type Kind: PartialEq + Eq + Debug + Clone + Copy;
6+
type Kind: PartialEq + Eq + Debug + Clone + Copy + Kind;
77

8+
/// Get a kind variant without data.
89
fn kind(&self) -> Self::Kind;
910
}
11+
12+
pub trait Kind: PartialEq + Eq + Debug + Clone + Copy {
13+
/// Return a vector with all possible kind variants.
14+
fn all() -> Vec<Self>;
15+
}

kinded_macros/src/gen/kind_enum.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ pub fn gen_kind_enum(meta: &Meta) -> TokenStream {
77
let impl_from_traits = gen_impl_from_traits(meta);
88
let impl_display_trait = gen_impl_display_trait(meta);
99
let impl_from_str_trait = gen_impl_from_str_trait(meta);
10+
let impl_kind_trait = gen_impl_kind_trait(meta);
1011

1112
quote!(
1213
#kind_enum_definition
1314
#impl_from_traits
1415
#impl_display_trait
1516
#impl_from_str_trait
17+
#impl_kind_trait
1618
)
1719
}
1820

@@ -29,10 +31,10 @@ fn gen_definition(meta: &Meta) -> TokenStream {
2931
} // }
3032

3133
impl #kind_name { // impl DrinkKind {
32-
pub fn all() -> impl Iterator<Item = #kind_name> { // pub fn all() -> impl Iterator<Item = DrinkKind> {
33-
[ // [
34+
pub fn all() -> Vec<#kind_name> { // pub fn all() -> Vec<DrinkKind> {
35+
vec![ // vec![
3436
#(#kind_name::#variant_names),* // DrinkKind::Mate, DrinkKind::Coffee, DrinkKind::Tea
35-
].into_iter() // ]
37+
] // ]
3638
} // }
3739
} // }
3840
)
@@ -131,3 +133,15 @@ fn gen_impl_from_str_trait(meta: &Meta) -> TokenStream {
131133
}
132134
)
133135
}
136+
137+
fn gen_impl_kind_trait(meta: &Meta) -> TokenStream {
138+
let kind_name = meta.kind_name();
139+
140+
quote!(
141+
impl ::kinded::Kind for #kind_name {
142+
fn all() -> Vec<#kind_name> {
143+
Self::all()
144+
}
145+
}
146+
)
147+
}

test_suite/src/lib.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ enum Role {
1313
},
1414
}
1515

16-
mod base_enum {
16+
mod main_enum {
1717
use super::*;
1818

1919
mod fn_kind {
@@ -271,13 +271,29 @@ mod kind_enum {
271271
assert_eq!("MySQL".parse::<DbKind>().unwrap(), DbKind::MySQL);
272272
}
273273
}
274+
275+
mod kind_trait {
276+
use crate::RoleKind;
277+
278+
fn get_all_kinds<T: kinded::Kind>() -> Vec<T> {
279+
T::all()
280+
}
281+
282+
#[test]
283+
fn should_implement_kind_trait() {
284+
let kinds = get_all_kinds::<RoleKind>();
285+
assert_eq!(
286+
kinds,
287+
vec![RoleKind::Guest, RoleKind::User, RoleKind::Admin]
288+
)
289+
}
290+
}
274291
}
275292

276293
#[test]
277294
fn should_provide_all_function_that_returns_iterator() {
278-
let kinds: Vec<_> = RoleKind::all().collect();
279295
assert_eq!(
280-
kinds,
296+
RoleKind::all(),
281297
vec![RoleKind::Guest, RoleKind::User, RoleKind::Admin],
282298
)
283299
}

0 commit comments

Comments
 (0)