quil_rs/program/error/
mod.rs

1// Copyright 2021 Rigetti Computing
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15mod leftover;
16mod result;
17mod syntax;
18
19use std::error::Error;
20use std::fmt;
21use std::fmt::Formatter;
22
23use crate::instruction::Instruction;
24use crate::parser::{LexError, ParseError};
25use crate::quil::Quil;
26pub use leftover::LeftoverError;
27pub use result::{disallow_leftover, map_parsed, recover};
28pub use syntax::SyntaxError;
29
30/// Errors that may occur while parsing a [`Program`](crate::program::Program).
31#[derive(Clone, Debug, PartialEq)]
32pub enum ParseProgramError<T> {
33    InvalidCalibration {
34        instruction: Instruction,
35        message: String,
36    },
37    Syntax(SyntaxError<T>),
38}
39
40impl<T> From<LexError> for ParseProgramError<T>
41where
42    T: fmt::Debug,
43{
44    fn from(e: LexError) -> Self {
45        Self::Syntax(SyntaxError::from(e))
46    }
47}
48
49impl<T> From<ParseError> for ParseProgramError<T> {
50    fn from(e: ParseError) -> Self {
51        Self::Syntax(SyntaxError::from(e))
52    }
53}
54
55impl<T> From<LeftoverError<T>> for ParseProgramError<T> {
56    fn from(err: LeftoverError<T>) -> Self {
57        Self::Syntax(SyntaxError::from(err))
58    }
59}
60
61impl<T> From<SyntaxError<T>> for ParseProgramError<T> {
62    fn from(err: SyntaxError<T>) -> Self {
63        Self::Syntax(err)
64    }
65}
66
67impl<T> ParseProgramError<T> {
68    /// Convert the parsed output into another type.
69    pub fn map_parsed<T2>(self, map: impl Fn(T) -> T2) -> ParseProgramError<T2> {
70        match self {
71            Self::InvalidCalibration {
72                instruction,
73                message,
74            } => ParseProgramError::InvalidCalibration {
75                instruction,
76                message,
77            },
78            Self::Syntax(err) => ParseProgramError::Syntax(err.map_parsed(map)),
79        }
80    }
81}
82
83impl<T> fmt::Display for ParseProgramError<T>
84where
85    T: fmt::Debug + 'static,
86{
87    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
88        match self {
89            Self::InvalidCalibration {
90                instruction,
91                message,
92            } => write!(
93                f,
94                "invalid calibration `{instruction}`: {message}",
95                instruction = instruction.to_quil_or_debug()
96            ),
97            Self::Syntax(err) => fmt::Display::fmt(err, f),
98        }
99    }
100}
101
102impl<T> Error for ParseProgramError<T>
103where
104    T: fmt::Debug + 'static,
105{
106    fn source(&self) -> Option<&(dyn Error + 'static)> {
107        match self {
108            Self::InvalidCalibration { .. } => None,
109            Self::Syntax(err) => Some(err),
110        }
111    }
112}