2022-11-18 03:06:57 +00:00
|
|
|
// SPDX-License-Identifier: CC0-1.0
|
|
|
|
|
|
|
|
//! Bitcoin string parsing utilities.
|
|
|
|
//!
|
|
|
|
//! This module provides utility types and traits
|
|
|
|
//! to support handling and parsing strings within `rust-bitcoin`.
|
|
|
|
|
|
|
|
use core::fmt;
|
|
|
|
|
2023-03-28 01:16:47 +00:00
|
|
|
use internals::write_err;
|
2022-11-18 03:06:57 +00:00
|
|
|
|
|
|
|
use crate::prelude::String;
|
|
|
|
|
|
|
|
/// Trait that allows types to be initialized from hex strings
|
|
|
|
pub trait FromHexStr: Sized {
|
|
|
|
/// An error occurred while parsing the hex string.
|
|
|
|
type Error;
|
|
|
|
|
|
|
|
/// Parses provided string as hex requiring 0x prefix.
|
|
|
|
///
|
|
|
|
/// This is intended for user-supplied inputs or already-existing protocols in which 0x prefix is used.
|
|
|
|
fn from_hex_str<S: AsRef<str> + Into<String>>(s: S) -> Result<Self, FromHexError<Self::Error>> {
|
|
|
|
if !s.as_ref().starts_with("0x") {
|
|
|
|
Err(FromHexError::MissingPrefix(s.into()))
|
|
|
|
} else {
|
|
|
|
Ok(Self::from_hex_str_no_prefix(s.as_ref().trim_start_matches("0x"))?)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Parses provided string as hex without requiring 0x prefix.
|
|
|
|
///
|
|
|
|
/// This is **not** recommended for user-supplied inputs because of possible confusion with decimals.
|
|
|
|
/// It should be only used for existing protocols which always encode values as hex without 0x prefix.
|
|
|
|
fn from_hex_str_no_prefix<S: AsRef<str> + Into<String>>(s: S) -> Result<Self, Self::Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Hex parsing error
|
2023-07-27 01:10:22 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
Make error types uniform
On our way to v1.0.0 we are defining a standard for our error types,
this includes:
- Uses the following derives (unless not possible, usually because of `io::Error`)
`#[derive(Debug, Clone, PartialEq, Eq)]`
- Has `non_exhaustive` unless we really know we can commit to not adding
anything.
Furthermore, we are trying to make the codebase easy to read. Error code
is write-once-read-many (well it should be) so if we make all the error
code super uniform the users can flick to an error and quickly see what
it includes. In an effort to achieve this I have made up a style and
over recent times have change much of the error code to that new style,
this PR audits _all_ error types in the code base and enforces the
style, specifically:
- Is layed out: definition, [impl block], Display impl, error::Error impl, From impls
- `error::Error` impl matches on enum even if it returns `None` for all variants
- Display/Error impls import enum variants locally
- match uses *self and `ref e`
- error::Error variants that return `Some` come first, `None` after
Re: non_exhaustive
To make dev and review easier I have added `non_exhaustive` to _every_
error type. We can then remove it error by error as we see fit. This is
because it takes a bit of thinking to do and review where as this patch
should not take much brain power to review.
2023-10-04 02:55:45 +00:00
|
|
|
#[non_exhaustive]
|
2022-11-18 03:06:57 +00:00
|
|
|
pub enum FromHexError<E> {
|
|
|
|
/// The input was not a valid hex string, contains the error that occurred while parsing.
|
|
|
|
ParseHex(E),
|
|
|
|
/// The input is missing `0x` prefix, contains the invalid input.
|
|
|
|
MissingPrefix(String),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<E> From<E> for FromHexError<E> {
|
|
|
|
fn from(e: E) -> Self { FromHexError::ParseHex(e) }
|
|
|
|
}
|
|
|
|
|
2022-11-02 22:36:37 +00:00
|
|
|
impl<E: fmt::Display> fmt::Display for FromHexError<E> {
|
2022-11-18 03:06:57 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
Make error types uniform
On our way to v1.0.0 we are defining a standard for our error types,
this includes:
- Uses the following derives (unless not possible, usually because of `io::Error`)
`#[derive(Debug, Clone, PartialEq, Eq)]`
- Has `non_exhaustive` unless we really know we can commit to not adding
anything.
Furthermore, we are trying to make the codebase easy to read. Error code
is write-once-read-many (well it should be) so if we make all the error
code super uniform the users can flick to an error and quickly see what
it includes. In an effort to achieve this I have made up a style and
over recent times have change much of the error code to that new style,
this PR audits _all_ error types in the code base and enforces the
style, specifically:
- Is layed out: definition, [impl block], Display impl, error::Error impl, From impls
- `error::Error` impl matches on enum even if it returns `None` for all variants
- Display/Error impls import enum variants locally
- match uses *self and `ref e`
- error::Error variants that return `Some` come first, `None` after
Re: non_exhaustive
To make dev and review easier I have added `non_exhaustive` to _every_
error type. We can then remove it error by error as we see fit. This is
because it takes a bit of thinking to do and review where as this patch
should not take much brain power to review.
2023-10-04 02:55:45 +00:00
|
|
|
use FromHexError::*;
|
2022-11-18 03:06:57 +00:00
|
|
|
|
|
|
|
match *self {
|
|
|
|
ParseHex(ref e) => write_err!(f, "failed to parse hex string"; e),
|
2022-11-02 22:36:37 +00:00
|
|
|
MissingPrefix(ref value) =>
|
|
|
|
write_err!(f, "the input value `{}` is missing the `0x` prefix", value; self),
|
2022-11-18 03:06:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
impl<E> std::error::Error for FromHexError<E>
|
|
|
|
where
|
|
|
|
E: std::error::Error + 'static,
|
|
|
|
{
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
Make error types uniform
On our way to v1.0.0 we are defining a standard for our error types,
this includes:
- Uses the following derives (unless not possible, usually because of `io::Error`)
`#[derive(Debug, Clone, PartialEq, Eq)]`
- Has `non_exhaustive` unless we really know we can commit to not adding
anything.
Furthermore, we are trying to make the codebase easy to read. Error code
is write-once-read-many (well it should be) so if we make all the error
code super uniform the users can flick to an error and quickly see what
it includes. In an effort to achieve this I have made up a style and
over recent times have change much of the error code to that new style,
this PR audits _all_ error types in the code base and enforces the
style, specifically:
- Is layed out: definition, [impl block], Display impl, error::Error impl, From impls
- `error::Error` impl matches on enum even if it returns `None` for all variants
- Display/Error impls import enum variants locally
- match uses *self and `ref e`
- error::Error variants that return `Some` come first, `None` after
Re: non_exhaustive
To make dev and review easier I have added `non_exhaustive` to _every_
error type. We can then remove it error by error as we see fit. This is
because it takes a bit of thinking to do and review where as this patch
should not take much brain power to review.
2023-10-04 02:55:45 +00:00
|
|
|
use FromHexError::*;
|
2022-11-18 03:06:57 +00:00
|
|
|
|
|
|
|
match *self {
|
|
|
|
ParseHex(ref e) => Some(e),
|
|
|
|
MissingPrefix(_) => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|