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

Decouple from UniFFI code-gen'd Web5Exception #334

Merged
merged 3 commits into from
Sep 4, 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
2 changes: 1 addition & 1 deletion bindings/web5_uniffi/src/web5.udl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace web5 {

[Error]
interface Web5Error {
Error(string type, string variant, string msg);
Error(string variant, string msg);
};

dictionary JwkData {
Expand Down
30 changes: 2 additions & 28 deletions bindings/web5_uniffi_wrapper/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use serde_json::Error as SerdeJsonError;
use std::sync::PoisonError;
use std::{any::type_name, fmt::Debug};
use std::fmt::Debug;
use thiserror::Error;
use web5::credentials::presentation_definition::PexError;
use web5::credentials::CredentialError;
Expand All @@ -9,41 +8,20 @@ use web5::errors::Web5Error as InnerWeb5Error;
#[derive(Debug, Error)]
pub enum Web5Error {
#[error("{msg}")]
Error {
r#type: String,
variant: String,
msg: String,
},
Error { variant: String, msg: String },
}

impl Web5Error {
pub fn from_poison_error<T>(error: PoisonError<T>, error_type: &str) -> Self {
Web5Error::Error {
r#type: error_type.to_string(),
variant: "PoisonError".to_string(),
msg: error.to_string(),
}
}

fn new<T>(error: T) -> Self
where
T: std::error::Error + 'static,
{
Self::Error {
r#type: type_of(&error).to_string(),
variant: variant_name(&error),
msg: error.to_string(),
}
}

pub fn r#type(&self) -> String {
match self {
Web5Error::Error {
r#type: error_type, ..
} => error_type.clone(),
}
}

pub fn variant(&self) -> String {
match self {
Web5Error::Error {
Expand All @@ -60,10 +38,6 @@ impl Web5Error {
}
}

fn type_of<T>(_: &T) -> &'static str {
type_name::<T>()
}

fn variant_name<T>(error: &T) -> String
where
T: Debug,
Expand Down
12 changes: 12 additions & 0 deletions bound/kt/src/main/kotlin/web5/sdk/Web5Exception.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package web5.sdk

class Web5Exception(
val variant: String,
override val message: String
) : Exception(message) {
companion object {
internal fun fromRustCore(e: web5.sdk.rust.Web5Exception.Exception): Web5Exception {
return Web5Exception(e.variant, e.msg)
}
}
}
16 changes: 16 additions & 0 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/Dsa.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
package web5.sdk.crypto

import web5.sdk.rust.Dsa as RustCoreDsa

enum class Dsa {
ED25519,
SECP256K1;
}

internal fun dsaFromRustCore(rustCore: RustCoreDsa): Dsa {
Copy link
Contributor

Choose a reason for hiding this comment

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

perfect

return when (rustCore) {
RustCoreDsa.ED25519 -> Dsa.ED25519
RustCoreDsa.SECP256K1 -> Dsa.SECP256K1
}
}

internal fun dsaToRustCore(dsa: Dsa): RustCoreDsa {
return when(dsa) {
Dsa.ED25519 -> RustCoreDsa.ED25519
Dsa.SECP256K1 -> RustCoreDsa.SECP256K1
}
}
10 changes: 8 additions & 2 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/Ed25519Generator.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package web5.sdk.crypto

import web5.sdk.Web5Exception
import web5.sdk.crypto.keys.Jwk
import web5.sdk.rust.ed25519GeneratorGenerate
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Generates private key material for Ed25519.
Expand All @@ -14,8 +16,12 @@ class Ed25519Generator {
* @return Jwk the JWK with private key material included.
*/
fun generate(): Jwk {
Copy link
Contributor

Choose a reason for hiding this comment

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

chad says:
You can simplify the generate() function by removing the redundant catch block for the generic Exception, as it will automatically be propagated if not caught.

Copy link
Contributor

Choose a reason for hiding this comment

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

also since there are a lot of these it could be cleaner to do it this way with return try:

    return try {
        val rustCoreJwkData = ed25519GeneratorGenerate()
        Jwk.fromRustCoreJwkData(rustCoreJwkData)
    } catch (e: RustCoreException) {
        throw Web5Exception.fromRustCore(e)
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nice catch! done

val rustCoreJwkData = ed25519GeneratorGenerate()
return Jwk.fromRustCoreJwkData(rustCoreJwkData)
try {
val rustCoreJwkData = ed25519GeneratorGenerate()
return Jwk.fromRustCoreJwkData(rustCoreJwkData)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package web5.sdk.crypto.keys

import web5.sdk.Web5Exception
import web5.sdk.crypto.signers.ToOuterSigner
import web5.sdk.crypto.signers.Signer
import web5.sdk.rust.InMemoryKeyManager as RustCoreInMemoryKeyManager
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* A class for managing cryptographic keys in-memory.
Expand All @@ -25,8 +27,12 @@ class InMemoryKeyManager (privateJwks: List<Jwk>) : KeyManager, KeyExporter {
* @return Jwk The public key represented as a JWK.
*/
override fun importPrivateJwk(privateJwk: Jwk): Jwk {
val rustCoreJwkData = this.rustCoreInMemoryKeyManager.importPrivateJwk(privateJwk.rustCoreJwkData)
return Jwk.fromRustCoreJwkData(rustCoreJwkData)
try {
val rustCoreJwkData = this.rustCoreInMemoryKeyManager.importPrivateJwk(privateJwk.rustCoreJwkData)
return Jwk.fromRustCoreJwkData(rustCoreJwkData)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}

/**
Expand All @@ -36,12 +42,20 @@ class InMemoryKeyManager (privateJwks: List<Jwk>) : KeyManager, KeyExporter {
* @return Signer The signer for the given public key.
*/
override fun getSigner(publicJwk: Jwk): Signer {
val rustCoreSigner = this.rustCoreInMemoryKeyManager.getSigner(publicJwk.rustCoreJwkData)
return ToOuterSigner(rustCoreSigner)
try {
val rustCoreSigner = this.rustCoreInMemoryKeyManager.getSigner(publicJwk.rustCoreJwkData)
return ToOuterSigner(rustCoreSigner)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}

override fun exportPrivateJwks(): List<Jwk> {
val rustCorePrivateJwksData = this.rustCoreInMemoryKeyManager.exportPrivateJwks()
return rustCorePrivateJwksData.map { Jwk.fromRustCoreJwkData(it) }
try {
val rustCorePrivateJwksData = this.rustCoreInMemoryKeyManager.exportPrivateJwks()
return rustCorePrivateJwksData.map { Jwk.fromRustCoreJwkData(it) }
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
14 changes: 10 additions & 4 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/keys/Jwk.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package web5.sdk.crypto.keys

import web5.sdk.Web5Exception
import web5.sdk.rust.Jwk as RustCoreJwk
import web5.sdk.rust.JwkData as RustCoreJwkData
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Partial representation of a [JSON Web Key as per RFC7517](https://tools.ietf.org/html/rfc7517).
Expand All @@ -24,8 +26,8 @@ data class Jwk (
y
)

internal companion object {
fun fromRustCoreJwkData(rustCoreJwkData: RustCoreJwkData): Jwk {
companion object {
internal fun fromRustCoreJwkData(rustCoreJwkData: RustCoreJwkData): Jwk {
return Jwk(
rustCoreJwkData.alg,
rustCoreJwkData.kty,
Expand All @@ -38,7 +40,11 @@ data class Jwk (
}

fun computeThumbprint(): String {
val rustCoreJwk = RustCoreJwk(rustCoreJwkData)
return rustCoreJwk.computeThumbprint()
try {
val rustCoreJwk = RustCoreJwk(rustCoreJwkData)
return rustCoreJwk.computeThumbprint()
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package web5.sdk.crypto.signers

import web5.sdk.Web5Exception
import web5.sdk.crypto.keys.Jwk
import web5.sdk.rust.Ed25519Signer as RustCoreEd25519Signer
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Implementation of Signer for Ed25519.
Expand All @@ -16,6 +18,10 @@ class Ed25519Signer(privateJwk: Jwk) : Signer {
* @return ByteArray the signature.
*/
override fun sign(payload: ByteArray): ByteArray {
return rustCoreSigner.sign(payload)
try {
return rustCoreSigner.sign(payload)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package web5.sdk.crypto.verifiers

import web5.sdk.Web5Exception
import web5.sdk.crypto.keys.Jwk
import web5.sdk.rust.Ed25519Verifier as RustCoreEd25519Verifier
import web5.sdk.rust.Web5Exception
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Implementation of Verifier for Ed25519.
Expand All @@ -18,6 +19,10 @@ class Ed25519Verifier(publicJwk: Jwk) : Verifier {
* @throws Web5Exception in the case of a failed verification
*/
override fun verify(message: ByteArray, signature: ByteArray) {
rustCoreVerifier.verify(message, signature)
try {
rustCoreVerifier.verify(message, signature)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
43 changes: 30 additions & 13 deletions bound/kt/src/main/kotlin/web5/sdk/dids/BearerDid.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package web5.sdk.dids

import web5.sdk.Web5Exception
import web5.sdk.crypto.keys.*
import web5.sdk.crypto.keys.ToInnerKeyExporter
import web5.sdk.crypto.keys.ToInnerKeyManager
import web5.sdk.crypto.keys.ToOuterKeyManager
import web5.sdk.crypto.signers.Signer
import web5.sdk.crypto.signers.ToOuterSigner
import web5.sdk.rust.BearerDid as RustCoreBearerDid
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Represents a Decentralized Identifier (DID) along with its DID document, key manager, metadata,
Expand All @@ -26,11 +28,15 @@ data class BearerDid private constructor(
did,
document,
keyManager,
RustCoreBearerDid(
did.toRustCoreDidData(),
document.toRustCore(),
ToInnerKeyManager(keyManager)
)
try {
RustCoreBearerDid(
did.toRustCoreDidData(),
document.toRustCore(),
ToInnerKeyManager(keyManager)
)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
)

companion object {
Expand All @@ -40,8 +46,12 @@ data class BearerDid private constructor(
* @param portableDid The PortableDid.
*/
fun fromPortableDid(portableDid: PortableDid): BearerDid {
val rustCoreBearerDid = RustCoreBearerDid.fromPortableDid(portableDid.rustCorePortableDid)
return BearerDid.fromRustCoreBearerDid(rustCoreBearerDid)
try {
val rustCoreBearerDid = RustCoreBearerDid.fromPortableDid(portableDid.rustCorePortableDid)
return fromRustCoreBearerDid(rustCoreBearerDid)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}

internal fun fromRustCoreBearerDid(rustCoreBearerDid: RustCoreBearerDid): BearerDid {
Expand All @@ -60,17 +70,24 @@ data class BearerDid private constructor(
* @return Signer The signer for the DID.
*/
fun getSigner(verificationMethodId: String): Signer {
val rustCoreSigner = rustCoreBearerDid.getSigner(verificationMethodId)

return ToOuterSigner(rustCoreSigner)
try {
val rustCoreSigner = rustCoreBearerDid.getSigner(verificationMethodId)
return ToOuterSigner(rustCoreSigner)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}

/**
* Returns the BearerDid represented as a PortableDid
*/
fun toPortableDid(keyExporter: KeyExporter): PortableDid {
val innerKeyExporter = ToInnerKeyExporter(keyExporter)
val rustCorePortableDid = rustCoreBearerDid.toPortableDid(innerKeyExporter)
return PortableDid.fromRustCorePortableDid(rustCorePortableDid)
try {
val innerKeyExporter = ToInnerKeyExporter(keyExporter)
val rustCorePortableDid = rustCoreBearerDid.toPortableDid(innerKeyExporter)
return PortableDid.fromRustCorePortableDid(rustCorePortableDid)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
12 changes: 9 additions & 3 deletions bound/kt/src/main/kotlin/web5/sdk/dids/Did.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package web5.sdk.dids

import web5.sdk.Web5Exception
import web5.sdk.rust.Did as RustCoreDid
import web5.sdk.rust.DidData as RustCoreDidData
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Representation of a [DID Core Identifier](https://www.w3.org/TR/did-core/#identifiers).
Expand All @@ -18,9 +20,13 @@ data class Did (
) {
companion object {
fun parse(uri: String): Did {
val rustCoreDid = RustCoreDid(uri)
val data = rustCoreDid.getData()
return fromRustCoreDidData(data)
try {
val rustCoreDid = RustCoreDid(uri)
val data = rustCoreDid.getData()
return fromRustCoreDidData(data)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}

internal fun fromRustCoreDidData(data: RustCoreDidData): Did {
Expand Down
Loading
Loading