diff --git a/src/lib.rs b/src/lib.rs index 27a149d78..e9daf4189 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -219,7 +219,7 @@ pub fn decode(s: &str) -> Result<(Hrp, Vec), DecodeError> { /// `Ck` algorithm (`NoChecksum` to exclude checksum all together). #[cfg(feature = "alloc")] #[inline] -pub fn encode(hrp: Hrp, data: &[u8]) -> Result { +pub fn encode(hrp: Hrp, data: &[u8]) -> Result { encode_lower::(hrp, data) } @@ -229,7 +229,9 @@ pub fn encode(hrp: Hrp, data: &[u8]) -> Result /// `Ck` algorithm (`NoChecksum` to exclude checksum all together). #[cfg(feature = "alloc")] #[inline] -pub fn encode_lower(hrp: Hrp, data: &[u8]) -> Result { +pub fn encode_lower(hrp: Hrp, data: &[u8]) -> Result { + let _ = encoded_length::(&hrp, data)?; + let mut buf = String::new(); encode_lower_to_fmt::(&mut buf, hrp, data)?; Ok(buf) @@ -241,7 +243,9 @@ pub fn encode_lower(hrp: Hrp, data: &[u8]) -> Result(hrp: Hrp, data: &[u8]) -> Result { +pub fn encode_upper(hrp: Hrp, data: &[u8]) -> Result { + let _ = encoded_length::(&hrp, data)?; + let mut buf = String::new(); encode_upper_to_fmt::(&mut buf, hrp, data)?; Ok(buf) @@ -256,7 +260,7 @@ pub fn encode_to_fmt( fmt: &mut W, hrp: Hrp, data: &[u8], -) -> Result<(), fmt::Error> { +) -> Result<(), EncodeError> { encode_lower_to_fmt::(fmt, hrp, data) } @@ -269,7 +273,9 @@ pub fn encode_lower_to_fmt( fmt: &mut W, hrp: Hrp, data: &[u8], -) -> Result<(), fmt::Error> { +) -> Result<(), EncodeError> { + let _ = encoded_length::(&hrp, data)?; + let iter = data.iter().copied().bytes_to_fes(); let chars = iter.with_checksum::(&hrp).chars(); for c in chars { @@ -287,7 +293,9 @@ pub fn encode_upper_to_fmt( fmt: &mut W, hrp: Hrp, data: &[u8], -) -> Result<(), fmt::Error> { +) -> Result<(), EncodeError> { + let _ = encoded_length::(&hrp, data)?; + let iter = data.iter().copied().bytes_to_fes(); let chars = iter.with_checksum::(&hrp).chars(); for c in chars { @@ -455,6 +463,49 @@ impl From for DecodeFromReaderError { fn from(e: DecodeError) -> Self { Self::Decode(e) } } +/// An error while encoding an address. +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub enum EncodeError { + /// Encoding HRP and data into a bech32 string exceeds the spec limit of 90 characters. + TooLong(EncodedLengthError), + /// Error writing to the formatter. + Fmt(fmt::Error), +} + +impl fmt::Display for EncodeError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use EncodeError::*; + + match *self { + TooLong(ref e) => write_err!(f, "encoded string too long"; e), + Fmt(ref e) => write_err!(f, "write to formatter failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for EncodeError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use EncodeError::*; + + match *self { + TooLong(ref e) => Some(e), + Fmt(ref e) => Some(e), + } + } +} + +impl From for EncodeError { + #[inline] + fn from(e: EncodedLengthError) -> Self { Self::TooLong(e) } +} + +impl From for EncodeError { + #[inline] + fn from(e: fmt::Error) -> Self { Self::Fmt(e) } +} + /// Encoding bech32 string exceeds the spec limit of 90 characters. #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive]