Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions payjoin-cli/src/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ impl Config {
"BIP77 (v2) selected but v2 feature not enabled".to_string(),
));
}
_ => return Err(ConfigError::Message("Unsupported payjoin version".to_string())),
}

config = handle_subcommands(config, cli)?;
Expand Down Expand Up @@ -235,6 +236,7 @@ impl Config {
"BIP77 (v2) selected but v2 feature not enabled".to_string(),
));
}
_ => return Err(ConfigError::Message("Unsupported payjoin version".to_string())),
}

if config.version.is_none() {
Expand Down
1 change: 1 addition & 0 deletions payjoin/src/core/into_url.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::core::{Url, UrlParseError};

#[derive(Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
BadScheme,
ParseError(UrlParseError),
Expand Down
1 change: 0 additions & 1 deletion payjoin/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ pub use uri::{PjParam, PjParseError, PjUri, Uri, UriExt};
pub(crate) mod error_codes;

pub(crate) mod output_substitution;
#[cfg(feature = "v1")]
pub use output_substitution::OutputSubstitution;

#[cfg(feature = "v2")]
Expand Down
9 changes: 9 additions & 0 deletions payjoin/src/core/persist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ impl<Event> PersistActions<Event> {

/// Handles cases where the transition either succeeds with a final result that ends the session, or hits a static condition and stays in the same state.
/// State transition may also be a fatal error or transient error.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub struct MaybeSuccessTransitionWithNoResults<Event, SuccessValue, CurrentState, Err>(
Result<AcceptOptionalTransition<Event, SuccessValue, CurrentState>, Rejection<Event, Err>>,
);
Expand Down Expand Up @@ -156,6 +157,7 @@ where
}

/// A transition that can result in a state transition, fatal error, or successfully have no results.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub struct MaybeFatalTransitionWithNoResults<Event, NextState, CurrentState, Err>(
Result<AcceptOptionalTransition<Event, NextState, CurrentState>, Rejection<Event, Err>>,
);
Expand Down Expand Up @@ -240,6 +242,7 @@ where
}

/// A transition that can be either fatal, transient, or a state transition.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub struct MaybeFatalTransition<Event, NextState, Err, ErrorState = ()>(
pub(crate) Result<AcceptNextState<Event, NextState>, Rejection<Event, Err, ErrorState>>,
);
Expand Down Expand Up @@ -310,6 +313,7 @@ where

/// A transition that can result in a state transition or a transient error.
/// Fatal errors cannot occur in this transition.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub struct MaybeTransientTransition<Event, NextState, Err>(
Result<AcceptNextState<Event, NextState>, RejectTransient<Err>>,
);
Expand Down Expand Up @@ -362,6 +366,7 @@ where
}

/// A transition that always results in a state transition.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub struct NextStateTransition<Event, NextState>(AcceptNextState<Event, NextState>);

impl<Event, NextState> NextStateTransition<Event, NextState> {
Expand Down Expand Up @@ -400,6 +405,7 @@ impl<Event, NextState> NextStateTransition<Event, NextState> {
/// No error path exists. Both outcomes are successful from the protocol's point
/// of view. The choice is determined by the source typestate's internal data,
/// not by the caller.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub struct MaybeTerminalTransition<Event, NextState>(MaybeTerminalOutcome<Event, NextState>);

impl<Event, NextState> MaybeTerminalTransition<Event, NextState> {
Expand Down Expand Up @@ -446,6 +452,7 @@ impl<Event, NextState> MaybeTerminalTransition<Event, NextState> {
/// Fatal outcomes still persist an event. When the fatal outcome advances, the
/// saved event keeps the session live for replay while the caller receives the
/// fatal protocol error.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub struct MaybeTerminalSuccessTransition<Event, NextState, Err>(
MaybeTerminalSuccessOutcome<Event, NextState, Err>,
);
Expand Down Expand Up @@ -531,6 +538,7 @@ where
/// being persisted. This lets callers receive derived data (e.g. a fallback
/// transaction) through the same `.save()` call pattern used by every other
/// transition type.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub struct TerminalTransition<Event, T>(Event, T);

impl<Event, T> TerminalTransition<Event, T> {
Expand All @@ -557,6 +565,7 @@ impl<Event, T> TerminalTransition<Event, T> {

/// A transition that can result in a succession completion, fatal error, or transient error.
/// The transition can also result in no state change.
#[must_use = "a transition must be persisted with .save() to advance the session"]
pub enum MaybeFatalOrSuccessTransition<Event, CurrentState, Err> {
Success(Event),
NoResults(CurrentState),
Expand Down
1 change: 1 addition & 0 deletions payjoin/src/core/receive/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ impl error::Error for Error {
/// 4. Provide errors according to BIP-78 JSON error specifications for return
/// after conversion into [`JsonReply`]
#[derive(Debug)]
#[non_exhaustive]
pub enum ProtocolError {
/// Error arising from validation of the original PSBT payload
OriginalPayload(PayloadError),
Expand Down
1 change: 1 addition & 0 deletions payjoin/src/core/receive/v2/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ impl SessionHistory {
// Represents the status of a session that can be inferred from the information in the session
// event log.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum SessionStatus {
Active,
Expired,
Expand Down
1 change: 1 addition & 0 deletions payjoin/src/core/send/v2/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ impl SessionHistory {
/// Represents the status of a session that can be inferred from the information in the session
/// event log.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum SessionStatus {
Expired,
Active,
Expand Down
1 change: 1 addition & 0 deletions payjoin/src/core/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ impl<'a> UrlQueryPairs<'a> {
///
/// Re-exported at the crate root as `UrlParseError`.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ParseError {
/// The authority section had no host between `://` and the path.
EmptyHost,
Expand Down
1 change: 1 addition & 0 deletions payjoin/src/core/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// and to match the expected wire format.
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Version {
/// BIP 78 Payjoin
One = 1,
Expand Down
19 changes: 19 additions & 0 deletions payjoin/src/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,30 @@ impl std::fmt::Display for ShortId {
}

#[derive(Debug)]
#[non_exhaustive]
pub enum ShortIdError {
DecodeBech32(bitcoin::bech32::primitives::decode::CheckedHrpstringError),
IncorrectLength(std::array::TryFromSliceError),
}

impl std::fmt::Display for ShortIdError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ShortIdError::DecodeBech32(e) => write!(f, "Failed to decode short ID: {e}"),
ShortIdError::IncorrectLength(e) => write!(f, "Short ID has an incorrect length: {e}"),
}
}
}

impl std::error::Error for ShortIdError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ShortIdError::DecodeBech32(e) => Some(e),
ShortIdError::IncorrectLength(e) => Some(e),
}
}
}

impl std::convert::From<bitcoin::hashes::sha256::Hash> for ShortId {
fn from(h: bitcoin::hashes::sha256::Hash) -> Self {
bitcoin::hashes::Hash::as_byte_array(&h)[..8]
Expand Down
Loading