1 /// Describes the arithmetic operation in an atomic memory read-modify-write operation.
2 use core::fmt::{self, Display, Formatter};
3 use core::str::FromStr;
4 #[cfg(feature = "enable-serde")]
5 use serde_derive::{Deserialize, Serialize};
6 
7 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
8 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
9 /// Describes the arithmetic operation in an atomic memory read-modify-write operation.
10 pub enum AtomicRmwOp {
11     /// Add
12     Add,
13     /// Sub
14     Sub,
15     /// And
16     And,
17     /// Nand
18     Nand,
19     /// Or
20     Or,
21     /// Xor
22     Xor,
23     /// Exchange
24     Xchg,
25     /// Unsigned min
26     Umin,
27     /// Unsigned max
28     Umax,
29     /// Signed min
30     Smin,
31     /// Signed max
32     Smax,
33 }
34 
35 impl AtomicRmwOp {
36     /// Returns a slice with all supported [AtomicRmwOp]'s.
all() -> &'static [AtomicRmwOp]37     pub fn all() -> &'static [AtomicRmwOp] {
38         &[
39             AtomicRmwOp::Add,
40             AtomicRmwOp::Sub,
41             AtomicRmwOp::And,
42             AtomicRmwOp::Nand,
43             AtomicRmwOp::Or,
44             AtomicRmwOp::Xor,
45             AtomicRmwOp::Xchg,
46             AtomicRmwOp::Umin,
47             AtomicRmwOp::Umax,
48             AtomicRmwOp::Smin,
49             AtomicRmwOp::Smax,
50         ]
51     }
52 }
53 
54 impl Display for AtomicRmwOp {
fmt(&self, f: &mut Formatter) -> fmt::Result55     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
56         let s = match self {
57             AtomicRmwOp::Add => "add",
58             AtomicRmwOp::Sub => "sub",
59             AtomicRmwOp::And => "and",
60             AtomicRmwOp::Nand => "nand",
61             AtomicRmwOp::Or => "or",
62             AtomicRmwOp::Xor => "xor",
63             AtomicRmwOp::Xchg => "xchg",
64             AtomicRmwOp::Umin => "umin",
65             AtomicRmwOp::Umax => "umax",
66             AtomicRmwOp::Smin => "smin",
67             AtomicRmwOp::Smax => "smax",
68         };
69         f.write_str(s)
70     }
71 }
72 
73 impl FromStr for AtomicRmwOp {
74     type Err = ();
from_str(s: &str) -> Result<Self, Self::Err>75     fn from_str(s: &str) -> Result<Self, Self::Err> {
76         match s {
77             "add" => Ok(AtomicRmwOp::Add),
78             "sub" => Ok(AtomicRmwOp::Sub),
79             "and" => Ok(AtomicRmwOp::And),
80             "nand" => Ok(AtomicRmwOp::Nand),
81             "or" => Ok(AtomicRmwOp::Or),
82             "xor" => Ok(AtomicRmwOp::Xor),
83             "xchg" => Ok(AtomicRmwOp::Xchg),
84             "umin" => Ok(AtomicRmwOp::Umin),
85             "umax" => Ok(AtomicRmwOp::Umax),
86             "smin" => Ok(AtomicRmwOp::Smin),
87             "smax" => Ok(AtomicRmwOp::Smax),
88             _ => Err(()),
89         }
90     }
91 }
92 
93 #[cfg(test)]
94 mod tests {
95     use super::*;
96 
97     #[test]
roundtrip_parse()98     fn roundtrip_parse() {
99         for op in AtomicRmwOp::all() {
100             let roundtripped = format!("{op}").parse::<AtomicRmwOp>().unwrap();
101             assert_eq!(*op, roundtripped);
102         }
103     }
104 }
105