pub struct Resolver<DOC = CoreDocument, CMD = SendSyncCommand<DOC>>{ /* private fields */ }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, SingleThreadedCommand<DOC>>where
DOC: From<CoreDocument> + 'static,
impl<DOC> Resolver<DOC, SingleThreadedCommand<DOC>>where
DOC: From<CoreDocument> + 'static,
Sourcepub fn attach_did_jwk_handler(&mut self)
pub fn attach_did_jwk_handler(&mut self)
Attaches a handler capable of resolving did:jwk DIDs.
Source§impl<DOC> Resolver<DOC>where
DOC: From<CoreDocument> + 'static,
impl<DOC> Resolver<DOC>where
DOC: From<CoreDocument> + 'static,
Sourcepub fn attach_did_jwk_handler(&mut self)
pub fn attach_did_jwk_handler(&mut self)
Attaches a handler capable of resolving did:jwk DIDs.
Source§impl<DOC> Resolver<DOC, SingleThreadedCommand<DOC>>where
DOC: From<CoreDocument> + 'static,
impl<DOC> Resolver<DOC, SingleThreadedCommand<DOC>>where
DOC: From<CoreDocument> + 'static,
Sourcepub fn attach_did_compositejwk_handler(&mut self)
pub fn attach_did_compositejwk_handler(&mut self)
Attaches a handler capable of resolving did:compositejwk DIDs.
Source§impl<DOC> Resolver<DOC>where
DOC: From<CoreDocument> + 'static,
impl<DOC> Resolver<DOC>where
DOC: From<CoreDocument> + 'static,
Sourcepub fn attach_did_compositejwk_handler(&mut self)
pub fn attach_did_compositejwk_handler(&mut self)
Attaches a handler capable of resolving did:compositejwk DIDs.
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: DidResolutionHandler + Send + Sync + 'static,
I: IntoIterator<Item = (&'static str, CLI)>,
pub fn attach_multiple_iota_handlers<CLI, I>(&mut self, clients: I)where
CLI: DidResolutionHandler + 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 `client1` and `client2` are instances of identity clients `IdentityClientReadOnly`.
attach_multiple_iota_handlers(vec![("client1", client1), ("client2", client2)]);§See Also
§Note
- Using
attach_iota_handlerorattach_handlerfor 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().
Trait Implementations§
Auto Trait Implementations§
impl<DOC, CMD> Freeze for Resolver<DOC, CMD>
impl<DOC, CMD> RefUnwindSafe for Resolver<DOC, CMD>where
DOC: RefUnwindSafe,
CMD: RefUnwindSafe,
impl<DOC, CMD> Send for Resolver<DOC, CMD>
impl<DOC, CMD> Sync for Resolver<DOC, CMD>
impl<DOC, CMD> Unpin for Resolver<DOC, CMD>
impl<DOC, CMD> UnwindSafe for Resolver<DOC, CMD>where
CMD: UnwindSafe,
DOC: UnwindSafe,
Blanket Implementations§
§impl<U> As for U
impl<U> As for U
§fn as_<T>(self) -> Twhere
T: CastFrom<U>,
fn as_<T>(self) -> Twhere
T: CastFrom<U>,
self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read more§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> ConvertTo<T> for Twhere
T: Send,
impl<T> ConvertTo<T> for Twhere
T: Send,
fn convert(self) -> Result<T, Error>
fn convert_unchecked(self) -> T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a Request§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.