From beacc8dc4c42e057a40d3854ad880248dc00620f Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Wed, 13 Nov 2024 14:45:38 +0000 Subject: [PATCH] Introduce `error` module with single `ParseError` enum in it. We will use this error type in the next commit. For now we will continue to use the giant global Error enum, so we add a variant to hold the new `ParseError`. But eventually `ParseError` will become a top-level error and `Error` will go away. --- src/error.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 12 ++++++++---- 2 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/error.rs diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 000000000..f66cd42f1 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,53 @@ +// Written in 2019 by Andrew Poelstra +// SPDX-License-Identifier: CC0-1.0 + +//! Errors + +use core::fmt; +#[cfg(feature = "std")] +use std::error; + +use crate::blanket_traits::StaticDebugAndDisplay; +use crate::Box; +/// An error parsing a Miniscript object (policy, descriptor or miniscript) +/// from a string. +#[derive(Debug)] +pub enum ParseError { + /// Failed to parse a public key or hash. + /// + /// Note that the error information is lost for nostd compatibility reasons. See + /// . + FromStr(Box), + /// Error parsing a string into an expression tree. + Tree(crate::ParseTreeError), +} + +impl ParseError { + /// Boxes a `FromStr` error for a `Pk` (or associated types) into a `ParseError` + pub(crate) fn box_from_str(e: E) -> Self { + ParseError::FromStr(Box::new(e)) + } +} + +impl From for ParseError { + fn from(e: crate::ParseTreeError) -> Self { Self::Tree(e) } +} + +impl fmt::Display for ParseError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + ParseError::FromStr(ref e) => e.fmt(f), + ParseError::Tree(ref e) => e.fmt(f), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for ParseError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + ParseError::FromStr(..) => None, + ParseError::Tree(ref e) => Some(e), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index f15d99e46..90a92d32b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -114,6 +114,7 @@ mod pub_macros; mod benchmarks; mod blanket_traits; pub mod descriptor; +mod error; pub mod expression; pub mod interpreter; pub mod iter; @@ -128,8 +129,6 @@ mod test_utils; mod util; use core::{fmt, hash, str}; -#[cfg(feature = "std")] -use std::error; use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; use bitcoin::hex::DisplayHex; @@ -137,6 +136,7 @@ use bitcoin::{script, Opcode}; pub use crate::blanket_traits::FromStrKey; pub use crate::descriptor::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey}; +pub use crate::error::ParseError; pub use crate::expression::{ParseThresholdError, ParseTreeError}; pub use crate::interpreter::Interpreter; pub use crate::miniscript::analyzable::{AnalysisError, ExtParams}; @@ -494,6 +494,8 @@ pub enum Error { ParseThreshold(ParseThresholdError), /// Invalid expression tree. ParseTree(ParseTreeError), + /// Invalid expression tree. + Parse(ParseError), } // https://github.com/sipa/miniscript/pull/5 for discussion on this number @@ -556,13 +558,14 @@ impl fmt::Display for Error { Error::Threshold(ref e) => e.fmt(f), Error::ParseThreshold(ref e) => e.fmt(f), Error::ParseTree(ref e) => e.fmt(f), + Error::Parse(ref e) => e.fmt(f), } } } #[cfg(feature = "std")] -impl error::Error for Error { - fn cause(&self) -> Option<&dyn error::Error> { +impl std::error::Error for Error { + fn cause(&self) -> Option<&dyn std::error::Error> { use self::Error::*; match self { @@ -607,6 +610,7 @@ impl error::Error for Error { Threshold(e) => Some(e), ParseThreshold(e) => Some(e), ParseTree(e) => Some(e), + Parse(e) => Some(e), } } }