use futures::channel::oneshot::Canceled;
use iroh::PublicKey;
use thiserror::Error;
use uuid::Uuid;
use crate::{
base::{BindingError, Ident, MonitorError, parse_ident},
compat,
remote::network::NetworkError,
};
pub type ActorTypeId = Uuid;
pub type Tag = u32;
#[derive(Debug, Clone, Error)]
pub enum RemoteError {
#[error(transparent)]
Canceled(#[from] Canceled),
#[error("invalid address")]
InvalidAddress,
#[error(transparent)]
NetworkError(#[from] NetworkError),
#[error(transparent)]
SerializeError(postcard::Error),
#[error(transparent)]
DeserializeError(postcard::Error),
#[error(transparent)]
BindingError(#[from] BindingError),
#[error(transparent)]
MonitorError(#[from] MonitorError),
#[error("deadline has elapsed")]
Timeout,
}
pub(crate) fn parse_url(addr: &url::Url) -> Result<(Ident, PublicKey), RemoteError> {
let ident = parse_ident(addr.username())?;
let public_key = addr
.host_str()
.ok_or(RemoteError::InvalidAddress)?
.parse::<PublicKey>()
.map_err(|_| RemoteError::InvalidAddress)?;
debug_assert!(addr.path_segments().is_none());
Ok((ident, public_key))
}
impl From<compat::Elapsed> for RemoteError {
fn from(_: compat::Elapsed) -> Self {
RemoteError::Timeout
}
}
#[cfg(test)]
mod tests {
use url::Url;
use uuid::uuid;
use super::*;
#[test]
fn test_split_url() {
let url = Url::parse("iroh://824d7cba-1489-4537-b2c9-1a488a3f895a@a0f71647936e25b8403433b31deb3a374d175b282baf9803a7715b138f9e6f65").unwrap();
let (ident, public_key) = parse_url(&url).unwrap();
assert_eq!(
public_key.to_string(),
"a0f71647936e25b8403433b31deb3a374d175b282baf9803a7715b138f9e6f65"
);
assert_eq!(
&ident,
uuid!("824d7cba-1489-4537-b2c9-1a488a3f895a").as_bytes()
);
let url = Url::parse(
"iroh://foo@a0f71647936e25b8403433b31deb3a374d175b282baf9803a7715b138f9e6f65",
)
.unwrap();
let (ident, public_key) = parse_url(&url).unwrap();
assert_eq!(
public_key.to_string(),
"a0f71647936e25b8403433b31deb3a374d175b282baf9803a7715b138f9e6f65"
);
let expected: [u8; 16] = {
let mut bytes = [0u8; 16];
bytes[..3].copy_from_slice(b"foo");
bytes
};
assert_eq!(&ident, &expected);
}
}