use std::string::FromUtf8Error;
use std::{fmt, str};
use nostr::nips::nip44;
use nostr::types::url;
use nostr::{event, key, Kind, SignerError};
use openmls::credentials::errors::BasicCredentialError;
use openmls::error::LibraryError;
use openmls::extensions::errors::InvalidExtensionError;
use openmls::framing::errors::ProtocolMessageError;
use openmls::group::{
AddMembersError, CommitToPendingProposalsError, CreateGroupContextExtProposalError,
CreateMessageError, ExportSecretError, MergePendingCommitError, NewGroupError,
ProcessMessageError, SelfUpdateError, WelcomeError,
};
use openmls::key_packages::errors::{KeyPackageNewError, KeyPackageVerifyError};
use openmls_traits::types::CryptoError;
#[derive(Debug, PartialEq)]
pub enum Error {
Hex(hex::FromHexError),
Keys(key::Error),
Event(event::Error),
EventBuilder(event::builder::Error),
Signer(SignerError),
NIP44(nip44::Error),
RelayUrl(url::Error),
Tls(tls_codec::Error),
Utf8(str::Utf8Error),
Crypto(CryptoError),
OpenMlsGeneric(LibraryError),
InvalidExtension(InvalidExtensionError),
CreateMessage(CreateMessageError),
ExportSecret(ExportSecretError),
BasicCredential(BasicCredentialError),
ProcessMessage(ProcessMessageError),
ProtocolMessage(String),
KeyPackage(String),
Group(String),
GroupExporterSecretNotFound,
Message(String),
CannotDecryptOwnMessage,
MergePendingCommit(String),
CommitToPendingProposalsError,
SelfUpdate(String),
Welcome(String),
MissingWelcomeForProcessedWelcome,
ProcessedWelcomeNotFound,
Provider(String),
GroupNotFound,
ProtocolGroupIdMismatch,
OwnLeafNotFound,
CantLoadSigner,
InvalidWelcomeMessage,
UnexpectedEvent {
expected: Kind,
received: Kind,
},
UnexpectedExtensionType,
NostrGroupDataExtensionNotFound,
MessageFromNonMember,
NotImplemented(String),
MessageNotFound,
ProposalFromNonAdmin,
CommitFromNonAdmin,
UpdateGroupContextExts(String),
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Hex(e) => write!(f, "{e}"),
Self::Keys(e) => write!(f, "{e}"),
Self::Event(e) => write!(f, "{e}"),
Self::EventBuilder(e) => write!(f, "{e}"),
Self::Signer(e) => write!(f, "{e}"),
Self::NIP44(e) => write!(f, "{e}"),
Self::RelayUrl(e) => write!(f, "{e}"),
Self::Tls(e) => write!(f, "{e}"),
Self::Utf8(e) => write!(f, "{e}"),
Self::Crypto(e) => write!(f, "{e}"),
Self::OpenMlsGeneric(e) => write!(f, "{e}"),
Self::InvalidExtension(e) => write!(f, "{e}"),
Self::CreateMessage(e) => write!(f, "{e}"),
Self::ExportSecret(e) => write!(f, "{e}"),
Self::BasicCredential(e) => write!(f, "{e}"),
Self::ProcessMessage(e) => write!(f, "{e}"),
Self::ProtocolMessage(e) => write!(f, "{e}"),
Self::KeyPackage(e) => write!(f, "{e}"),
Self::Group(e) => write!(f, "{e}"),
Self::GroupExporterSecretNotFound => write!(f, "group exporter secret not found"),
Self::Message(e) => write!(f, "{e}"),
Self::CannotDecryptOwnMessage => write!(f, "cannot decrypt own message"),
Self::Welcome(e) => write!(f, "{e}"),
Self::MissingWelcomeForProcessedWelcome => {
write!(f, "missing welcome for processed welcome")
}
Self::ProcessedWelcomeNotFound => write!(f, "processed welcome not found"),
Self::MergePendingCommit(e) => write!(f, "{e}"),
Self::CommitToPendingProposalsError => {
write!(f, "unable to commit to pending proposal")
}
Self::SelfUpdate(e) => write!(f, "{e}"),
Self::Provider(e) => write!(f, "{e}"),
Self::GroupNotFound => write!(f, "group not found"),
Self::ProtocolGroupIdMismatch => write!(
f,
"protocol message group ID doesn't match the current group ID"
),
Self::OwnLeafNotFound => write!(f, "own leaf not found"),
Self::CantLoadSigner => write!(f, "can't load signer"),
Self::InvalidWelcomeMessage => write!(f, "invalid welcome message"),
Self::UnexpectedEvent { expected, received } => write!(
f,
"unexpected event kind: expected={expected}, received={received}"
),
Self::UnexpectedExtensionType => {
write!(f, "Unexpected extension type")
}
Self::NostrGroupDataExtensionNotFound => {
write!(f, "Nostr group data extension not found")
}
Self::MessageFromNonMember => {
write!(f, "Message recieved from non-member")
}
Self::NotImplemented(e) => {
write!(f, "{e}")
}
Self::MessageNotFound => write!(f, "stored message not found"),
Self::ProposalFromNonAdmin => write!(f, "not processing proposal from non-admin"),
Self::CommitFromNonAdmin => write!(f, "not processing commit from non-admin"),
Self::UpdateGroupContextExts(e) => {
write!(f, "Error when updating group context extensions {e}")
}
}
}
}
impl From<hex::FromHexError> for Error {
fn from(e: hex::FromHexError) -> Self {
Self::Hex(e)
}
}
impl From<key::Error> for Error {
fn from(e: key::Error) -> Self {
Self::Keys(e)
}
}
impl From<event::Error> for Error {
fn from(e: event::Error) -> Self {
Self::Event(e)
}
}
impl From<event::builder::Error> for Error {
fn from(e: event::builder::Error) -> Self {
Self::EventBuilder(e)
}
}
impl From<SignerError> for Error {
fn from(e: SignerError) -> Self {
Self::Signer(e)
}
}
impl From<nip44::Error> for Error {
fn from(e: nip44::Error) -> Self {
Self::NIP44(e)
}
}
impl From<url::Error> for Error {
fn from(e: url::Error) -> Self {
Self::RelayUrl(e)
}
}
impl From<tls_codec::Error> for Error {
fn from(e: tls_codec::Error) -> Self {
Self::Tls(e)
}
}
impl From<str::Utf8Error> for Error {
fn from(e: str::Utf8Error) -> Self {
Self::Utf8(e)
}
}
impl From<FromUtf8Error> for Error {
fn from(e: FromUtf8Error) -> Self {
Self::Utf8(e.utf8_error())
}
}
impl From<CryptoError> for Error {
fn from(e: CryptoError) -> Self {
Self::Crypto(e)
}
}
impl From<LibraryError> for Error {
fn from(e: LibraryError) -> Self {
Self::OpenMlsGeneric(e)
}
}
impl From<InvalidExtensionError> for Error {
fn from(e: InvalidExtensionError) -> Self {
Self::InvalidExtension(e)
}
}
impl From<CreateMessageError> for Error {
fn from(e: CreateMessageError) -> Self {
Self::CreateMessage(e)
}
}
impl From<ExportSecretError> for Error {
fn from(e: ExportSecretError) -> Self {
Self::ExportSecret(e)
}
}
impl From<BasicCredentialError> for Error {
fn from(e: BasicCredentialError) -> Self {
Self::BasicCredential(e)
}
}
impl From<ProcessMessageError> for Error {
fn from(e: ProcessMessageError) -> Self {
Self::ProcessMessage(e)
}
}
impl From<ProtocolMessageError> for Error {
fn from(e: ProtocolMessageError) -> Self {
Self::ProtocolMessage(e.to_string())
}
}
impl From<KeyPackageNewError> for Error {
fn from(e: KeyPackageNewError) -> Self {
Self::KeyPackage(e.to_string())
}
}
impl From<KeyPackageVerifyError> for Error {
fn from(e: KeyPackageVerifyError) -> Self {
Self::KeyPackage(e.to_string())
}
}
impl<T> From<NewGroupError<T>> for Error
where
T: fmt::Display,
{
fn from(e: NewGroupError<T>) -> Self {
Self::Group(e.to_string())
}
}
impl<T> From<AddMembersError<T>> for Error
where
T: fmt::Display,
{
fn from(e: AddMembersError<T>) -> Self {
Self::Group(e.to_string())
}
}
impl<T> From<MergePendingCommitError<T>> for Error
where
T: fmt::Display,
{
fn from(e: MergePendingCommitError<T>) -> Self {
Self::MergePendingCommit(e.to_string())
}
}
impl<T> From<CommitToPendingProposalsError<T>> for Error
where
T: fmt::Display,
{
fn from(_e: CommitToPendingProposalsError<T>) -> Self {
Self::CommitToPendingProposalsError
}
}
impl<T> From<SelfUpdateError<T>> for Error
where
T: fmt::Display,
{
fn from(e: SelfUpdateError<T>) -> Self {
Self::SelfUpdate(e.to_string())
}
}
impl<T> From<WelcomeError<T>> for Error
where
T: fmt::Display,
{
fn from(e: WelcomeError<T>) -> Self {
Self::Welcome(e.to_string())
}
}
impl<T> From<CreateGroupContextExtProposalError<T>> for Error
where
T: fmt::Display,
{
fn from(e: CreateGroupContextExtProposalError<T>) -> Self {
Self::UpdateGroupContextExts(e.to_string())
}
}