quil_rs/
reserved.rs

1//! This module contains enums for reserved tokens in [quil](https://quil-lang.github.io)
2
3use std::{fmt::Display, str::FromStr};
4
5use strum;
6
7pub use crate::parser::{Command, DataType, KeywordToken, Modifier};
8
9/// An enum that can represent any reserved token in quil.
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub enum ReservedToken {
12    Command(Command),
13    DataType(DataType),
14    Modifier(Modifier),
15    OtherKeyword(KeywordToken),
16    Gate(ReservedGate),
17    Constant(ReservedConstant),
18}
19
20#[derive(Clone, Debug, thiserror::Error)]
21#[error("{0} is not a reserved token")]
22pub struct NotReservedToken(String);
23
24impl FromStr for ReservedToken {
25    type Err = NotReservedToken;
26
27    fn from_str(s: &str) -> Result<Self, Self::Err> {
28        fn parse<T: FromStr>(
29            reserved: impl Fn(T) -> ReservedToken,
30            s: &str,
31        ) -> Result<ReservedToken, T::Err> {
32            T::from_str(s).map(reserved)
33        }
34
35        parse(Self::Command, s)
36            .or_else(|_| parse(Self::DataType, s))
37            .or_else(|_| parse(Self::Modifier, s))
38            .or_else(|_| parse(Self::OtherKeyword, s))
39            .or_else(|_| parse(Self::Gate, s))
40            .or_else(|_| parse(Self::Constant, s))
41            .map_err(|_| NotReservedToken(s.to_string()))
42    }
43}
44
45impl Display for ReservedToken {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        match self {
48            Self::Command(command) => write!(f, "{command}"),
49            Self::DataType(data_type) => write!(f, "{data_type}"),
50            Self::Modifier(modifier) => write!(f, "{modifier}"),
51            Self::OtherKeyword(keyword_token) => write!(f, "{keyword_token}"),
52            Self::Gate(gate) => write!(f, "{gate}"),
53            Self::Constant(constant) => write!(f, "{constant}"),
54        }
55    }
56}
57
58/// Every reserved Gate identifier
59#[derive(Clone, Copy, Debug, PartialEq, Eq, strum::Display, strum::EnumString)]
60#[strum(serialize_all = "UPPERCASE")]
61#[allow(clippy::upper_case_acronyms)]
62pub enum ReservedGate {
63    CAN,
64    CCNOT,
65    CNOT,
66    CPHASE,
67    CPHASE00,
68    CPHASE01,
69    CPHASE10,
70    CSWAP,
71    CZ,
72    H,
73    I,
74    ISWAP,
75    PHASE,
76    PISWAP,
77    PSWAP,
78    RX,
79    RY,
80    RZ,
81    S,
82    SWAP,
83    T,
84    X,
85    XY,
86    Y,
87    Z,
88}
89
90/// Every reserved constant
91#[derive(Clone, Copy, Debug, PartialEq, Eq, strum::Display, strum::EnumString)]
92#[strum(serialize_all = "lowercase")]
93pub enum ReservedConstant {
94    #[strum(serialize = "i")]
95    Imaginary,
96    Pi,
97}