Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add async for I/O calls #372

Merged
merged 9 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean to change the name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I learned that implementing Display is slightly preferable to implementing ToString because implementing Display also implements ToString plus you get format!() support

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
Loading