Struct identity_iota::resolver::Resolver
source · pub struct Resolver<DOC = CoreDocument, CMD = SendSyncCommand<DOC>>{ /* private fields */ }
resolver
only.Expand description
Convenience type for resolving DID documents from different DID methods.
§Configuration
The resolver will only be able to resolve DID documents for methods it has been configured for. This is done by
attaching method specific handlers with Self::attach_handler
.
Implementations§
source§impl<M, DOC> Resolver<DOC, M>
impl<M, DOC> Resolver<DOC, M>
sourcepub fn new() -> Resolver<DOC, M>
pub fn new() -> Resolver<DOC, M>
Constructs a new Resolver
.
§Example
Construct a Resolver
that resolves DID documents of type
CoreDocument
.
let mut resolver = Resolver::<CoreDocument>::new();
// Now attach some handlers whose output can be converted to a `CoreDocument`.
sourcepub async fn resolve<D>(&self, did: &D) -> Result<DOC, Error>where
D: DID,
pub async fn resolve<D>(&self, did: &D) -> Result<DOC, Error>where
D: DID,
Fetches the DID Document of the given DID.
§Errors
Errors if the resolver has not been configured to handle the method corresponding to the given DID or the resolution process itself fails.
§Example
async fn configure_and_resolve(
did: CoreDID,
) -> std::result::Result<CoreDocument, Box<dyn std::error::Error>> {
let resolver: Resolver = configure_resolver(Resolver::new());
let resolved_doc: CoreDocument = resolver.resolve(&did).await?;
Ok(resolved_doc)
}
fn configure_resolver(mut resolver: Resolver) -> Resolver {
resolver.attach_handler("foo".to_owned(), resolve_foo);
// Attach handlers for other DID methods we are interested in.
resolver
}
async fn resolve_foo(did: CoreDID) -> std::result::Result<CoreDocument, std::io::Error> {
todo!()
}
source§impl<DOC> Resolver<DOC>where
DOC: 'static,
impl<DOC> Resolver<DOC>where
DOC: 'static,
sourcepub fn attach_handler<D, F, Fut, DOCUMENT, E, DIDERR>(
&mut self,
method: String,
handler: F
)
pub fn attach_handler<D, F, Fut, DOCUMENT, E, DIDERR>( &mut self, method: String, handler: F )
Attach a new handler responsible for resolving DIDs of the given DID method.
The handler
is expected to be a closure taking an owned DID and asynchronously returning a DID Document
which can be converted to the type this Resolver
is parametrized over. The handler
is required to be
Clone
, Send
, Sync
and 'static
hence all captured variables must satisfy these bounds. In this regard
the move
keyword and (possibly) wrapping values in an Arc
may come in handy (see the example
below).
NOTE: If there already exists a handler for this method then it will be replaced with the new handler. In the case where one would like to have a “backup handler” for the same DID method, one can achieve this with composition.
§Example
// A client that can resolve DIDs of our invented "foo" method.
struct Client;
impl Client {
// Resolves some of the DIDs we are interested in.
async fn resolve(&self, _did: &CoreDID) -> std::result::Result<CoreDocument, std::io::Error> {
todo!()
}
}
// This way we can essentially produce (cheap) clones of our client.
let client = std::sync::Arc::new(Client {});
// Get a clone we can move into a handler.
let client_clone = client.clone();
// Construct a resolver that resolves documents of type `CoreDocument`.
let mut resolver = Resolver::<CoreDocument>::new();
// Now we want to attach a handler that uses the client to resolve DIDs whose method is "foo".
resolver.attach_handler("foo".to_owned(), move |did: CoreDID| {
// We want to resolve the did asynchronously, but since we do not know when it will be awaited we
// let the future take ownership of the client by moving a clone into the asynchronous block.
let future_client = client_clone.clone();
async move { future_client.resolve(&did).await }
});
source§impl<DOC> Resolver<DOC, SingleThreadedCommand<DOC>>where
DOC: 'static,
impl<DOC> Resolver<DOC, SingleThreadedCommand<DOC>>where
DOC: 'static,
sourcepub fn attach_handler<D, F, Fut, DOCUMENT, E, DIDERR>(
&mut self,
method: String,
handler: F
)
pub fn attach_handler<D, F, Fut, DOCUMENT, E, DIDERR>( &mut self, method: String, handler: F )
Attach a new handler responsible for resolving DIDs of the given DID method.
The handler
is expected to be a closure taking an owned DID and asynchronously returning a DID Document
which can be converted to the type this Resolver
is parametrized over. The handler
is required to be
Clone
and 'static
hence all captured variables must satisfy these bounds. In this regard the
move
keyword and (possibly) wrapping values in an std::rc::Rc
may come in handy (see the example below).
NOTE: If there already exists a handler for this method then it will be replaced with the new handler. In the case where one would like to have a “backup handler” for the same DID method, one can achieve this with composition.
§Example
// A client that can resolve DIDs of our invented "foo" method.
struct Client;
impl Client {
// Resolves some of the DIDs we are interested in.
async fn resolve(&self, _did: &CoreDID) -> std::result::Result<CoreDocument, std::io::Error> {
todo!()
}
}
// This way we can essentially produce (cheap) clones of our client.
let client = std::rc::Rc::new(Client {});
// Get a clone we can move into a handler.
let client_clone = client.clone();
// Construct a resolver that resolves documents of type `CoreDocument`.
let mut resolver = SingleThreadedResolver::<CoreDocument>::new();
// Now we want to attach a handler that uses the client to resolve DIDs whose method is "foo".
resolver.attach_handler("foo".to_owned(), move |did: CoreDID| {
// We want to resolve the did asynchronously, but since we do not know when it will be awaited we
// let the future take ownership of the client by moving a clone into the asynchronous block.
let future_client = client_clone.clone();
async move { future_client.resolve(&did).await }
});
source§impl<DOC> Resolver<DOC>
impl<DOC> Resolver<DOC>
sourcepub fn attach_iota_handler<CLI>(&mut self, client: CLI)
pub fn attach_iota_handler<CLI>(&mut self, client: CLI)
Convenience method for attaching a new handler responsible for resolving IOTA DIDs.
See also attach_handler
.
sourcepub fn attach_multiple_iota_handlers<CLI, I>(&mut self, clients: I)where
CLI: IotaIdentityClientExt + Send + Sync + 'static,
I: IntoIterator<Item = (&'static str, CLI)>,
pub fn attach_multiple_iota_handlers<CLI, I>(&mut self, clients: I)where
CLI: IotaIdentityClientExt + Send + Sync + 'static,
I: IntoIterator<Item = (&'static str, CLI)>,
Convenience method for attaching multiple handlers responsible for resolving IOTA DIDs on multiple networks.
§Arguments
clients
- A collection of tuples where each tuple contains the name of the network name and its corresponding client.
§Examples
// Assume `smr_client` and `iota_client` are instances IOTA clients `iota_sdk::client::Client`.
attach_multiple_iota_handlers(vec![("smr", smr_client), ("iota", iota_client)]);
§See Also
§Note
- Using
attach_iota_handler
orattach_handler
for the IOTA method would override all previously added clients. - This function does not validate the provided configuration. Ensure that the provided
network name corresponds with the client, possibly by using
client.network_name()
.