use nom::IResult;
use crate::{
nixhash,
store_path::{self, StorePath},
};
pub type NomResult<I, O> = IResult<I, O, NomError<I>>;
#[derive(Debug, thiserror::Error, PartialEq)]
pub enum ErrorKind {
#[error("duplicate map key: {0}")]
DuplicateMapKey(String),
#[error("duplicate output name {1} for input derivation {0}")]
DuplicateInputDerivationOutputName(String, String),
#[error("duplicate input source: {0}")]
DuplicateInputSource(StorePath<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),
}
#[derive(Debug, PartialEq)]
pub struct NomError<I> {
pub input: I,
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),
}
}
fn append(_input: I, _kind: nom::error::ErrorKind, other: Self) -> Self {
other
}
}
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),
}
}
}
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()),
}
}