use crate::session::{VtaEndpoint, resolve_vta_endpoint};
use super::error::ProvisionError;
#[derive(Clone, Debug, Default)]
pub struct ResolvedVta {
pub vta_did: String,
pub tsp_mediator_did: Option<String>,
pub mediator_did: Option<String>,
pub rest_url: Option<String>,
}
impl ResolvedVta {
#[must_use]
pub fn advertised(&self) -> Vec<crate::protocol::matching::Protocol> {
use crate::protocol::matching::Protocol;
let mut out = Vec::with_capacity(3);
if self.tsp_mediator_did.is_some() {
out.push(Protocol::Tsp);
}
if self.mediator_did.is_some() {
out.push(Protocol::Didcomm);
}
if self.rest_url.is_some() {
out.push(Protocol::Rest);
}
out
}
}
pub async fn resolve_vta(vta_did: &str) -> Result<ResolvedVta, ProvisionError> {
match resolve_vta_endpoint(vta_did)
.await
.map_err(|e| ProvisionError::Resolve {
vta_did: vta_did.to_string(),
message: e.to_string(),
})? {
VtaEndpoint::Tsp {
vta_did,
mediator_did,
didcomm_mediator_did,
rest_url,
} => Ok(ResolvedVta {
vta_did,
tsp_mediator_did: Some(mediator_did),
mediator_did: didcomm_mediator_did,
rest_url,
}),
VtaEndpoint::DIDComm {
vta_did,
mediator_did,
rest_url,
} => Ok(ResolvedVta {
vta_did,
tsp_mediator_did: None,
mediator_did: Some(mediator_did),
rest_url,
}),
VtaEndpoint::Rest { url } => Ok(ResolvedVta {
vta_did: vta_did.to_string(),
tsp_mediator_did: None,
mediator_did: None,
rest_url: Some(url),
}),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::protocol::matching::Protocol;
fn resolved(tsp: Option<&str>, didcomm: Option<&str>, rest: Option<&str>) -> ResolvedVta {
ResolvedVta {
vta_did: "did:webvh:scid:vta.example".into(),
tsp_mediator_did: tsp.map(str::to_string),
mediator_did: didcomm.map(str::to_string),
rest_url: rest.map(str::to_string),
}
}
#[test]
fn a_dual_transport_vta_reports_every_transport_it_offers() {
let r = resolved(
Some("did:webvh:scid:mediator.example"),
Some("did:webvh:scid:mediator.example"),
Some("https://vta.example"),
);
assert_eq!(
r.advertised(),
vec![Protocol::Tsp, Protocol::Didcomm, Protocol::Rest]
);
}
#[test]
fn a_tsp_only_vta_reports_tsp() {
let r = resolved(Some("did:webvh:scid:mediator.example"), None, None);
assert_eq!(r.advertised(), vec![Protocol::Tsp]);
}
#[test]
fn advertised_is_in_preference_order() {
let r = resolved(None, Some("did:webvh:scid:m"), Some("https://vta.example"));
assert_eq!(r.advertised(), vec![Protocol::Didcomm, Protocol::Rest]);
}
#[test]
fn a_vta_advertising_nothing_reports_nothing() {
assert!(resolved(None, None, None).advertised().is_empty());
}
}