whitaker_common/attributes/helpers.rs
1//! Helpers for working with attribute collections.
2
3use super::{Attribute, AttributePath};
4
5/// Splits a slice of attributes into doc and non-doc groups.
6///
7/// # Examples
8///
9/// ```
10/// use whitaker_common::attributes::{split_doc_attributes, Attribute, AttributeKind, AttributePath};
11///
12/// let doc = Attribute::new(AttributePath::from("doc"), AttributeKind::Outer);
13/// let allow = Attribute::new(AttributePath::from("allow"), AttributeKind::Outer);
14/// let attributes = vec![doc.clone(), allow.clone()];
15/// let (docs, rest) = split_doc_attributes(&attributes);
16/// assert_eq!(docs.len(), 1);
17/// assert_eq!(rest.len(), 1);
18/// ```
19#[must_use]
20pub fn split_doc_attributes(attrs: &[Attribute]) -> (Vec<&Attribute>, Vec<&Attribute>) {
21 attrs.iter().partition(|attr| attr.is_doc())
22}
23
24/// Returns the subset of attributes that apply as outer attributes.
25///
26/// # Examples
27///
28/// ```
29/// use whitaker_common::attributes::{outer_attributes, Attribute, AttributeKind, AttributePath};
30///
31/// let inner = Attribute::new(AttributePath::from("doc"), AttributeKind::Inner);
32/// let outer = Attribute::new(AttributePath::from("test"), AttributeKind::Outer);
33/// let attributes = vec![inner, outer.clone()];
34/// let outer_only = outer_attributes(&attributes);
35/// assert_eq!(outer_only, vec![&outer]);
36/// ```
37#[must_use]
38pub fn outer_attributes(attrs: &[Attribute]) -> Vec<&Attribute> {
39 attrs.iter().filter(|attr| attr.is_outer()).collect()
40}
41
42/// Returns `true` when any attribute marks the item as test-like.
43///
44/// # Examples
45///
46/// ```
47/// use whitaker_common::attributes::{has_test_like_attribute, Attribute, AttributeKind, AttributePath};
48///
49/// let attr = Attribute::new(AttributePath::from("tokio::test"), AttributeKind::Outer);
50/// assert!(has_test_like_attribute(&[attr]));
51/// ```
52#[must_use]
53pub fn has_test_like_attribute(attrs: &[Attribute]) -> bool {
54 has_test_like_attribute_with(attrs, &[])
55}
56
57/// Returns `true` when any attribute marks the item as test-like, accounting
58/// for custom attribute paths supplied at runtime.
59///
60/// # Examples
61///
62/// ```
63/// use whitaker_common::attributes::{has_test_like_attribute_with, Attribute, AttributeKind, AttributePath};
64///
65/// let attr = Attribute::new(AttributePath::from("custom::test"), AttributeKind::Outer);
66/// let additional = vec![AttributePath::from("custom::test")];
67/// assert!(has_test_like_attribute_with(&[attr], &additional));
68/// ```
69#[must_use]
70pub fn has_test_like_attribute_with(attrs: &[Attribute], additional: &[AttributePath]) -> bool {
71 attrs
72 .iter()
73 .any(|attribute| attribute.is_test_like_with(additional))
74}