Skip to main content

nextest_runner/config/elements/
priority.rs

1// Copyright (c) The nextest Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use crate::errors::TestPriorityOutOfRange;
5use serde::{Deserialize, Deserializer};
6
7/// A test priority: a number between -100 and 100.
8///
9/// The sort order is from highest to lowest priority.
10#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
11#[cfg_attr(feature = "config-schema", derive(schemars::JsonSchema))]
12pub struct TestPriority(
13    #[cfg_attr(feature = "config-schema", schemars(range(min = -100, max = 100)))] i8,
14);
15
16impl TestPriority {
17    /// Creates a new `TestPriority`.
18    pub fn new(priority: i8) -> Result<Self, TestPriorityOutOfRange> {
19        if !(-100..=100).contains(&priority) {
20            return Err(TestPriorityOutOfRange { priority });
21        }
22        Ok(Self(priority))
23    }
24
25    /// Returns the priority as an `i8`.
26    pub fn to_i8(self) -> i8 {
27        self.0
28    }
29}
30
31impl PartialOrd for TestPriority {
32    #[inline]
33    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
34        Some(self.cmp(other))
35    }
36}
37
38impl Ord for TestPriority {
39    #[inline]
40    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
41        // Reverse the order to sort from highest to lowest priority.
42        other.0.cmp(&self.0)
43    }
44}
45
46impl<'de> Deserialize<'de> for TestPriority {
47    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
48    where
49        D: Deserializer<'de>,
50    {
51        let priority = i8::deserialize(deserializer)?;
52        TestPriority::new(priority).map_err(serde::de::Error::custom)
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn priority_out_of_range() {
62        let priority = TestPriority::new(-101);
63        priority.expect_err("priority must be between -100 and 100");
64
65        let priority = TestPriority::new(101);
66        priority.expect_err("priority must be between -100 and 100");
67    }
68
69    #[test]
70    fn priority_deserialize() {
71        let priority: TestPriority = serde_json::from_str("-100").unwrap();
72        assert_eq!(priority.to_i8(), -100);
73
74        let priority: TestPriority = serde_json::from_str("0").unwrap();
75        assert_eq!(priority.to_i8(), 0);
76
77        let priority: TestPriority = serde_json::from_str("100").unwrap();
78        assert_eq!(priority.to_i8(), 100);
79
80        let priority: Result<TestPriority, _> = serde_json::from_str("-101");
81        priority.expect_err("priority must be between -100 and 100");
82
83        let priority: Result<TestPriority, _> = serde_json::from_str("101");
84        priority.expect_err("priority must be between -100 and 100");
85    }
86
87    #[test]
88    fn priority_sort_order() {
89        let mut priorities = vec![
90            TestPriority::new(0).unwrap(),
91            TestPriority::new(100).unwrap(),
92            TestPriority::new(-100).unwrap(),
93        ];
94        priorities.sort();
95        assert_eq!(
96            priorities,
97            [
98                TestPriority::new(100).unwrap(),
99                TestPriority::new(0).unwrap(),
100                TestPriority::new(-100).unwrap()
101            ]
102        );
103    }
104}