Skip to main content

co_identity/types/
resolver.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 1io BRANDGUARDIAN GmbH
3
4use crate::IdentityBox;
5use async_trait::async_trait;
6use std::{fmt::Debug, sync::Arc};
7
8#[derive(Debug, thiserror::Error)]
9pub enum IdentityResolverError {
10	/// Identity not found.
11	/// Ususally this means that the resolver is not capable of resolving this identity.
12	/// Therefore this is not retryable.
13	#[error("Identity not found")]
14	NotFound,
15
16	/// Other error.
17	/// This is possible retryable.
18	#[error("Resolve Identitiy failed")]
19	Other(#[from] anyhow::Error),
20}
21
22#[async_trait]
23pub trait IdentityResolver: Debug {
24	async fn resolve(&self, identity: &str) -> Result<IdentityBox, IdentityResolverError>;
25
26	fn boxed(self) -> IdentityResolverBox
27	where
28		Self: Sized + Clone + Send + Sync + 'static,
29	{
30		IdentityResolverBox::new(self)
31	}
32}
33
34/// Dynamic Identity Resolver.
35#[derive(Debug)]
36pub struct IdentityResolverBox {
37	resolver: Arc<dyn IdentityResolver + Send + Sync + 'static>,
38}
39impl IdentityResolverBox {
40	pub fn new<R: IdentityResolver + Clone + Send + Sync + 'static>(resolver: R) -> Self {
41		Self { resolver: Arc::new(resolver) }
42	}
43}
44#[async_trait]
45impl IdentityResolver for IdentityResolverBox {
46	async fn resolve(&self, identity: &str) -> Result<IdentityBox, IdentityResolverError> {
47		self.resolver.resolve(identity).await
48	}
49}
50impl Clone for IdentityResolverBox {
51	fn clone(&self) -> Self {
52		Self { resolver: self.resolver.clone() }
53	}
54}