etest/resource/
id.rs

1use std::borrow::Cow;
2
3/// A resource which can be "used" or "consumed"
4///
5/// To be used with the `uses` and `consumes` parameters of `#[etest]`.  For type
6/// safety custom types can be specified which implement `Into<ResourceId>`.
7///
8/// E.g.
9///
10/// ```
11/// # use etest::ResourceId;
12/// # fn is_hdmi_connected() -> bool { true }
13/// enum Output {
14///     Auto,
15///     Hdmi,
16///     Lvds,
17/// }
18///
19/// impl From<Output> for ResourceId
20/// {
21///     fn from(o: Output) -> Self {
22///         let o = match o {
23///             // this is evaluated at runtime of the test
24///             Output::Auto if is_hdmi_connected() => Output::Hdmi,
25///             Output::Auto                        => Output::Lvds,
26///             o => o,
27///         };
28///
29///         match o {
30///             Output::Hdmi => "hdmi".into(),
31///             Output::Lvds => "lvds".into(),
32///             Output::Auto => unreachable!(),
33///         }
34///     }
35/// }
36///
37/// # use etest::etest;
38/// #[etest(consumes=[Output])]
39/// fn test() {}
40/// ```
41#[derive(Debug, Clone, Hash, Eq, PartialEq)]
42pub enum ResourceIdImpl<'a> {
43    /// Normal resource
44    Id(Cow<'a, str>),
45
46    /// An empty resource which will be ignored.
47    ///
48    /// Used e.g. when generating a list of resources dynamically where some
49    /// of the resources are optional and can be omitted.
50    None,
51
52    /// Basic resource which is used by all tests.
53    ///
54    /// Unless specified else (by the `no_default_uses` attribute), this
55    /// resource will be implicitly added to the "uses" list of every test.
56    /// To avoid parallel execution with other ones, a test can add this
57    /// resource type to its "consumes" list by the `notparallel` attribute.
58    Basic,
59}
60
61pub type ResourceId = ResourceIdImpl<'static>;
62
63impl <'a> ResourceIdImpl<'a> {
64    pub const fn new(id: &'a str) -> Self {
65        Self::Id(Cow::Borrowed(id))
66    }
67
68    pub fn from_string(s: String) -> Self {
69        Self::Id(Cow::Owned(s))
70    }
71
72    pub fn is_some(&self) -> bool {
73        self != &Self::None
74    }
75}
76
77impl <'a> From<&'a str> for ResourceIdImpl<'a> {
78    fn from(val: &'a str) -> Self {
79        Self::new(val)
80    }
81}
82
83impl From<String> for ResourceIdImpl<'_> {
84    fn from(val: String) -> Self {
85        Self::from_string(val)
86    }
87}
88
89/// Maps an option to a [`ResourceId`].
90///
91/// Value of `None` maps to the special [`ResourceId::None`] resource type
92/// which will be ignored when building list of resources dynamically.
93impl <'a, T> From<Option<T>> for ResourceIdImpl<'a>
94where
95    T: Into<ResourceIdImpl<'a>>,
96{
97    fn from(val: Option<T>) -> Self {
98        match val {
99            None	=> Self::None,
100            Some(v)	=> v.into(),
101        }
102    }
103}