Skip to content

Commit 439713b

Browse files
refactor: remove PrincipalBufferError (#193) (#194)
Switched from `ExternalError` to `dyn Error` in CanisterBuilder. Fixes #193.
1 parent 01c2114 commit 439713b

File tree

2 files changed

+21
-31
lines changed

2 files changed

+21
-31
lines changed

ic-types/src/principal.rs

+16-26
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,20 @@ macro_rules! const_panic {
1212
};
1313
}
1414

15-
/// An error happened while decoding bytes to make a principal.
16-
#[derive(Error, Clone, Debug, Eq, PartialEq)]
17-
pub enum PrincipalBufferError {
18-
#[error("Buffer is too long.")]
19-
BufferTooLong(),
20-
}
21-
2215
/// An error happened while encoding, decoding or serializing a principal.
2316
#[derive(Error, Clone, Debug, Eq, PartialEq)]
2417
pub enum PrincipalError {
2518
#[error("Buffer is too long.")]
2619
BufferTooLong(),
2720

2821
#[error(r#"Invalid textual format: expected "{0}""#)]
29-
AbnormalTextualFormat(String),
22+
AbnormalTextualFormat(Principal),
3023

3124
#[error("Text must be a base 32 string.")]
3225
InvalidTextualFormatNotBase32(),
3326

3427
#[error("Text cannot be converted to a Principal; too small.")]
3528
TextTooSmall(),
36-
37-
#[error("A custom tool returned an error instead of a Principal: {0}")]
38-
ExternalError(String),
39-
}
40-
41-
impl From<PrincipalBufferError> for PrincipalError {
42-
fn from(v: PrincipalBufferError) -> Self {
43-
match v {
44-
PrincipalBufferError::BufferTooLong() => Self::BufferTooLong(),
45-
}
46-
}
4729
}
4830

4931
/// A class of principal. Because this should not be exposed it
@@ -204,13 +186,13 @@ impl Principal {
204186
}
205187

206188
/// Attempt to decode a slice into a Principal.
207-
pub const fn try_from_slice(bytes: &[u8]) -> Result<Self, PrincipalBufferError> {
189+
pub const fn try_from_slice(bytes: &[u8]) -> Result<Self, PrincipalError> {
208190
match bytes {
209191
[] => Ok(Principal::management_canister()),
210192
[4] => Ok(Principal::anonymous()),
211-
[.., 4] => Err(PrincipalBufferError::BufferTooLong()),
193+
[.., 4] => Err(PrincipalError::BufferTooLong()),
212194
bytes @ [..] => match PrincipalInner::try_from_slice(bytes) {
213-
None => Err(PrincipalBufferError::BufferTooLong()),
195+
None => Err(PrincipalError::BufferTooLong()),
214196
Some(v) => Ok(Principal(v)),
215197
},
216198
}
@@ -235,7 +217,7 @@ impl Principal {
235217
let expected = format!("{}", result);
236218

237219
if text.as_ref() != expected {
238-
return Err(PrincipalError::AbnormalTextualFormat(expected));
220+
return Err(PrincipalError::AbnormalTextualFormat(result));
239221
}
240222
Ok(result)
241223
}
@@ -302,15 +284,15 @@ impl TryFrom<&str> for Principal {
302284

303285
/// Vector TryFrom. The slice and array version of this trait are defined below.
304286
impl TryFrom<Vec<u8>> for Principal {
305-
type Error = PrincipalBufferError;
287+
type Error = PrincipalError;
306288

307289
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
308290
Self::try_from(bytes.as_slice())
309291
}
310292
}
311293

312294
impl TryFrom<&Vec<u8>> for Principal {
313-
type Error = PrincipalBufferError;
295+
type Error = PrincipalError;
314296

315297
fn try_from(bytes: &Vec<u8>) -> Result<Self, Self::Error> {
316298
Self::try_from(bytes.as_slice())
@@ -319,7 +301,7 @@ impl TryFrom<&Vec<u8>> for Principal {
319301

320302
/// Implement try_from for a generic sized slice.
321303
impl TryFrom<&[u8]> for Principal {
322-
type Error = PrincipalBufferError;
304+
type Error = PrincipalError;
323305

324306
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
325307
Self::try_from_slice(bytes)
@@ -539,6 +521,14 @@ mod tests {
539521
);
540522
}
541523

524+
#[test]
525+
fn parse_text_bad_format() {
526+
assert_eq!(
527+
Principal::from_str("aaaaa-aA").unwrap_err().to_string(),
528+
r#"Invalid textual format: expected "aaaaa-aa""#,
529+
);
530+
}
531+
542532
#[test]
543533
fn parse_management_canister_to_text_ok() {
544534
assert_eq!(Principal::from_str("aaaaa-aa").unwrap().as_slice(), &[]);

ic-utils/src/canister.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ use candid::parser::value::IDLValue;
44
use candid::ser::IDLBuilder;
55
use candid::CandidType;
66
use ic_agent::{Agent, AgentError};
7-
use ic_types::{Principal, PrincipalError};
7+
use ic_types::Principal;
88
use std::convert::TryInto;
99
use thiserror::Error;
1010

1111
/// An error happened while building a canister.
1212
#[derive(Debug, Error)]
1313
pub enum CanisterBuilderError {
1414
#[error("Getting the Canister ID returned an error: {0}")]
15-
PrincipalError(#[from] PrincipalError),
15+
PrincipalError(#[from] Box<dyn std::error::Error>),
1616

1717
#[error("Must specify an Agent")]
1818
MustSpecifyAnAgent(),
@@ -24,22 +24,22 @@ pub enum CanisterBuilderError {
2424
/// A canister builder, which can be used to create a canister abstraction.
2525
pub struct CanisterBuilder<'agent, T = ()> {
2626
agent: Option<&'agent Agent>,
27-
canister_id: Option<Result<Principal, PrincipalError>>,
27+
canister_id: Option<Result<Principal, CanisterBuilderError>>,
2828
interface: T,
2929
}
3030

3131
impl<'agent, T> CanisterBuilder<'agent, T> {
3232
/// Attach a canister ID to this canister.
3333
pub fn with_canister_id<E, P>(self, canister_id: P) -> Self
3434
where
35-
E: std::error::Error,
35+
E: 'static + std::error::Error,
3636
P: TryInto<Principal, Error = E>,
3737
{
3838
Self {
3939
canister_id: Some(
4040
canister_id
4141
.try_into()
42-
.map_err(|e| PrincipalError::ExternalError(format!("{}", e))),
42+
.map_err(|e| CanisterBuilderError::PrincipalError(Box::new(e))),
4343
),
4444
..self
4545
}

0 commit comments

Comments
 (0)