nextest_runner/config/
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)]
11pub struct TestPriority(i8);
12
13impl TestPriority {
14    /// Creates a new `TestPriority`.
15    pub fn new(priority: i8) -> Result<Self, TestPriorityOutOfRange> {
16        if !(-100..=100).contains(&priority) {
17            return Err(TestPriorityOutOfRange { priority });
18        }
19        Ok(Self(priority))
20    }
21
22    /// Returns the priority as an `i8`.
23    pub fn to_i8(self) -> i8 {
24        self.0
25    }
26}
27
28impl PartialOrd for TestPriority {
29    #[inline]
30    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
31        Some(self.cmp(other))
32    }
33}
34
35impl Ord for TestPriority {
36    #[inline]
37    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
38        // Reverse the order to sort from highest to lowest priority.
39        other.0.cmp(&self.0)
40    }
41}
42
43impl<'de> Deserialize<'de> for TestPriority {
44    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
45    where
46        D: Deserializer<'de>,
47    {
48        let priority = i8::deserialize(deserializer)?;
49        TestPriority::new(priority).map_err(serde::de::Error::custom)
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn priority_out_of_range() {
59        let priority = TestPriority::new(-101);
60        priority.expect_err("priority must be between -100 and 100");
61
62        let priority = TestPriority::new(101);
63        priority.expect_err("priority must be between -100 and 100");
64    }
65
66    #[test]
67    fn priority_deserialize() {
68        let priority: TestPriority = serde_json::from_str("-100").unwrap();
69        assert_eq!(priority.to_i8(), -100);
70
71        let priority: TestPriority = serde_json::from_str("0").unwrap();
72        assert_eq!(priority.to_i8(), 0);
73
74        let priority: TestPriority = serde_json::from_str("100").unwrap();
75        assert_eq!(priority.to_i8(), 100);
76
77        let priority: Result<TestPriority, _> = serde_json::from_str("-101");
78        priority.expect_err("priority must be between -100 and 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
84    #[test]
85    fn priority_sort_order() {
86        let mut priorities = vec![
87            TestPriority::new(0).unwrap(),
88            TestPriority::new(100).unwrap(),
89            TestPriority::new(-100).unwrap(),
90        ];
91        priorities.sort();
92        assert_eq!(
93            priorities,
94            [
95                TestPriority::new(100).unwrap(),
96                TestPriority::new(0).unwrap(),
97                TestPriority::new(-100).unwrap()
98            ]
99        );
100    }
101}