Skip to main content

co_identity/resolvers/
join.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 1io BRANDGUARDIAN GmbH
3
4use crate::{
5	IdentityBox, IdentityResolver, IdentityResolverBox, IdentityResolverError, PrivateIdentityBox,
6	PrivateIdentityResolver, PrivateIdentityResolverBox,
7};
8use async_trait::async_trait;
9
10#[derive(Debug, Clone)]
11pub struct JoinIdentityResolver {
12	resolvers: Vec<IdentityResolverBox>,
13}
14impl JoinIdentityResolver {
15	pub fn new(resolvers: Vec<IdentityResolverBox>) -> Self {
16		Self { resolvers }
17	}
18}
19#[async_trait]
20impl IdentityResolver for JoinIdentityResolver {
21	async fn resolve(&self, identity: &str) -> Result<IdentityBox, IdentityResolverError> {
22		let mut last_error: Option<IdentityResolverError> = None;
23		for resolver in self.resolvers.iter() {
24			match resolver.resolve(identity).await {
25				Ok(i) => return Ok(i),
26				Err(IdentityResolverError::NotFound) => {},
27				Err(e) => last_error = Some(e),
28			}
29		}
30		return Err(last_error.unwrap_or(IdentityResolverError::NotFound));
31	}
32}
33
34#[derive(Debug, Clone)]
35pub struct JoinPrivateIdentityResolver {
36	resolvers: Vec<PrivateIdentityResolverBox>,
37}
38impl JoinPrivateIdentityResolver {
39	pub fn new(resolvers: Vec<PrivateIdentityResolverBox>) -> Self {
40		Self { resolvers }
41	}
42}
43#[async_trait]
44impl PrivateIdentityResolver for JoinPrivateIdentityResolver {
45	async fn resolve_private(&self, identity: &str) -> Result<PrivateIdentityBox, IdentityResolverError> {
46		let mut last_error: Option<IdentityResolverError> = None;
47		for resolver in self.resolvers.iter() {
48			match resolver.resolve_private(identity).await {
49				Ok(i) => return Ok(i),
50				Err(IdentityResolverError::NotFound) => {},
51				Err(e) => last_error = Some(e),
52			}
53		}
54		return Err(last_error.unwrap_or(IdentityResolverError::NotFound));
55	}
56}