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}