quil_rs/program/error/
leftover.rs

1// Copyright 2022 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
15use crate::parser::ErrorInput;
16use std::fmt;
17
18/// The parser returned success, but there was unexpected leftover input.
19///
20/// This error contains the parsed item, which can be accessed using [`LeftoverError::recover`].
21#[derive(Clone, Debug, PartialEq, Eq)]
22pub struct LeftoverError<O> {
23    line: u32,
24    column: usize,
25    snippet: String,
26    parsed: O,
27}
28
29impl<O> fmt::Display for LeftoverError<O> {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        write!(
32            f,
33            "successfully parsed {} with leftover input starting at line {}, column {} ({})",
34            std::any::type_name::<O>(),
35            self.line,
36            self.column,
37            self.snippet,
38        )
39    }
40}
41
42impl<O> std::error::Error for LeftoverError<O> where Self: fmt::Debug {}
43
44impl<O> LeftoverError<O> {
45    /// Create a new `LeftoverError` from the given leftover input and parsed item.
46    pub(crate) fn new<I>(leftover: I, parsed: O) -> Self
47    where
48        I: ErrorInput,
49    {
50        Self {
51            line: leftover.line(),
52            column: leftover.column(),
53            snippet: leftover.snippet(),
54            parsed,
55        }
56    }
57
58    /// Consumes this error and returns the parsed output.
59    pub fn recover(self) -> O {
60        self.parsed
61    }
62
63    /// Map the parsed output into some other type.
64    pub fn map_parsed<O2>(self, map: impl FnOnce(O) -> O2) -> LeftoverError<O2> {
65        let Self {
66            line,
67            column,
68            snippet,
69            parsed,
70        } = self;
71        let parsed = map(parsed);
72        LeftoverError {
73            line,
74            column,
75            snippet,
76            parsed,
77        }
78    }
79}