b147452948
...so that we can parse (and at the same time validate) store paths directly to `StorePath`s. https: //b.tvl.fyi/issues/264 Change-Id: Ide4cb5403f8e3400f7d2a5838c652ac35dbd1a4f Reviewed-on: https://cl.tvl.fyi/c/depot/+/10968 Reviewed-by: flokli <flokli@flokli.de> Autosubmit: Peter Kolloch <info@eigenvalue.net> Tested-by: BuildkiteCI
84 lines
2.4 KiB
Rust
84 lines
2.4 KiB
Rust
//! This contains error and result types that can happen while parsing
|
|
//! Derivations from ATerm.
|
|
use nom::IResult;
|
|
|
|
use crate::{nixhash, store_path};
|
|
|
|
pub type NomResult<I, O> = IResult<I, O, NomError<I>>;
|
|
|
|
#[derive(Debug, thiserror::Error, PartialEq)]
|
|
pub enum ErrorKind {
|
|
/// duplicate key in map
|
|
#[error("duplicate map key: {0}")]
|
|
DuplicateMapKey(String),
|
|
|
|
/// Input derivation has two outputs with the same name
|
|
#[error("duplicate output name {1} for input derivation {0}")]
|
|
DuplicateInputDerivationOutputName(String, String),
|
|
|
|
#[error("duplicate input source: {0}")]
|
|
DuplicateInputSource(String),
|
|
|
|
#[error("nix hash error: {0}")]
|
|
NixHashError(nixhash::Error),
|
|
|
|
#[error("store path error: {0}")]
|
|
StorePathError(#[from] store_path::Error),
|
|
|
|
#[error("nom error: {0:?}")]
|
|
Nom(nom::error::ErrorKind),
|
|
}
|
|
|
|
/// Our own error type to pass along parser-related errors.
|
|
#[derive(Debug, PartialEq)]
|
|
pub struct NomError<I> {
|
|
/// position of the error in the input data
|
|
pub input: I,
|
|
/// error code
|
|
pub code: ErrorKind,
|
|
}
|
|
|
|
impl<I, E> nom::error::FromExternalError<I, E> for NomError<I> {
|
|
fn from_external_error(input: I, kind: nom::error::ErrorKind, _e: E) -> Self {
|
|
Self {
|
|
input,
|
|
code: ErrorKind::Nom(kind),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<I> nom::error::ParseError<I> for NomError<I> {
|
|
fn from_error_kind(input: I, kind: nom::error::ErrorKind) -> Self {
|
|
Self {
|
|
input,
|
|
code: ErrorKind::Nom(kind),
|
|
}
|
|
}
|
|
|
|
// FUTUREWORK: implement, so we have support for backtracking through the
|
|
// parse tree?
|
|
fn append(_input: I, _kind: nom::error::ErrorKind, other: Self) -> Self {
|
|
other
|
|
}
|
|
}
|
|
|
|
/// This wraps a [nom::error::Error] into our error.
|
|
impl<I> From<nom::error::Error<I>> for NomError<I> {
|
|
fn from(value: nom::error::Error<I>) -> Self {
|
|
Self {
|
|
input: value.input,
|
|
code: ErrorKind::Nom(value.code),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// This essentially implements
|
|
/// `From<nom::Err<nom::error::Error<I>>>` for `nom::Err<NomError<I>>`,
|
|
/// which we can't because `nom::Err<_>` is a foreign type.
|
|
pub(crate) fn into_nomerror<I>(e: nom::Err<nom::error::Error<I>>) -> nom::Err<NomError<I>> {
|
|
match e {
|
|
nom::Err::Incomplete(n) => nom::Err::Incomplete(n),
|
|
nom::Err::Error(e) => nom::Err::Error(e.into()),
|
|
nom::Err::Failure(e) => nom::Err::Failure(e.into()),
|
|
}
|
|
}
|