quil_rs/program/error/leftover.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
// Copyright 2022 Rigetti Computing
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::parser::ErrorInput;
use std::fmt;
/// The parser returned success, but there was unexpected leftover input.
///
/// This error contains the parsed item, which can be accessed using [`LeftoverError::recover`].
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct LeftoverError<O> {
line: u32,
column: usize,
snippet: String,
parsed: O,
}
impl<O> fmt::Display for LeftoverError<O> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"successfully parsed {} with leftover input starting at line {}, column {} ({})",
std::any::type_name::<O>(),
self.line,
self.column,
self.snippet,
)
}
}
impl<O> std::error::Error for LeftoverError<O> where Self: fmt::Debug {}
impl<O> LeftoverError<O> {
/// Create a new `LeftoverError` from the given leftover input and parsed item.
pub(crate) fn new<I>(leftover: I, parsed: O) -> Self
where
I: ErrorInput,
{
Self {
line: leftover.line(),
column: leftover.column(),
snippet: leftover.snippet(),
parsed,
}
}
/// Consumes this error and returns the parsed output.
pub fn recover(self) -> O {
self.parsed
}
/// Map the parsed output into some other type.
pub fn map_parsed<O2>(self, map: impl FnOnce(O) -> O2) -> LeftoverError<O2> {
let Self {
line,
column,
snippet,
parsed,
} = self;
let parsed = map(parsed);
LeftoverError {
line,
column,
snippet,
parsed,
}
}
}