Skip to content

Commit

Permalink
Add async for I/O calls (#372)
Browse files Browse the repository at this point in the history
  • Loading branch information
KendallWeihe authored Sep 30, 2024
1 parent 005bd3c commit ef1a319
Show file tree
Hide file tree
Showing 35 changed files with 656 additions and 469 deletions.
4 changes: 3 additions & 1 deletion bindings/web5_uniffi/src/web5.udl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ namespace web5 {

[Throws=Web5Error]
BearerDid did_web_create(string domain, DidWebCreateOptions? options);
[Throws=Web5Error]
ResolutionResult did_web_resolve([ByRef] string uri);

[Throws=Web5Error]
BearerDid did_dht_create(DidDhtCreateOptions? options);
[Throws=Web5Error]
void did_dht_publish(BearerDid bearer_did, string? gateway_url);
[Throws=Web5Error]
ResolutionResult did_dht_resolve([ByRef] string uri, string? gateway_url);
};

Expand Down Expand Up @@ -190,7 +192,7 @@ dictionary ResolutionResultData {
};

interface ResolutionResult {
[Name=resolve]
[Name=resolve, Throws=Web5Error]
constructor([ByRef] string uri);
ResolutionResultData get_data();
};
Expand Down
1 change: 1 addition & 0 deletions bindings/web5_uniffi_wrapper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ license-file.workspace = true
[dependencies]
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1.38.0", features = ["full"] }
web5 = { path = "../../crates/web5" }
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::errors::Result;
use crate::{errors::Result, get_rt};
use web5::credentials::presentation_definition::PresentationDefinition as InnerPresentationDefinition;

pub struct PresentationDefinition(pub InnerPresentationDefinition);
Expand All @@ -13,11 +13,14 @@ impl PresentationDefinition {
}

pub fn select_credentials(&self, vc_jwts: &Vec<String>) -> Result<Vec<String>> {
Ok(self.0.select_credentials(vc_jwts)?)
let rt = get_rt()?;
Ok(rt.block_on(self.0.select_credentials(vc_jwts))?)
}

pub fn create_presentation_from_credentials(&self, vc_jwts: &Vec<String>) -> Result<String> {
let presentation_result = self.0.create_presentation_from_credentials(vc_jwts)?;
let rt = get_rt()?;
let presentation_result =
rt.block_on(self.0.create_presentation_from_credentials(vc_jwts))?;
let json_serialized_presentation_result = serde_json::to_string(&presentation_result)?;

Ok(json_serialized_presentation_result)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::credentials::verifiable_credential_1_1::VerifiableCredential;
use crate::errors::Result;
use crate::get_rt;
use std::sync::Arc;
use web5::credentials::Issuer;
use web5::{
Expand All @@ -25,11 +26,12 @@ impl StatusListCredential {
.collect()
});

Ok(Self(InnerStatusListCredential::create(
let rt = get_rt()?;
Ok(Self(rt.block_on(InnerStatusListCredential::create(
issuer,
status_purpose,
inner_vcs,
)?))
))?))
}

pub fn get_base(&self) -> Result<Arc<VerifiableCredential>> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::get_rt;
use crate::{dids::bearer_did::BearerDid, errors::Result};
use std::{sync::Arc, time::SystemTime};
use web5::credentials::CredentialStatus;
Expand Down Expand Up @@ -60,8 +61,12 @@ impl VerifiableCredential {
evidence,
};

let inner_vc =
InnerVerifiableCredential::create(issuer, credential_subject, Some(inner_options))?;
let rt = get_rt()?;
let inner_vc = rt.block_on(InnerVerifiableCredential::create(
issuer,
credential_subject,
Some(inner_options),
))?;

Ok(Self {
inner_vc,
Expand Down Expand Up @@ -91,7 +96,8 @@ impl VerifiableCredential {
}

pub fn from_vc_jwt(vc_jwt: String, verify: bool) -> Result<Self> {
let inner_vc = InnerVerifiableCredential::from_vc_jwt(&vc_jwt, verify)?;
let rt = get_rt()?;
let inner_vc = rt.block_on(InnerVerifiableCredential::from_vc_jwt(&vc_jwt, verify))?;
let json_serialized_issuer = serde_json::to_string(&inner_vc.issuer)?;
let json_serialized_credential_subject =
serde_json::to_string(&inner_vc.credential_subject)?;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::get_rt;
use crate::{dids::bearer_did::BearerDid, errors::Result};
use serde_json::Value;
use std::collections::HashMap;
Expand Down Expand Up @@ -44,7 +45,12 @@ impl VerifiablePresentation {
additional_data,
};

let inner_vp = InnerVerifiablePresentation::create(holder, vc_jwts, Some(inner_options))?;
let rt = get_rt()?;
let inner_vp = rt.block_on(InnerVerifiablePresentation::create(
holder,
vc_jwts,
Some(inner_options),
))?;

Ok(Self { inner_vp })
}
Expand All @@ -68,8 +74,8 @@ impl VerifiablePresentation {
}

pub fn from_vp_jwt(vp_jwt: String, verify: bool) -> Result<Self> {
let inner_vp = InnerVerifiablePresentation::from_vp_jwt(&vp_jwt, verify)?;

let rt = get_rt()?;
let inner_vp = rt.block_on(InnerVerifiablePresentation::from_vp_jwt(&vp_jwt, verify))?;
Ok(Self { inner_vp })
}

Expand Down
14 changes: 9 additions & 5 deletions bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ use crate::{
crypto::key_manager::{KeyManager, ToInnerKeyManager},
dids::{bearer_did::BearerDid, resolution::resolution_result::ResolutionResult},
errors::Result,
get_rt,
};
use std::sync::Arc;
use web5::dids::{
data_model::{service::Service, verification_method::VerificationMethod},
methods::did_dht::{DidDht as InnerDidDht, DidDhtCreateOptions as InnerDidDhtCreateOptions},
};

pub fn did_dht_resolve(uri: &str, gateway_url: Option<String>) -> Arc<ResolutionResult> {
let resolution_result = InnerDidDht::resolve(uri, gateway_url);
Arc::new(ResolutionResult(resolution_result))
pub fn did_dht_resolve(uri: &str, gateway_url: Option<String>) -> Result<Arc<ResolutionResult>> {
let rt = get_rt()?;
let resolution_result = rt.block_on(InnerDidDht::resolve(uri, gateway_url));
Ok(Arc::new(ResolutionResult(resolution_result)))
}

#[derive(Default)]
Expand Down Expand Up @@ -39,10 +41,12 @@ pub fn did_dht_create(options: Option<DidDhtCreateOptions>) -> Result<Arc<Bearer
verification_method: o.verification_method,
});

let inner_bearer_did = InnerDidDht::create(inner_options)?;
let rt = get_rt()?;
let inner_bearer_did = rt.block_on(InnerDidDht::create(inner_options))?;
Ok(Arc::new(BearerDid(inner_bearer_did)))
}

pub fn did_dht_publish(bearer_did: Arc<BearerDid>, gateway_url: Option<String>) -> Result<()> {
Ok(InnerDidDht::publish(bearer_did.0.clone(), gateway_url)?)
let rt = get_rt()?;
Ok(rt.block_on(InnerDidDht::publish(bearer_did.0.clone(), gateway_url))?)
}
9 changes: 5 additions & 4 deletions bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
crypto::key_manager::{KeyManager, ToInnerKeyManager},
dids::{bearer_did::BearerDid, resolution::resolution_result::ResolutionResult},
errors::Result,
errors::Result, get_rt,
};
use std::sync::Arc;
use web5::{
Expand All @@ -14,9 +14,10 @@ use web5::{
},
};

pub fn did_web_resolve(uri: &str) -> Arc<ResolutionResult> {
let resolution_result = InnerDidWeb::resolve(uri);
Arc::new(ResolutionResult(resolution_result))
pub fn did_web_resolve(uri: &str) -> Result<Arc<ResolutionResult>> {
let rt = get_rt()?;
let resolution_result = rt.block_on(InnerDidWeb::resolve(uri));
Ok(Arc::new(ResolutionResult(resolution_result)))
}

#[derive(Default)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::{errors::Result, get_rt};
use web5::dids::resolution::resolution_result::ResolutionResult as InnerResolutionResult;

pub struct ResolutionResult(pub InnerResolutionResult);

impl ResolutionResult {
pub fn resolve(uri: &str) -> Self {
Self(InnerResolutionResult::resolve(uri))
pub fn resolve(uri: &str) -> Result<Self> {
let rt = get_rt()?;
Ok(Self(rt.block_on(InnerResolutionResult::resolve(uri))))
}

pub fn get_data(&self) -> InnerResolutionResult {
Expand Down
10 changes: 10 additions & 0 deletions bindings/web5_uniffi_wrapper/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
use errors::Result;
use tokio::runtime::Runtime;
use web5::errors::Web5Error;

pub mod credentials;
pub mod crypto;
pub mod dids;

pub mod errors;

pub fn get_rt() -> Result<Runtime> {
let rt = Runtime::new()
.map_err(|e| Web5Error::Unknown(format!("unable to instantiate tokio runtime {}", e)))?;
Ok(rt)
}
21 changes: 12 additions & 9 deletions bound/kt/src/main/kotlin/web5/sdk/rust/UniFFI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1429,7 +1429,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) {
if (lib.uniffi_web5_uniffi_checksum_func_did_dht_publish() != 17158.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_func_did_dht_resolve() != 56140.toShort()) {
if (lib.uniffi_web5_uniffi_checksum_func_did_dht_resolve() != 25411.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_func_did_jwk_create() != 64914.toShort()) {
Expand All @@ -1441,7 +1441,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) {
if (lib.uniffi_web5_uniffi_checksum_func_did_web_create() != 8722.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_func_did_web_resolve() != 15538.toShort()) {
if (lib.uniffi_web5_uniffi_checksum_func_did_web_resolve() != 6380.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_func_ed25519_generator_generate() != 57849.toShort()) {
Expand Down Expand Up @@ -1585,7 +1585,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) {
if (lib.uniffi_web5_uniffi_checksum_constructor_presentationdefinition_new() != 13282.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_constructor_resolutionresult_resolve() != 11404.toShort()) {
if (lib.uniffi_web5_uniffi_checksum_constructor_resolutionresult_resolve() != 14670.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_constructor_secp256k1signer_new() != 58975.toShort()) {
Expand Down Expand Up @@ -4986,9 +4986,10 @@ open class ResolutionResult: Disposable, AutoCloseable, ResolutionResultInterfac


companion object {
fun `resolve`(`uri`: kotlin.String): ResolutionResult {

@Throws(Web5Exception::class) fun `resolve`(`uri`: kotlin.String): ResolutionResult {
return FfiConverterTypeResolutionResult.lift(
uniffiRustCall() { _status ->
uniffiRustCallWithError(Web5Exception) { _status ->
UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_constructor_resolutionresult_resolve(
FfiConverterString.lower(`uri`),_status)
}
Expand Down Expand Up @@ -8588,9 +8589,10 @@ public object FfiConverterMapStringString: FfiConverterRustBuffer<Map<kotlin.Str
}


fun `didDhtResolve`(`uri`: kotlin.String, `gatewayUrl`: kotlin.String?): ResolutionResult {

@Throws(Web5Exception::class) fun `didDhtResolve`(`uri`: kotlin.String, `gatewayUrl`: kotlin.String?): ResolutionResult {
return FfiConverterTypeResolutionResult.lift(
uniffiRustCall() { _status ->
uniffiRustCallWithError(Web5Exception) { _status ->
UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_func_did_dht_resolve(
FfiConverterString.lower(`uri`),FfiConverterOptionalString.lower(`gatewayUrl`),_status)
}
Expand Down Expand Up @@ -8626,9 +8628,10 @@ public object FfiConverterMapStringString: FfiConverterRustBuffer<Map<kotlin.Str
)
}

fun `didWebResolve`(`uri`: kotlin.String): ResolutionResult {

@Throws(Web5Exception::class) fun `didWebResolve`(`uri`: kotlin.String): ResolutionResult {
return FfiConverterTypeResolutionResult.lift(
uniffiRustCall() { _status ->
uniffiRustCallWithError(Web5Exception) { _status ->
UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_func_did_web_resolve(
FfiConverterString.lower(`uri`),_status)
}
Expand Down
2 changes: 2 additions & 0 deletions crates/http-std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ repository.workspace = true
license-file.workspace = true

[dependencies]
async-trait = "0.1.83"
serde = { workspace = true }
lazy_static = { workspace = true }
thiserror = { workspace = true }
url = "2.5.0"
Expand Down
39 changes: 29 additions & 10 deletions crates/http-std/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,54 @@
use crate::Result;
use std::collections::HashMap;
use crate::{Error, Result};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt, str::FromStr};

#[async_trait]
pub trait Client: Send + Sync {
fn fetch(&self, url: &str, options: Option<FetchOptions>) -> Result<Response>;
async fn fetch(&self, url: &str, options: Option<FetchOptions>) -> Result<Response>;
}

#[derive(Default)]
#[derive(Default, Serialize, Deserialize)]
pub struct FetchOptions {
pub method: Option<Method>,
pub headers: Option<HashMap<String, String>>,
pub body: Option<Vec<u8>>,
}

#[derive(Serialize, Deserialize)]
pub struct Response {
pub status_code: u16,
pub headers: HashMap<String, String>,
pub body: Vec<u8>,
}

#[derive(Serialize, Deserialize)]
pub enum Method {
Get,
Post,
Put,
}

impl ToString for Method {
fn to_string(&self) -> String {
match self {
Method::Get => "GET".to_string(),
Method::Post => "POST".to_string(),
Method::Put => "PUT".to_string(),
impl fmt::Display for Method {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let method_str = match self {
Method::Get => "GET",
Method::Post => "POST",
Method::Put => "PUT",
};
write!(f, "{}", method_str)
}
}

impl FromStr for Method {
type Err = Error;

fn from_str(s: &str) -> Result<Self> {
match s.to_ascii_uppercase().as_ref() {
"GET" => Ok(Method::Get),
"POST" => Ok(Method::Post),
"PUT" => Ok(Method::Put),
_ => Err(Error::Parameter(format!("unknown method {}", s))),
}
}
}
8 changes: 4 additions & 4 deletions crates/http-std/src/default_client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{Client, Error, FetchOptions, Method, Response, Result};
use async_trait::async_trait;
use rustls::pki_types::ServerName;
use rustls::{ClientConfig, ClientConnection, RootCertStore, StreamOwned};
use rustls_native_certs::load_native_certs;
Expand Down Expand Up @@ -158,8 +159,9 @@ fn parse_response(response_bytes: &[u8]) -> Result<Response> {

pub struct DefaultClient;

#[async_trait]
impl Client for DefaultClient {
fn fetch(&self, url: &str, options: Option<FetchOptions>) -> Result<Response> {
async fn fetch(&self, url: &str, options: Option<FetchOptions>) -> Result<Response> {
let options = options.unwrap_or_default();
let destination = parse_destination(url)?;
let method = options.method.unwrap_or(Method::Get);
Expand All @@ -168,9 +170,7 @@ impl Client for DefaultClient {
"{} {} HTTP/1.1\r\n\
Host: {}\r\n\
Connection: close\r\n",
method.to_string(),
destination.path,
destination.host,
method, destination.path, destination.host,
);
if let Some(headers) = &options.headers {
if !headers.is_empty() {
Expand Down
Loading

0 comments on commit ef1a319

Please sign in to comment.