diff --git a/.lock b/.lock new file mode 100644 index 00000000..e69de29b diff --git a/crates.js b/crates.js new file mode 100644 index 00000000..e46a28d8 --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["jwt_compact"]; \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 00000000..f5402616 --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +Rustdoc help

Rustdoc help

Back
\ No newline at end of file diff --git a/implementors/core/clone/trait.Clone.js b/implementors/core/clone/trait.Clone.js new file mode 100644 index 00000000..109af38c --- /dev/null +++ b/implementors/core/clone/trait.Clone.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Clone for Ed25519"],["impl<A, T, H> Clone for SignedToken<A, T, H>where\n A: Algorithm,\n A::Signature: Clone,\n T: Clone,\n H: Clone,"],["impl Clone for Hs256Signature"],["impl Clone for Rsa"],["impl<'a> Clone for JsonWebKey<'a>"],["impl<'a> Clone for SecretBytes<'a>"],["impl<A: Clone> Clone for Renamed<A>"],["impl Clone for Hs512Signature"],["impl Clone for Hs384Signature"],["impl Clone for Claim"],["impl<T: Clone> Clone for StrongKey<T>"],["impl<T: Clone> Clone for StrongAlg<T>"],["impl Clone for Hs384"],["impl Clone for Empty"],["impl Clone for Hs512"],["impl<T: Clone> Clone for Claims<T>"],["impl<A: Algorithm + ?Sized, T> Clone for Validator<'_, A, T>"],["impl<const N: usize> Clone for Thumbprint<N>"],["impl<T: Clone, H: Clone> Clone for Token<T, H>"],["impl Clone for ModulusBits"],["impl<'a> Clone for RsaPrimeFactor<'a>"],["impl<T: Clone> Clone for Header<T>"],["impl Clone for Hs512Key"],["impl<'a> Clone for RsaPrivateParts<'a>"],["impl Clone for Hs256Key"],["impl Clone for Hs384Key"],["impl Clone for Hs256"],["impl Clone for KeyType"],["impl<'a, H: Clone> Clone for UntrustedToken<'a, H>"],["impl<F: Clone> Clone for TimeOptions<F>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.Eq.js b/implementors/core/cmp/trait.Eq.js new file mode 100644 index 00000000..fd090318 --- /dev/null +++ b/implementors/core/cmp/trait.Eq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Eq for ModulusBits"],["impl<const N: usize> Eq for Thumbprint<N>"],["impl Eq for Claim"],["impl Eq for KeyType"],["impl Eq for Hs512Signature"],["impl Eq for Empty"],["impl Eq for Hs256Signature"],["impl Eq for Ed25519"],["impl Eq for Hs256"],["impl<T: Eq> Eq for StrongKey<T>"],["impl<T: Eq> Eq for Claims<T>"],["impl Eq for Hs384Signature"],["impl Eq for Hs384"],["impl Eq for Hs512"],["impl Eq for Rsa"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.PartialEq.js b/implementors/core/cmp/trait.PartialEq.js new file mode 100644 index 00000000..12f463f6 --- /dev/null +++ b/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl PartialEq<Hs256Signature> for Hs256Signature"],["impl PartialEq<ModulusBits> for ModulusBits"],["impl PartialEq<SecretBytes<'_>> for SecretBytes<'_>"],["impl<'a> PartialEq<RsaPrivateParts<'a>> for RsaPrivateParts<'a>"],["impl<const N: usize> PartialEq<Thumbprint<N>> for Thumbprint<N>"],["impl<T: PartialEq> PartialEq<Claims<T>> for Claims<T>"],["impl PartialEq<Claim> for Claim"],["impl<'a> PartialEq<JsonWebKey<'a>> for JsonWebKey<'a>"],["impl PartialEq<Ed25519> for Ed25519"],["impl PartialEq<Hs384Signature> for Hs384Signature"],["impl PartialEq<Hs512> for Hs512"],["impl PartialEq<Empty> for Empty"],["impl<T: PartialEq> PartialEq<StrongKey<T>> for StrongKey<T>"],["impl PartialEq<Rsa> for Rsa"],["impl PartialEq<Hs512Signature> for Hs512Signature"],["impl<'a> PartialEq<RsaPrimeFactor<'a>> for RsaPrimeFactor<'a>"],["impl PartialEq<KeyType> for KeyType"],["impl PartialEq<Hs384> for Hs384"],["impl PartialEq<Hs256> for Hs256"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.AsMut.js b/implementors/core/convert/trait.AsMut.js new file mode 100644 index 00000000..23a888c4 --- /dev/null +++ b/implementors/core/convert/trait.AsMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl AsMut<[u8]> for Hs512Key"],["impl AsMut<[u8]> for Hs384Key"],["impl AsMut<[u8]> for Hs256Key"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.AsRef.js b/implementors/core/convert/trait.AsRef.js new file mode 100644 index 00000000..d060bb70 --- /dev/null +++ b/implementors/core/convert/trait.AsRef.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<T> AsRef<T> for StrongKey<T>"],["impl AsRef<[u8]> for Hs512Key"],["impl AsRef<[u8]> for Hs256Key"],["impl AsRef<[u8]> for Hs384Key"],["impl AsRef<[u8]> for SecretBytes<'_>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.From.js b/implementors/core/convert/trait.From.js new file mode 100644 index 00000000..87a47951 --- /dev/null +++ b/implementors/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> From<&'a Hs384Key> for JsonWebKey<'a>"],["impl<'a> From<&'a SecretKey> for JsonWebKey<'a>"],["impl From<&[u8]> for Hs384Key"],["impl<'a> From<&'a SigningKey<NistP256>> for JsonWebKey<'a>"],["impl<'a> From<&'a SecretKey> for JsonWebKey<'a>"],["impl<'a> From<&'a Hs256Key> for JsonWebKey<'a>"],["impl<'a> From<&'a VerifyingKey<NistP256>> for JsonWebKey<'a>"],["impl<const N: usize> From<&str> for Thumbprint<N>"],["impl<'a> From<&'a RsaPrivateKey> for JsonWebKey<'a>"],["impl<'a> From<&'a PublicKey> for JsonWebKey<'a>"],["impl<const N: usize> From<String> for Thumbprint<N>"],["impl From<&[u8]> for Hs512Key"],["impl<const N: usize> From<[u8; N]> for Thumbprint<N>"],["impl<'a> From<&'a Hs512Key> for JsonWebKey<'a>"],["impl From<&[u8]> for Hs256Key"],["impl<'a> From<&'a RsaPublicKey> for JsonWebKey<'a>"],["impl<'a> From<&'a PublicKey> for JsonWebKey<'a>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.TryFrom.js b/implementors/core/convert/trait.TryFrom.js new file mode 100644 index 00000000..196df4d0 --- /dev/null +++ b/implementors/core/convert/trait.TryFrom.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl TryFrom<usize> for ModulusBits"],["impl TryFrom<&JsonWebKey<'_>> for RsaPrivateKey"],["impl TryFrom<&JsonWebKey<'_>> for PublicKey"],["impl<'a, H: DeserializeOwned> TryFrom<&'a str> for UntrustedToken<'a, H>"],["impl TryFrom<&JsonWebKey<'_>> for Hs256Key"],["impl TryFrom<Hs512Key> for StrongKey<Hs512Key>"],["impl TryFrom<RsaPublicKey> for StrongKey<RsaPublicKey>"],["impl TryFrom<Hs384Key> for StrongKey<Hs384Key>"],["impl TryFrom<&JsonWebKey<'_>> for SecretKey"],["impl TryFrom<&JsonWebKey<'_>> for SigningKey"],["impl TryFrom<&JsonWebKey<'_>> for RsaPublicKey"],["impl TryFrom<&JsonWebKey<'_>> for PublicKey"],["impl TryFrom<&JsonWebKey<'_>> for VerifyingKey"],["impl TryFrom<Hs256Key> for StrongKey<Hs256Key>"],["impl TryFrom<RsaPrivateKey> for StrongKey<RsaPrivateKey>"],["impl TryFrom<&JsonWebKey<'_>> for Hs384Key"],["impl TryFrom<&JsonWebKey<'_>> for SecretKey"],["impl TryFrom<&JsonWebKey<'_>> for Hs512Key"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/default/trait.Default.js b/implementors/core/default/trait.Default.js new file mode 100644 index 00000000..4652d8b3 --- /dev/null +++ b/implementors/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Default for Hs512"],["impl<T: Default> Default for Header<T>"],["impl Default for Es256"],["impl<T: Default> Default for StrongAlg<T>"],["impl Default for Empty"],["impl Default for Hs256"],["impl<D> Default for Es256k<D>where\n D: FixedOutputReset<OutputSize = U32> + BlockSizeUser + Clone + Default + HashMarker,"],["impl Default for TimeOptions"],["impl Default for Ed25519"],["impl Default for Hs384"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/error/trait.Error.js b/implementors/core/error/trait.Error.js new file mode 100644 index 00000000..9a9d52d4 --- /dev/null +++ b/implementors/core/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Error for ValidationError"],["impl Error for RsaParseError"],["impl Error for ModulusBitsError"],["impl<T: Debug + 'static> Error for WeakKeyError<T>"],["impl Error for ParseError"],["impl Error for CreationError"],["impl Error for JwkError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Debug.js b/implementors/core/fmt/trait.Debug.js new file mode 100644 index 00000000..68f405a0 --- /dev/null +++ b/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> Debug for JsonWebKey<'a>"],["impl Debug for Hs384Signature"],["impl Debug for RsaSignature"],["impl<T: Debug> Debug for Claims<T>"],["impl<'a> Debug for RsaPrivateParts<'a>"],["impl<T: Debug> Debug for Header<T>"],["impl<T: Debug> Debug for StrongAlg<T>"],["impl Debug for ParseError"],["impl<T: Debug> Debug for WeakKeyError<T>"],["impl Debug for RsaParseError"],["impl<T: Debug> Debug for StrongKey<T>"],["impl Debug for CreationError"],["impl<'a> Debug for RsaPrimeFactor<'a>"],["impl Debug for Hs384"],["impl Debug for Es256"],["impl<T: Debug, H: Debug> Debug for Token<T, H>"],["impl<F: Debug> Debug for TimeOptions<F>"],["impl<'a, H: Debug> Debug for UntrustedToken<'a, H>"],["impl Debug for Hs384Key"],["impl Debug for Hs256"],["impl<'a, A: Debug + Algorithm + ?Sized, T: Debug> Debug for Validator<'a, A, T>where\n A::VerifyingKey: Debug,"],["impl Debug for JwkError"],["impl Debug for Empty"],["impl Debug for Ed25519"],["impl Debug for ModulusBitsError"],["impl Debug for Hs512Signature"],["impl Debug for Hs256Signature"],["impl Debug for ValidationError"],["impl<A: Debug> Debug for Renamed<A>"],["impl Debug for Hs256Key"],["impl Debug for Rsa"],["impl Debug for SecretBytes<'_>"],["impl<D: Debug> Debug for Es256k<D>"],["impl Debug for Hs512Key"],["impl Debug for Hs512"],["impl<A, T, H> Debug for SignedToken<A, T, H>where\n A: Algorithm,\n A::Signature: Debug,\n T: Debug,\n H: Debug,"],["impl Debug for KeyType"],["impl Debug for ModulusBits"],["impl<const N: usize> Debug for Thumbprint<N>"],["impl Debug for Claim"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Display.js b/implementors/core/fmt/trait.Display.js new file mode 100644 index 00000000..7ae012cc --- /dev/null +++ b/implementors/core/fmt/trait.Display.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Display for CreationError"],["impl Display for Claim"],["impl Display for ValidationError"],["impl<T> Display for WeakKeyError<T>"],["impl Display for KeyType"],["impl Display for ParseError"],["impl Display for ModulusBitsError"],["impl Display for JwkError"],["impl Display for RsaParseError"],["impl Display for JsonWebKey<'_>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/hash/trait.Hash.js b/implementors/core/hash/trait.Hash.js new file mode 100644 index 00000000..37f8aa6a --- /dev/null +++ b/implementors/core/hash/trait.Hash.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Hash for Ed25519"],["impl Hash for Empty"],["impl Hash for KeyType"],["impl Hash for Hs512"],["impl Hash for Hs256"],["impl Hash for Hs384"],["impl<const N: usize> Hash for Thumbprint<N>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Copy.js b/implementors/core/marker/trait.Copy.js new file mode 100644 index 00000000..2b09ced2 --- /dev/null +++ b/implementors/core/marker/trait.Copy.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Copy for Empty"],["impl Copy for Hs256"],["impl<T: Copy> Copy for StrongKey<T>"],["impl<A: Copy> Copy for Renamed<A>"],["impl Copy for Ed25519"],["impl<F: Copy> Copy for TimeOptions<F>"],["impl Copy for KeyType"],["impl Copy for Hs384"],["impl<A: Algorithm + ?Sized, T> Copy for Validator<'_, A, T>"],["impl Copy for Hs512"],["impl Copy for Rsa"],["impl Copy for ModulusBits"],["impl<T: Copy> Copy for StrongAlg<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Freeze.js b/implementors/core/marker/trait.Freeze.js new file mode 100644 index 00000000..9593944c --- /dev/null +++ b/implementors/core/marker/trait.Freeze.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> Freeze for SecretBytes<'a>",1,["jwt_compact::alg::generic::SecretBytes"]],["impl Freeze for Hs256Signature",1,["jwt_compact::alg::hmacs::Hs256Signature"]],["impl Freeze for Hs384Signature",1,["jwt_compact::alg::hmacs::Hs384Signature"]],["impl Freeze for Hs512Signature",1,["jwt_compact::alg::hmacs::Hs512Signature"]],["impl Freeze for Hs256Key",1,["jwt_compact::alg::hmacs::Hs256Key"]],["impl Freeze for Hs384Key",1,["jwt_compact::alg::hmacs::Hs384Key"]],["impl Freeze for Hs512Key",1,["jwt_compact::alg::hmacs::Hs512Key"]],["impl Freeze for Hs256",1,["jwt_compact::alg::hmacs::Hs256"]],["impl Freeze for Hs384",1,["jwt_compact::alg::hmacs::Hs384"]],["impl Freeze for Hs512",1,["jwt_compact::alg::hmacs::Hs512"]],["impl<D> Freeze for Es256k<D>",1,["jwt_compact::alg::es256k::Es256k"]],["impl Freeze for Ed25519",1,["jwt_compact::alg::eddsa_sodium::Ed25519"]],["impl Freeze for Es256",1,["jwt_compact::alg::p256::Es256"]],["impl Freeze for RsaSignature",1,["jwt_compact::alg::rsa::RsaSignature"]],["impl Freeze for ModulusBits",1,["jwt_compact::alg::rsa::ModulusBits"]],["impl Freeze for ModulusBitsError",1,["jwt_compact::alg::rsa::ModulusBitsError"]],["impl Freeze for Rsa",1,["jwt_compact::alg::rsa::Rsa"]],["impl Freeze for RsaParseError",1,["jwt_compact::alg::rsa::RsaParseError"]],["impl<T> Freeze for StrongKey<T>where\n T: Freeze,",1,["jwt_compact::alg::StrongKey"]],["impl<T> Freeze for WeakKeyError<T>where\n T: Freeze,",1,["jwt_compact::alg::WeakKeyError"]],["impl<T> Freeze for StrongAlg<T>where\n T: Freeze,",1,["jwt_compact::alg::StrongAlg"]],["impl<F> Freeze for TimeOptions<F>where\n F: Freeze,",1,["jwt_compact::claims::TimeOptions"]],["impl Freeze for Empty",1,["jwt_compact::claims::Empty"]],["impl<T> Freeze for Claims<T>where\n T: Freeze,",1,["jwt_compact::claims::Claims"]],["impl Freeze for ParseError",1,["jwt_compact::error::ParseError"]],["impl Freeze for ValidationError",1,["jwt_compact::error::ValidationError"]],["impl Freeze for Claim",1,["jwt_compact::error::Claim"]],["impl Freeze for CreationError",1,["jwt_compact::error::CreationError"]],["impl Freeze for KeyType",1,["jwt_compact::jwk::KeyType"]],["impl Freeze for JwkError",1,["jwt_compact::jwk::JwkError"]],["impl<'a> Freeze for JsonWebKey<'a>",1,["jwt_compact::jwk::JsonWebKey"]],["impl<'a> Freeze for RsaPrivateParts<'a>",1,["jwt_compact::jwk::RsaPrivateParts"]],["impl<'a> Freeze for RsaPrimeFactor<'a>",1,["jwt_compact::jwk::RsaPrimeFactor"]],["impl<const N: usize> Freeze for Thumbprint<N>",1,["jwt_compact::token::Thumbprint"]],["impl<T> Freeze for Header<T>where\n T: Freeze,",1,["jwt_compact::token::Header"]],["impl<'a, H> Freeze for UntrustedToken<'a, H>where\n H: Freeze,",1,["jwt_compact::token::UntrustedToken"]],["impl<T, H> Freeze for Token<T, H>where\n H: Freeze,\n T: Freeze,",1,["jwt_compact::token::Token"]],["impl<A: ?Sized, T, H> Freeze for SignedToken<A, T, H>where\n H: Freeze,\n T: Freeze,\n <A as Algorithm>::Signature: Freeze,",1,["jwt_compact::token::SignedToken"]],["impl<A> Freeze for Renamed<A>where\n A: Freeze,",1,["jwt_compact::traits::Renamed"]],["impl<'a, A: ?Sized, T> Freeze for Validator<'a, A, T>",1,["jwt_compact::traits::Validator"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Send.js b/implementors/core/marker/trait.Send.js new file mode 100644 index 00000000..4e307838 --- /dev/null +++ b/implementors/core/marker/trait.Send.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> Send for SecretBytes<'a>",1,["jwt_compact::alg::generic::SecretBytes"]],["impl Send for Hs256Signature",1,["jwt_compact::alg::hmacs::Hs256Signature"]],["impl Send for Hs384Signature",1,["jwt_compact::alg::hmacs::Hs384Signature"]],["impl Send for Hs512Signature",1,["jwt_compact::alg::hmacs::Hs512Signature"]],["impl Send for Hs256Key",1,["jwt_compact::alg::hmacs::Hs256Key"]],["impl Send for Hs384Key",1,["jwt_compact::alg::hmacs::Hs384Key"]],["impl Send for Hs512Key",1,["jwt_compact::alg::hmacs::Hs512Key"]],["impl Send for Hs256",1,["jwt_compact::alg::hmacs::Hs256"]],["impl Send for Hs384",1,["jwt_compact::alg::hmacs::Hs384"]],["impl Send for Hs512",1,["jwt_compact::alg::hmacs::Hs512"]],["impl<D> Send for Es256k<D>where\n D: Send,",1,["jwt_compact::alg::es256k::Es256k"]],["impl Send for Ed25519",1,["jwt_compact::alg::eddsa_sodium::Ed25519"]],["impl Send for Es256",1,["jwt_compact::alg::p256::Es256"]],["impl Send for RsaSignature",1,["jwt_compact::alg::rsa::RsaSignature"]],["impl Send for ModulusBits",1,["jwt_compact::alg::rsa::ModulusBits"]],["impl Send for ModulusBitsError",1,["jwt_compact::alg::rsa::ModulusBitsError"]],["impl Send for Rsa",1,["jwt_compact::alg::rsa::Rsa"]],["impl Send for RsaParseError",1,["jwt_compact::alg::rsa::RsaParseError"]],["impl<T> Send for StrongKey<T>where\n T: Send,",1,["jwt_compact::alg::StrongKey"]],["impl<T> Send for WeakKeyError<T>where\n T: Send,",1,["jwt_compact::alg::WeakKeyError"]],["impl<T> Send for StrongAlg<T>where\n T: Send,",1,["jwt_compact::alg::StrongAlg"]],["impl<F> Send for TimeOptions<F>where\n F: Send,",1,["jwt_compact::claims::TimeOptions"]],["impl Send for Empty",1,["jwt_compact::claims::Empty"]],["impl<T> Send for Claims<T>where\n T: Send,",1,["jwt_compact::claims::Claims"]],["impl Send for ParseError",1,["jwt_compact::error::ParseError"]],["impl Send for ValidationError",1,["jwt_compact::error::ValidationError"]],["impl Send for Claim",1,["jwt_compact::error::Claim"]],["impl Send for CreationError",1,["jwt_compact::error::CreationError"]],["impl Send for KeyType",1,["jwt_compact::jwk::KeyType"]],["impl Send for JwkError",1,["jwt_compact::jwk::JwkError"]],["impl<'a> Send for JsonWebKey<'a>",1,["jwt_compact::jwk::JsonWebKey"]],["impl<'a> Send for RsaPrivateParts<'a>",1,["jwt_compact::jwk::RsaPrivateParts"]],["impl<'a> Send for RsaPrimeFactor<'a>",1,["jwt_compact::jwk::RsaPrimeFactor"]],["impl<const N: usize> Send for Thumbprint<N>",1,["jwt_compact::token::Thumbprint"]],["impl<T> Send for Header<T>where\n T: Send,",1,["jwt_compact::token::Header"]],["impl<'a, H> Send for UntrustedToken<'a, H>where\n H: Send,",1,["jwt_compact::token::UntrustedToken"]],["impl<T, H> Send for Token<T, H>where\n H: Send,\n T: Send,",1,["jwt_compact::token::Token"]],["impl<A: ?Sized, T, H> Send for SignedToken<A, T, H>where\n H: Send,\n T: Send,\n <A as Algorithm>::Signature: Send,",1,["jwt_compact::token::SignedToken"]],["impl<A> Send for Renamed<A>where\n A: Send,",1,["jwt_compact::traits::Renamed"]],["impl<'a, A: ?Sized, T> Send for Validator<'a, A, T>where\n A: Sync,\n <A as Algorithm>::VerifyingKey: Sync,",1,["jwt_compact::traits::Validator"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.StructuralEq.js b/implementors/core/marker/trait.StructuralEq.js new file mode 100644 index 00000000..1a465d79 --- /dev/null +++ b/implementors/core/marker/trait.StructuralEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<T> StructuralEq for StrongKey<T>"],["impl StructuralEq for Hs384"],["impl StructuralEq for Hs512"],["impl StructuralEq for ModulusBits"],["impl StructuralEq for Claim"],["impl<T> StructuralEq for Claims<T>"],["impl StructuralEq for Ed25519"],["impl StructuralEq for KeyType"],["impl StructuralEq for Empty"],["impl StructuralEq for Hs512Signature"],["impl StructuralEq for Rsa"],["impl<const N: usize> StructuralEq for Thumbprint<N>"],["impl StructuralEq for Hs256"],["impl StructuralEq for Hs256Signature"],["impl StructuralEq for Hs384Signature"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.StructuralPartialEq.js b/implementors/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 00000000..954177f4 --- /dev/null +++ b/implementors/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl StructuralPartialEq for KeyType"],["impl StructuralPartialEq for Hs512Signature"],["impl StructuralPartialEq for Ed25519"],["impl StructuralPartialEq for Claim"],["impl<'a> StructuralPartialEq for JsonWebKey<'a>"],["impl<const N: usize> StructuralPartialEq for Thumbprint<N>"],["impl StructuralPartialEq for Hs384Signature"],["impl<'a> StructuralPartialEq for RsaPrivateParts<'a>"],["impl StructuralPartialEq for Empty"],["impl<'a> StructuralPartialEq for RsaPrimeFactor<'a>"],["impl StructuralPartialEq for Hs512"],["impl StructuralPartialEq for Hs384"],["impl StructuralPartialEq for Hs256"],["impl<T> StructuralPartialEq for Claims<T>"],["impl StructuralPartialEq for Rsa"],["impl<T> StructuralPartialEq for StrongKey<T>"],["impl StructuralPartialEq for Hs256Signature"],["impl StructuralPartialEq for ModulusBits"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Sync.js b/implementors/core/marker/trait.Sync.js new file mode 100644 index 00000000..b48b445e --- /dev/null +++ b/implementors/core/marker/trait.Sync.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> Sync for SecretBytes<'a>",1,["jwt_compact::alg::generic::SecretBytes"]],["impl Sync for Hs256Signature",1,["jwt_compact::alg::hmacs::Hs256Signature"]],["impl Sync for Hs384Signature",1,["jwt_compact::alg::hmacs::Hs384Signature"]],["impl Sync for Hs512Signature",1,["jwt_compact::alg::hmacs::Hs512Signature"]],["impl Sync for Hs256Key",1,["jwt_compact::alg::hmacs::Hs256Key"]],["impl Sync for Hs384Key",1,["jwt_compact::alg::hmacs::Hs384Key"]],["impl Sync for Hs512Key",1,["jwt_compact::alg::hmacs::Hs512Key"]],["impl Sync for Hs256",1,["jwt_compact::alg::hmacs::Hs256"]],["impl Sync for Hs384",1,["jwt_compact::alg::hmacs::Hs384"]],["impl Sync for Hs512",1,["jwt_compact::alg::hmacs::Hs512"]],["impl<D> Sync for Es256k<D>where\n D: Sync,",1,["jwt_compact::alg::es256k::Es256k"]],["impl Sync for Ed25519",1,["jwt_compact::alg::eddsa_sodium::Ed25519"]],["impl Sync for Es256",1,["jwt_compact::alg::p256::Es256"]],["impl Sync for RsaSignature",1,["jwt_compact::alg::rsa::RsaSignature"]],["impl Sync for ModulusBits",1,["jwt_compact::alg::rsa::ModulusBits"]],["impl Sync for ModulusBitsError",1,["jwt_compact::alg::rsa::ModulusBitsError"]],["impl Sync for Rsa",1,["jwt_compact::alg::rsa::Rsa"]],["impl Sync for RsaParseError",1,["jwt_compact::alg::rsa::RsaParseError"]],["impl<T> Sync for StrongKey<T>where\n T: Sync,",1,["jwt_compact::alg::StrongKey"]],["impl<T> Sync for WeakKeyError<T>where\n T: Sync,",1,["jwt_compact::alg::WeakKeyError"]],["impl<T> Sync for StrongAlg<T>where\n T: Sync,",1,["jwt_compact::alg::StrongAlg"]],["impl<F> Sync for TimeOptions<F>where\n F: Sync,",1,["jwt_compact::claims::TimeOptions"]],["impl Sync for Empty",1,["jwt_compact::claims::Empty"]],["impl<T> Sync for Claims<T>where\n T: Sync,",1,["jwt_compact::claims::Claims"]],["impl Sync for ParseError",1,["jwt_compact::error::ParseError"]],["impl Sync for ValidationError",1,["jwt_compact::error::ValidationError"]],["impl Sync for Claim",1,["jwt_compact::error::Claim"]],["impl Sync for CreationError",1,["jwt_compact::error::CreationError"]],["impl Sync for KeyType",1,["jwt_compact::jwk::KeyType"]],["impl Sync for JwkError",1,["jwt_compact::jwk::JwkError"]],["impl<'a> Sync for JsonWebKey<'a>",1,["jwt_compact::jwk::JsonWebKey"]],["impl<'a> Sync for RsaPrivateParts<'a>",1,["jwt_compact::jwk::RsaPrivateParts"]],["impl<'a> Sync for RsaPrimeFactor<'a>",1,["jwt_compact::jwk::RsaPrimeFactor"]],["impl<const N: usize> Sync for Thumbprint<N>",1,["jwt_compact::token::Thumbprint"]],["impl<T> Sync for Header<T>where\n T: Sync,",1,["jwt_compact::token::Header"]],["impl<'a, H> Sync for UntrustedToken<'a, H>where\n H: Sync,",1,["jwt_compact::token::UntrustedToken"]],["impl<T, H> Sync for Token<T, H>where\n H: Sync,\n T: Sync,",1,["jwt_compact::token::Token"]],["impl<A: ?Sized, T, H> Sync for SignedToken<A, T, H>where\n H: Sync,\n T: Sync,\n <A as Algorithm>::Signature: Sync,",1,["jwt_compact::token::SignedToken"]],["impl<A> Sync for Renamed<A>where\n A: Sync,",1,["jwt_compact::traits::Renamed"]],["impl<'a, A: ?Sized, T> Sync for Validator<'a, A, T>where\n A: Sync,\n <A as Algorithm>::VerifyingKey: Sync,",1,["jwt_compact::traits::Validator"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Unpin.js b/implementors/core/marker/trait.Unpin.js new file mode 100644 index 00000000..cd690a62 --- /dev/null +++ b/implementors/core/marker/trait.Unpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> Unpin for SecretBytes<'a>",1,["jwt_compact::alg::generic::SecretBytes"]],["impl Unpin for Hs256Signature",1,["jwt_compact::alg::hmacs::Hs256Signature"]],["impl Unpin for Hs384Signature",1,["jwt_compact::alg::hmacs::Hs384Signature"]],["impl Unpin for Hs512Signature",1,["jwt_compact::alg::hmacs::Hs512Signature"]],["impl Unpin for Hs256Key",1,["jwt_compact::alg::hmacs::Hs256Key"]],["impl Unpin for Hs384Key",1,["jwt_compact::alg::hmacs::Hs384Key"]],["impl Unpin for Hs512Key",1,["jwt_compact::alg::hmacs::Hs512Key"]],["impl Unpin for Hs256",1,["jwt_compact::alg::hmacs::Hs256"]],["impl Unpin for Hs384",1,["jwt_compact::alg::hmacs::Hs384"]],["impl Unpin for Hs512",1,["jwt_compact::alg::hmacs::Hs512"]],["impl<D> Unpin for Es256k<D>where\n D: Unpin,",1,["jwt_compact::alg::es256k::Es256k"]],["impl Unpin for Ed25519",1,["jwt_compact::alg::eddsa_sodium::Ed25519"]],["impl Unpin for Es256",1,["jwt_compact::alg::p256::Es256"]],["impl Unpin for RsaSignature",1,["jwt_compact::alg::rsa::RsaSignature"]],["impl Unpin for ModulusBits",1,["jwt_compact::alg::rsa::ModulusBits"]],["impl Unpin for ModulusBitsError",1,["jwt_compact::alg::rsa::ModulusBitsError"]],["impl Unpin for Rsa",1,["jwt_compact::alg::rsa::Rsa"]],["impl Unpin for RsaParseError",1,["jwt_compact::alg::rsa::RsaParseError"]],["impl<T> Unpin for StrongKey<T>where\n T: Unpin,",1,["jwt_compact::alg::StrongKey"]],["impl<T> Unpin for WeakKeyError<T>where\n T: Unpin,",1,["jwt_compact::alg::WeakKeyError"]],["impl<T> Unpin for StrongAlg<T>where\n T: Unpin,",1,["jwt_compact::alg::StrongAlg"]],["impl<F> Unpin for TimeOptions<F>where\n F: Unpin,",1,["jwt_compact::claims::TimeOptions"]],["impl Unpin for Empty",1,["jwt_compact::claims::Empty"]],["impl<T> Unpin for Claims<T>where\n T: Unpin,",1,["jwt_compact::claims::Claims"]],["impl Unpin for ParseError",1,["jwt_compact::error::ParseError"]],["impl Unpin for ValidationError",1,["jwt_compact::error::ValidationError"]],["impl Unpin for Claim",1,["jwt_compact::error::Claim"]],["impl Unpin for CreationError",1,["jwt_compact::error::CreationError"]],["impl Unpin for KeyType",1,["jwt_compact::jwk::KeyType"]],["impl Unpin for JwkError",1,["jwt_compact::jwk::JwkError"]],["impl<'a> Unpin for JsonWebKey<'a>",1,["jwt_compact::jwk::JsonWebKey"]],["impl<'a> Unpin for RsaPrivateParts<'a>",1,["jwt_compact::jwk::RsaPrivateParts"]],["impl<'a> Unpin for RsaPrimeFactor<'a>",1,["jwt_compact::jwk::RsaPrimeFactor"]],["impl<const N: usize> Unpin for Thumbprint<N>",1,["jwt_compact::token::Thumbprint"]],["impl<T> Unpin for Header<T>where\n T: Unpin,",1,["jwt_compact::token::Header"]],["impl<'a, H> Unpin for UntrustedToken<'a, H>where\n H: Unpin,",1,["jwt_compact::token::UntrustedToken"]],["impl<T, H> Unpin for Token<T, H>where\n H: Unpin,\n T: Unpin,",1,["jwt_compact::token::Token"]],["impl<A: ?Sized, T, H> Unpin for SignedToken<A, T, H>where\n H: Unpin,\n T: Unpin,\n <A as Algorithm>::Signature: Unpin,",1,["jwt_compact::token::SignedToken"]],["impl<A> Unpin for Renamed<A>where\n A: Unpin,",1,["jwt_compact::traits::Renamed"]],["impl<'a, A: ?Sized, T> Unpin for Validator<'a, A, T>",1,["jwt_compact::traits::Validator"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/deref/trait.Deref.js b/implementors/core/ops/deref/trait.Deref.js new file mode 100644 index 00000000..d0f33048 --- /dev/null +++ b/implementors/core/ops/deref/trait.Deref.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Deref for SecretBytes<'_>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/drop/trait.Drop.js b/implementors/core/ops/drop/trait.Drop.js new file mode 100644 index 00000000..e597569d --- /dev/null +++ b/implementors/core/ops/drop/trait.Drop.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Drop for SecretBytes<'_>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 00000000..c4d300c3 --- /dev/null +++ b/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> RefUnwindSafe for SecretBytes<'a>",1,["jwt_compact::alg::generic::SecretBytes"]],["impl RefUnwindSafe for Hs256Signature",1,["jwt_compact::alg::hmacs::Hs256Signature"]],["impl RefUnwindSafe for Hs384Signature",1,["jwt_compact::alg::hmacs::Hs384Signature"]],["impl RefUnwindSafe for Hs512Signature",1,["jwt_compact::alg::hmacs::Hs512Signature"]],["impl RefUnwindSafe for Hs256Key",1,["jwt_compact::alg::hmacs::Hs256Key"]],["impl RefUnwindSafe for Hs384Key",1,["jwt_compact::alg::hmacs::Hs384Key"]],["impl RefUnwindSafe for Hs512Key",1,["jwt_compact::alg::hmacs::Hs512Key"]],["impl RefUnwindSafe for Hs256",1,["jwt_compact::alg::hmacs::Hs256"]],["impl RefUnwindSafe for Hs384",1,["jwt_compact::alg::hmacs::Hs384"]],["impl RefUnwindSafe for Hs512",1,["jwt_compact::alg::hmacs::Hs512"]],["impl<D> RefUnwindSafe for Es256k<D>where\n D: RefUnwindSafe,",1,["jwt_compact::alg::es256k::Es256k"]],["impl RefUnwindSafe for Ed25519",1,["jwt_compact::alg::eddsa_sodium::Ed25519"]],["impl RefUnwindSafe for Es256",1,["jwt_compact::alg::p256::Es256"]],["impl RefUnwindSafe for RsaSignature",1,["jwt_compact::alg::rsa::RsaSignature"]],["impl RefUnwindSafe for ModulusBits",1,["jwt_compact::alg::rsa::ModulusBits"]],["impl RefUnwindSafe for ModulusBitsError",1,["jwt_compact::alg::rsa::ModulusBitsError"]],["impl RefUnwindSafe for Rsa",1,["jwt_compact::alg::rsa::Rsa"]],["impl RefUnwindSafe for RsaParseError",1,["jwt_compact::alg::rsa::RsaParseError"]],["impl<T> RefUnwindSafe for StrongKey<T>where\n T: RefUnwindSafe,",1,["jwt_compact::alg::StrongKey"]],["impl<T> RefUnwindSafe for WeakKeyError<T>where\n T: RefUnwindSafe,",1,["jwt_compact::alg::WeakKeyError"]],["impl<T> RefUnwindSafe for StrongAlg<T>where\n T: RefUnwindSafe,",1,["jwt_compact::alg::StrongAlg"]],["impl<F> RefUnwindSafe for TimeOptions<F>where\n F: RefUnwindSafe,",1,["jwt_compact::claims::TimeOptions"]],["impl RefUnwindSafe for Empty",1,["jwt_compact::claims::Empty"]],["impl<T> RefUnwindSafe for Claims<T>where\n T: RefUnwindSafe,",1,["jwt_compact::claims::Claims"]],["impl !RefUnwindSafe for ParseError",1,["jwt_compact::error::ParseError"]],["impl !RefUnwindSafe for ValidationError",1,["jwt_compact::error::ValidationError"]],["impl RefUnwindSafe for Claim",1,["jwt_compact::error::Claim"]],["impl !RefUnwindSafe for CreationError",1,["jwt_compact::error::CreationError"]],["impl RefUnwindSafe for KeyType",1,["jwt_compact::jwk::KeyType"]],["impl RefUnwindSafe for JwkError",1,["jwt_compact::jwk::JwkError"]],["impl<'a> RefUnwindSafe for JsonWebKey<'a>",1,["jwt_compact::jwk::JsonWebKey"]],["impl<'a> RefUnwindSafe for RsaPrivateParts<'a>",1,["jwt_compact::jwk::RsaPrivateParts"]],["impl<'a> RefUnwindSafe for RsaPrimeFactor<'a>",1,["jwt_compact::jwk::RsaPrimeFactor"]],["impl<const N: usize> RefUnwindSafe for Thumbprint<N>",1,["jwt_compact::token::Thumbprint"]],["impl<T> RefUnwindSafe for Header<T>where\n T: RefUnwindSafe,",1,["jwt_compact::token::Header"]],["impl<'a, H> RefUnwindSafe for UntrustedToken<'a, H>where\n H: RefUnwindSafe,",1,["jwt_compact::token::UntrustedToken"]],["impl<T, H> RefUnwindSafe for Token<T, H>where\n H: RefUnwindSafe,\n T: RefUnwindSafe,",1,["jwt_compact::token::Token"]],["impl<A: ?Sized, T, H> RefUnwindSafe for SignedToken<A, T, H>where\n H: RefUnwindSafe,\n T: RefUnwindSafe,\n <A as Algorithm>::Signature: RefUnwindSafe,",1,["jwt_compact::token::SignedToken"]],["impl<A> RefUnwindSafe for Renamed<A>where\n A: RefUnwindSafe,",1,["jwt_compact::traits::Renamed"]],["impl<'a, A: ?Sized, T> RefUnwindSafe for Validator<'a, A, T>where\n A: RefUnwindSafe,\n <A as Algorithm>::VerifyingKey: RefUnwindSafe,",1,["jwt_compact::traits::Validator"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/implementors/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 00000000..eef65ca8 --- /dev/null +++ b/implementors/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> UnwindSafe for SecretBytes<'a>",1,["jwt_compact::alg::generic::SecretBytes"]],["impl UnwindSafe for Hs256Signature",1,["jwt_compact::alg::hmacs::Hs256Signature"]],["impl UnwindSafe for Hs384Signature",1,["jwt_compact::alg::hmacs::Hs384Signature"]],["impl UnwindSafe for Hs512Signature",1,["jwt_compact::alg::hmacs::Hs512Signature"]],["impl UnwindSafe for Hs256Key",1,["jwt_compact::alg::hmacs::Hs256Key"]],["impl UnwindSafe for Hs384Key",1,["jwt_compact::alg::hmacs::Hs384Key"]],["impl UnwindSafe for Hs512Key",1,["jwt_compact::alg::hmacs::Hs512Key"]],["impl UnwindSafe for Hs256",1,["jwt_compact::alg::hmacs::Hs256"]],["impl UnwindSafe for Hs384",1,["jwt_compact::alg::hmacs::Hs384"]],["impl UnwindSafe for Hs512",1,["jwt_compact::alg::hmacs::Hs512"]],["impl<D> UnwindSafe for Es256k<D>where\n D: UnwindSafe,",1,["jwt_compact::alg::es256k::Es256k"]],["impl UnwindSafe for Ed25519",1,["jwt_compact::alg::eddsa_sodium::Ed25519"]],["impl UnwindSafe for Es256",1,["jwt_compact::alg::p256::Es256"]],["impl UnwindSafe for RsaSignature",1,["jwt_compact::alg::rsa::RsaSignature"]],["impl UnwindSafe for ModulusBits",1,["jwt_compact::alg::rsa::ModulusBits"]],["impl UnwindSafe for ModulusBitsError",1,["jwt_compact::alg::rsa::ModulusBitsError"]],["impl UnwindSafe for Rsa",1,["jwt_compact::alg::rsa::Rsa"]],["impl UnwindSafe for RsaParseError",1,["jwt_compact::alg::rsa::RsaParseError"]],["impl<T> UnwindSafe for StrongKey<T>where\n T: UnwindSafe,",1,["jwt_compact::alg::StrongKey"]],["impl<T> UnwindSafe for WeakKeyError<T>where\n T: UnwindSafe,",1,["jwt_compact::alg::WeakKeyError"]],["impl<T> UnwindSafe for StrongAlg<T>where\n T: UnwindSafe,",1,["jwt_compact::alg::StrongAlg"]],["impl<F> UnwindSafe for TimeOptions<F>where\n F: UnwindSafe,",1,["jwt_compact::claims::TimeOptions"]],["impl UnwindSafe for Empty",1,["jwt_compact::claims::Empty"]],["impl<T> UnwindSafe for Claims<T>where\n T: UnwindSafe,",1,["jwt_compact::claims::Claims"]],["impl !UnwindSafe for ParseError",1,["jwt_compact::error::ParseError"]],["impl !UnwindSafe for ValidationError",1,["jwt_compact::error::ValidationError"]],["impl UnwindSafe for Claim",1,["jwt_compact::error::Claim"]],["impl !UnwindSafe for CreationError",1,["jwt_compact::error::CreationError"]],["impl UnwindSafe for KeyType",1,["jwt_compact::jwk::KeyType"]],["impl UnwindSafe for JwkError",1,["jwt_compact::jwk::JwkError"]],["impl<'a> UnwindSafe for JsonWebKey<'a>",1,["jwt_compact::jwk::JsonWebKey"]],["impl<'a> UnwindSafe for RsaPrivateParts<'a>",1,["jwt_compact::jwk::RsaPrivateParts"]],["impl<'a> UnwindSafe for RsaPrimeFactor<'a>",1,["jwt_compact::jwk::RsaPrimeFactor"]],["impl<const N: usize> UnwindSafe for Thumbprint<N>",1,["jwt_compact::token::Thumbprint"]],["impl<T> UnwindSafe for Header<T>where\n T: UnwindSafe,",1,["jwt_compact::token::Header"]],["impl<'a, H> UnwindSafe for UntrustedToken<'a, H>where\n H: UnwindSafe,",1,["jwt_compact::token::UntrustedToken"]],["impl<T, H> UnwindSafe for Token<T, H>where\n H: UnwindSafe,\n T: UnwindSafe,",1,["jwt_compact::token::Token"]],["impl<A: ?Sized, T, H> UnwindSafe for SignedToken<A, T, H>where\n H: UnwindSafe,\n T: UnwindSafe,\n <A as Algorithm>::Signature: UnwindSafe,",1,["jwt_compact::token::SignedToken"]],["impl<A> UnwindSafe for Renamed<A>where\n A: UnwindSafe,",1,["jwt_compact::traits::Renamed"]],["impl<'a, A: ?Sized, T> UnwindSafe for Validator<'a, A, T>where\n A: RefUnwindSafe,\n <A as Algorithm>::VerifyingKey: RefUnwindSafe,",1,["jwt_compact::traits::Validator"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/str/traits/trait.FromStr.js b/implementors/core/str/traits/trait.FromStr.js new file mode 100644 index 00000000..89c0e0c5 --- /dev/null +++ b/implementors/core/str/traits/trait.FromStr.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl FromStr for Rsa"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/jwt_compact/alg/generic/trait.SigningKey.js b/implementors/jwt_compact/alg/generic/trait.SigningKey.js new file mode 100644 index 00000000..b263a378 --- /dev/null +++ b/implementors/jwt_compact/alg/generic/trait.SigningKey.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/jwt_compact/alg/generic/trait.VerifyingKey.js b/implementors/jwt_compact/alg/generic/trait.VerifyingKey.js new file mode 100644 index 00000000..b263a378 --- /dev/null +++ b/implementors/jwt_compact/alg/generic/trait.VerifyingKey.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/jwt_compact/traits/trait.Algorithm.js b/implementors/jwt_compact/traits/trait.Algorithm.js new file mode 100644 index 00000000..b263a378 --- /dev/null +++ b/implementors/jwt_compact/traits/trait.Algorithm.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/jwt_compact/traits/trait.AlgorithmExt.js b/implementors/jwt_compact/traits/trait.AlgorithmExt.js new file mode 100644 index 00000000..b263a378 --- /dev/null +++ b/implementors/jwt_compact/traits/trait.AlgorithmExt.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/jwt_compact/traits/trait.AlgorithmSignature.js b/implementors/jwt_compact/traits/trait.AlgorithmSignature.js new file mode 100644 index 00000000..b263a378 --- /dev/null +++ b/implementors/jwt_compact/traits/trait.AlgorithmSignature.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/serde/de/trait.Deserialize.js b/implementors/serde/de/trait.Deserialize.js new file mode 100644 index 00000000..7b4cc907 --- /dev/null +++ b/implementors/serde/de/trait.Deserialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'de, const N: usize> Deserialize<'de> for Thumbprint<N>"],["impl<'de, 'a> Deserialize<'de> for RsaPrivateParts<'a>"],["impl<'de, T> Deserialize<'de> for Header<T>where\n T: Deserialize<'de>,"],["impl<'de> Deserialize<'de> for SecretBytes<'_>"],["impl<'de> Deserialize<'de> for Empty"],["impl<'de, 'a> Deserialize<'de> for JsonWebKey<'a>"],["impl<'de, 'a> Deserialize<'de> for RsaPrimeFactor<'a>"],["impl<'de, T> Deserialize<'de> for Claims<T>where\n T: Deserialize<'de>,"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/serde/ser/trait.Serialize.js b/implementors/serde/ser/trait.Serialize.js new file mode 100644 index 00000000..1fb81fa7 --- /dev/null +++ b/implementors/serde/ser/trait.Serialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl<'a> Serialize for RsaPrimeFactor<'a>"],["impl<T> Serialize for Claims<T>where\n T: Serialize,"],["impl<const N: usize> Serialize for Thumbprint<N>"],["impl<T> Serialize for Header<T>where\n T: Serialize,"],["impl<'a> Serialize for JsonWebKey<'a>"],["impl Serialize for Empty"],["impl Serialize for SecretBytes<'_>"],["impl<'a> Serialize for RsaPrivateParts<'a>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/zeroize/trait.Zeroize.js b/implementors/zeroize/trait.Zeroize.js new file mode 100644 index 00000000..6a021ef7 --- /dev/null +++ b/implementors/zeroize/trait.Zeroize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"jwt_compact":[["impl Zeroize for Hs384Key"],["impl Zeroize for Hs512Key"],["impl Zeroize for Hs256Key"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/jwt_compact/alg/eddsa_sodium/struct.Ed25519.html b/jwt_compact/alg/eddsa_sodium/struct.Ed25519.html new file mode 100644 index 00000000..4d3334b8 --- /dev/null +++ b/jwt_compact/alg/eddsa_sodium/struct.Ed25519.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Ed25519.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/enum.ModulusBits.html b/jwt_compact/alg/enum.ModulusBits.html new file mode 100644 index 00000000..a35825c8 --- /dev/null +++ b/jwt_compact/alg/enum.ModulusBits.html @@ -0,0 +1,24 @@ +ModulusBits in jwt_compact::alg - Rust
#[non_exhaustive]
pub enum ModulusBits { + TwoKibibytes, + ThreeKibibytes, + FourKibibytes, +}
Available on crate feature rsa only.
Expand description

Bit length of an RSA key modulus (aka RSA key length).

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

TwoKibibytes

2048 bits. This is the minimum recommended key length as of 2020.

+
§

ThreeKibibytes

3072 bits.

+
§

FourKibibytes

4096 bits.

+

Implementations§

source§

impl ModulusBits

source

pub fn bits(self) -> usize

Converts this length to the numeric value.

+

Trait Implementations§

source§

impl Clone for ModulusBits

source§

fn clone(&self) -> ModulusBits

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ModulusBits

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<ModulusBits> for ModulusBits

source§

fn eq(&self, other: &ModulusBits) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryFrom<usize> for ModulusBits

§

type Error = ModulusBitsError

The type returned in the event of a conversion error.
source§

fn try_from(value: usize) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl Copy for ModulusBits

source§

impl Eq for ModulusBits

source§

impl StructuralEq for ModulusBits

source§

impl StructuralPartialEq for ModulusBits

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/es256k/struct.Es256k.html b/jwt_compact/alg/es256k/struct.Es256k.html new file mode 100644 index 00000000..4c6f42e9 --- /dev/null +++ b/jwt_compact/alg/es256k/struct.Es256k.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Es256k.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/generic/struct.SecretBytes.html b/jwt_compact/alg/generic/struct.SecretBytes.html new file mode 100644 index 00000000..b599cf73 --- /dev/null +++ b/jwt_compact/alg/generic/struct.SecretBytes.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.SecretBytes.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/generic/trait.SigningKey.html b/jwt_compact/alg/generic/trait.SigningKey.html new file mode 100644 index 00000000..f0fb5c44 --- /dev/null +++ b/jwt_compact/alg/generic/trait.SigningKey.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/trait.SigningKey.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/generic/trait.VerifyingKey.html b/jwt_compact/alg/generic/trait.VerifyingKey.html new file mode 100644 index 00000000..8e6c151a --- /dev/null +++ b/jwt_compact/alg/generic/trait.VerifyingKey.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/trait.VerifyingKey.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs256.html b/jwt_compact/alg/hmacs/struct.Hs256.html new file mode 100644 index 00000000..97f1e7da --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs256.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs256.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs256Key.html b/jwt_compact/alg/hmacs/struct.Hs256Key.html new file mode 100644 index 00000000..45b8febf --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs256Key.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs256Key.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs256Signature.html b/jwt_compact/alg/hmacs/struct.Hs256Signature.html new file mode 100644 index 00000000..73c125ff --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs256Signature.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs256Signature.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs384.html b/jwt_compact/alg/hmacs/struct.Hs384.html new file mode 100644 index 00000000..713eeb83 --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs384.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs384.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs384Key.html b/jwt_compact/alg/hmacs/struct.Hs384Key.html new file mode 100644 index 00000000..a63c6c2f --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs384Key.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs384Key.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs384Signature.html b/jwt_compact/alg/hmacs/struct.Hs384Signature.html new file mode 100644 index 00000000..99ec666b --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs384Signature.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs384Signature.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs512.html b/jwt_compact/alg/hmacs/struct.Hs512.html new file mode 100644 index 00000000..3c519853 --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs512.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs512.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs512Key.html b/jwt_compact/alg/hmacs/struct.Hs512Key.html new file mode 100644 index 00000000..7669b6c0 --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs512Key.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs512Key.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/hmacs/struct.Hs512Signature.html b/jwt_compact/alg/hmacs/struct.Hs512Signature.html new file mode 100644 index 00000000..d2acf25e --- /dev/null +++ b/jwt_compact/alg/hmacs/struct.Hs512Signature.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Hs512Signature.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/index.html b/jwt_compact/alg/index.html new file mode 100644 index 00000000..8e023b97 --- /dev/null +++ b/jwt_compact/alg/index.html @@ -0,0 +1,7 @@ +jwt_compact::alg - Rust

Module jwt_compact::alg

source ·
Expand description

Implementations of JWT signing / verification algorithms. Also contains generic traits +for signing and verifying keys.

+

Structs

  • Ed25519exonum-crypto or ed25519-dalek or ed25519-compact
    Integrity algorithm using digital signatures on the Ed25519 elliptic curve.
  • Es256p256
    ES256 signing algorithm. Implements elliptic curve digital signatures (ECDSA) +on the secp256r1 curve (aka P-256).
  • Es256kes256k or k256
    Algorithm implementing elliptic curve digital signatures (ECDSA) on the secp256k1 curve.
  • HS256 signing algorithm.
  • Signing / verifying key for HS256 algorithm. Zeroed on drop.
  • Signature produced by the Hs256 algorithm.
  • HS384 signing algorithm.
  • Signing / verifying key for HS384 algorithm. Zeroed on drop.
  • Signature produced by the Hs384 algorithm.
  • HS512 signing algorithm.
  • Signing / verifying key for HS512 algorithm. Zeroed on drop.
  • Signature produced by the Hs512 algorithm.
  • Error type returned when a conversion of an integer into ModulusBits fails.
  • Rsarsa
    Integrity algorithm using RSA digital signatures.
  • Errors that can occur when parsing an Rsa algorithm from a string.
  • Represents a whole RSA key, public and private parts.
  • Represents the public part of an RSA key.
  • RSA signature.
  • Generic container for secret bytes, which can be either owned or borrowed. +If owned, bytes are zeroized on drop.
  • Wrapper around a JWT algorithm signalling that it supports only StrongKeys.
  • Wrapper around keys allowing to enforce key strength requirements.
  • Error type used for fallible conversion into a StrongKey.

Enums

  • Bit length of an RSA key modulus (aka RSA key length).

Traits

  • Signing key for a specific signature cryptosystem. In the case of public-key cryptosystems, +this is a private key.
  • Verifying key for a specific signature cryptosystem. In the case of public-key cryptosystems, +this is a public key.
\ No newline at end of file diff --git a/jwt_compact/alg/p256/struct.Es256.html b/jwt_compact/alg/p256/struct.Es256.html new file mode 100644 index 00000000..d1af8b68 --- /dev/null +++ b/jwt_compact/alg/p256/struct.Es256.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Es256.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/rsa/enum.ModulusBits.html b/jwt_compact/alg/rsa/enum.ModulusBits.html new file mode 100644 index 00000000..b130153e --- /dev/null +++ b/jwt_compact/alg/rsa/enum.ModulusBits.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/enum.ModulusBits.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/rsa/struct.ModulusBitsError.html b/jwt_compact/alg/rsa/struct.ModulusBitsError.html new file mode 100644 index 00000000..46f8fbce --- /dev/null +++ b/jwt_compact/alg/rsa/struct.ModulusBitsError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.ModulusBitsError.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/rsa/struct.Rsa.html b/jwt_compact/alg/rsa/struct.Rsa.html new file mode 100644 index 00000000..273bee9f --- /dev/null +++ b/jwt_compact/alg/rsa/struct.Rsa.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.Rsa.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/rsa/struct.RsaParseError.html b/jwt_compact/alg/rsa/struct.RsaParseError.html new file mode 100644 index 00000000..260c0c9d --- /dev/null +++ b/jwt_compact/alg/rsa/struct.RsaParseError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.RsaParseError.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/rsa/struct.RsaPrivateKey.html b/jwt_compact/alg/rsa/struct.RsaPrivateKey.html new file mode 100644 index 00000000..a9a0cf02 --- /dev/null +++ b/jwt_compact/alg/rsa/struct.RsaPrivateKey.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.RsaPrivateKey.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/rsa/struct.RsaPublicKey.html b/jwt_compact/alg/rsa/struct.RsaPublicKey.html new file mode 100644 index 00000000..9b2ebee0 --- /dev/null +++ b/jwt_compact/alg/rsa/struct.RsaPublicKey.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.RsaPublicKey.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/rsa/struct.RsaSignature.html b/jwt_compact/alg/rsa/struct.RsaSignature.html new file mode 100644 index 00000000..1e26aef2 --- /dev/null +++ b/jwt_compact/alg/rsa/struct.RsaSignature.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../jwt_compact/alg/struct.RsaSignature.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/alg/sidebar-items.js b/jwt_compact/alg/sidebar-items.js new file mode 100644 index 00000000..a7b9127d --- /dev/null +++ b/jwt_compact/alg/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ModulusBits"],"struct":["Ed25519","Es256","Es256k","Hs256","Hs256Key","Hs256Signature","Hs384","Hs384Key","Hs384Signature","Hs512","Hs512Key","Hs512Signature","ModulusBitsError","Rsa","RsaParseError","RsaPrivateKey","RsaPublicKey","RsaSignature","SecretBytes","StrongAlg","StrongKey","WeakKeyError"],"trait":["SigningKey","VerifyingKey"]}; \ No newline at end of file diff --git a/jwt_compact/alg/struct.Ed25519.html b/jwt_compact/alg/struct.Ed25519.html new file mode 100644 index 00000000..0f0dedb1 --- /dev/null +++ b/jwt_compact/alg/struct.Ed25519.html @@ -0,0 +1,61 @@ +Ed25519 in jwt_compact::alg - Rust

Struct jwt_compact::alg::Ed25519

source ·
pub struct Ed25519;
Available on crate features exonum-crypto or ed25519-dalek or ed25519-compact only.
Expand description

Integrity algorithm using digital signatures on the Ed25519 elliptic curve.

+

The name of the algorithm is specified as EdDSA as per IANA registry. +Use with_specific_name() to switch to non-standard Ed25519.

+

Implementations§

source§

impl Ed25519

source

pub fn with_specific_name() -> Renamed<Self>

Creates an algorithm instance with the algorithm name specified as Ed25519. +This is a non-standard name, but it is used in some apps.

+

Trait Implementations§

source§

impl Algorithm for Ed25519

§

type SigningKey = SecretKey

Key used when issuing new tokens.
§

type VerifyingKey = PublicKey

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = Signature

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl Clone for Ed25519

source§

fn clone(&self) -> Ed25519

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Ed25519

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Ed25519

source§

fn default() -> Ed25519

Returns the “default value” for a type. Read more
source§

impl Hash for Ed25519

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Ed25519> for Ed25519

source§

fn eq(&self, other: &Ed25519) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl SigningKey<Ed25519> for SecretKey

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn to_verifying_key(&self) -> PublicKey

Converts a signing key to a verification key.
source§

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes. Read more
source§

impl VerifyingKey<Ed25519> for PublicKey

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Returns the key as raw bytes. Read more
source§

impl Copy for Ed25519

source§

impl Eq for Ed25519

source§

impl StructuralEq for Ed25519

source§

impl StructuralPartialEq for Ed25519

Auto Trait Implementations§

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Es256.html b/jwt_compact/alg/struct.Es256.html new file mode 100644 index 00000000..3f11d66e --- /dev/null +++ b/jwt_compact/alg/struct.Es256.html @@ -0,0 +1,54 @@ +Es256 in jwt_compact::alg - Rust

Struct jwt_compact::alg::Es256

source ·
pub struct Es256;
Available on crate feature p256 only.
Expand description

ES256 signing algorithm. Implements elliptic curve digital signatures (ECDSA) +on the secp256r1 curve (aka P-256).

+

Trait Implementations§

source§

impl Algorithm for Es256

§

type SigningKey = SigningKey<NistP256>

Key used when issuing new tokens.
§

type VerifyingKey = VerifyingKey<NistP256>

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = Signature<NistP256>

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl Debug for Es256

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Es256

source§

fn default() -> Es256

Returns the “default value” for a type. Read more
source§

impl SigningKey<Es256> for SigningKey

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn to_verifying_key(&self) -> VerifyingKey

Converts a signing key to a verification key.
source§

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes. Read more
source§

impl VerifyingKey<Es256> for VerifyingKey

source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Serializes the key as a 33-byte compressed form.

+
source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.

Auto Trait Implementations§

§

impl RefUnwindSafe for Es256

§

impl Send for Es256

§

impl Sync for Es256

§

impl Unpin for Es256

§

impl UnwindSafe for Es256

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Es256k.html b/jwt_compact/alg/struct.Es256k.html new file mode 100644 index 00000000..1c7bbc2d --- /dev/null +++ b/jwt_compact/alg/struct.Es256k.html @@ -0,0 +1,65 @@ +Es256k in jwt_compact::alg - Rust

Struct jwt_compact::alg::Es256k

source ·
pub struct Es256k<D = Sha256> { /* private fields */ }
Available on crate features es256k or k256 only.
Expand description

Algorithm implementing elliptic curve digital signatures (ECDSA) on the secp256k1 curve.

+

The algorithm does not fix the choice of the message digest algorithm; instead, +it is provided as a type parameter. SHA-256 is the default parameter value, +but it can be set to any cryptographically secure hash function with 32-byte output +(e.g., SHA3-256).

+

Implementations§

source§

impl<D> Es256k<D>where + D: FixedOutputReset<OutputSize = U32> + BlockSizeUser + Clone + Default + HashMarker,

source

pub fn new(context: Secp256k1<All>) -> Self

Available on crate feature es256k only.

Creates a new algorithm instance. +This is a (moderately) expensive operation, so if necessary, the algorithm should +be clone()d rather than created anew.

+

Trait Implementations§

source§

impl<D> Algorithm for Es256k<D>where + D: FixedOutputReset<OutputSize = U32> + BlockSizeUser + Clone + Default + HashMarker,

§

type SigningKey = SecretKey

Key used when issuing new tokens.
§

type VerifyingKey = PublicKey

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = Signature

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl<D: Debug> Debug for Es256k<D>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<D> Default for Es256k<D>where + D: FixedOutputReset<OutputSize = U32> + BlockSizeUser + Clone + Default + HashMarker,

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<D> RefUnwindSafe for Es256k<D>where + D: RefUnwindSafe,

§

impl<D> Send for Es256k<D>where + D: Send,

§

impl<D> Sync for Es256k<D>where + D: Sync,

§

impl<D> Unpin for Es256k<D>where + D: Unpin,

§

impl<D> UnwindSafe for Es256k<D>where + D: UnwindSafe,

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs256.html b/jwt_compact/alg/struct.Hs256.html new file mode 100644 index 00000000..5a04b0f2 --- /dev/null +++ b/jwt_compact/alg/struct.Hs256.html @@ -0,0 +1,58 @@ +Hs256 in jwt_compact::alg - Rust

Struct jwt_compact::alg::Hs256

source ·
pub struct Hs256;
Expand description

HS256 signing algorithm.

+

See RFC 7518 for the algorithm specification.

+

Trait Implementations§

source§

impl Algorithm for Hs256

§

type SigningKey = Hs256Key

Key used when issuing new tokens.
§

type VerifyingKey = Hs256Key

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = Hs256Signature

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl Clone for Hs256

source§

fn clone(&self) -> Hs256

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs256

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Hs256

source§

fn default() -> Hs256

Returns the “default value” for a type. Read more
source§

impl Hash for Hs256

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Hs256> for Hs256

source§

fn eq(&self, other: &Hs256) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl SigningKey<Hs256> for Hs256Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn to_verifying_key(&self) -> Self

Converts a signing key to a verification key.
source§

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes. Read more
source§

impl VerifyingKey<Hs256> for Hs256Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Returns the key as raw bytes. Read more
source§

impl Copy for Hs256

source§

impl Eq for Hs256

source§

impl StructuralEq for Hs256

source§

impl StructuralPartialEq for Hs256

Auto Trait Implementations§

§

impl RefUnwindSafe for Hs256

§

impl Send for Hs256

§

impl Sync for Hs256

§

impl Unpin for Hs256

§

impl UnwindSafe for Hs256

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs256Key.html b/jwt_compact/alg/struct.Hs256Key.html new file mode 100644 index 00000000..f1efa294 --- /dev/null +++ b/jwt_compact/alg/struct.Hs256Key.html @@ -0,0 +1,24 @@ +Hs256Key in jwt_compact::alg - Rust

Struct jwt_compact::alg::Hs256Key

source ·
pub struct Hs256Key(/* private fields */);
Expand description

Signing / verifying key for HS256 algorithm. Zeroed on drop.

+

Implementations§

source§

impl Hs256Key

source

pub fn generate<R: CryptoRng + RngCore>(rng: &mut R) -> StrongKey<Self>

Generates a random key using a cryptographically secure RNG.

+
source

pub fn new(bytes: impl AsRef<[u8]>) -> Self

Creates a key from the specified bytes.

+

Trait Implementations§

source§

impl AsMut<[u8]> for Hs256Key

source§

fn as_mut(&mut self) -> &mut [u8]

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<[u8]> for Hs256Key

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Hs256Key

source§

fn clone(&self) -> Hs256Key

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs256Key

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<&[u8]> for Hs256Key

source§

fn from(bytes: &[u8]) -> Self

Converts to this type from the input type.
source§

impl<'a> From<&'a Hs256Key> for JsonWebKey<'a>

source§

fn from(key: &'a Hs256Key) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl SigningKey<Hs256> for Hs256Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn to_verifying_key(&self) -> Self

Converts a signing key to a verification key.
source§

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes. Read more
source§

impl TryFrom<&JsonWebKey<'_>> for Hs256Key

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Hs256Key> for StrongKey<Hs256Key>

§

type Error = WeakKeyError<Hs256Key>

The type returned in the event of a conversion error.
source§

fn try_from(value: Hs256Key) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl VerifyingKey<Hs256> for Hs256Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Returns the key as raw bytes. Read more
source§

impl Zeroize for Hs256Key

source§

fn zeroize(&mut self)

Zero out this object from memory using Rust intrinsics which ensure the +zeroization operation is not “optimized away” by the compiler.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToHex for Twhere + T: AsRef<[u8]>,

source§

fn encode_hex<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Lower case +letters are used (e.g. f9b4ca)
source§

fn encode_hex_upper<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Upper case +letters are used (e.g. F9B4CA)
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs256Signature.html b/jwt_compact/alg/struct.Hs256Signature.html new file mode 100644 index 00000000..74ec45ad --- /dev/null +++ b/jwt_compact/alg/struct.Hs256Signature.html @@ -0,0 +1,18 @@ +Hs256Signature in jwt_compact::alg - Rust
pub struct Hs256Signature(/* private fields */);
Expand description

Signature produced by the Hs256 algorithm.

+

Trait Implementations§

source§

impl AlgorithmSignature for Hs256Signature

source§

const LENGTH: Option<NonZeroUsize> = _

Constant byte length of signatures supported by the Algorithm, or None if +the signature length is variable. Read more
source§

fn try_from_slice(bytes: &[u8]) -> Result<Self>

Attempts to restore a signature from a byte slice. This method may fail +if the slice is malformed.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Represents this signature as bytes.
source§

impl Clone for Hs256Signature

source§

fn clone(&self) -> Hs256Signature

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs256Signature

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<Hs256Signature> for Hs256Signature

source§

fn eq(&self, other: &Hs256Signature) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Hs256Signature

source§

impl StructuralEq for Hs256Signature

source§

impl StructuralPartialEq for Hs256Signature

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs384.html b/jwt_compact/alg/struct.Hs384.html new file mode 100644 index 00000000..9977f8c4 --- /dev/null +++ b/jwt_compact/alg/struct.Hs384.html @@ -0,0 +1,58 @@ +Hs384 in jwt_compact::alg - Rust

Struct jwt_compact::alg::Hs384

source ·
pub struct Hs384;
Expand description

HS384 signing algorithm.

+

See RFC 7518 for the algorithm specification.

+

Trait Implementations§

source§

impl Algorithm for Hs384

§

type SigningKey = Hs384Key

Key used when issuing new tokens.
§

type VerifyingKey = Hs384Key

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = Hs384Signature

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl Clone for Hs384

source§

fn clone(&self) -> Hs384

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs384

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Hs384

source§

fn default() -> Hs384

Returns the “default value” for a type. Read more
source§

impl Hash for Hs384

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Hs384> for Hs384

source§

fn eq(&self, other: &Hs384) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl SigningKey<Hs384> for Hs384Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn to_verifying_key(&self) -> Self

Converts a signing key to a verification key.
source§

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes. Read more
source§

impl VerifyingKey<Hs384> for Hs384Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Returns the key as raw bytes. Read more
source§

impl Copy for Hs384

source§

impl Eq for Hs384

source§

impl StructuralEq for Hs384

source§

impl StructuralPartialEq for Hs384

Auto Trait Implementations§

§

impl RefUnwindSafe for Hs384

§

impl Send for Hs384

§

impl Sync for Hs384

§

impl Unpin for Hs384

§

impl UnwindSafe for Hs384

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs384Key.html b/jwt_compact/alg/struct.Hs384Key.html new file mode 100644 index 00000000..82cd142b --- /dev/null +++ b/jwt_compact/alg/struct.Hs384Key.html @@ -0,0 +1,24 @@ +Hs384Key in jwt_compact::alg - Rust

Struct jwt_compact::alg::Hs384Key

source ·
pub struct Hs384Key(/* private fields */);
Expand description

Signing / verifying key for HS384 algorithm. Zeroed on drop.

+

Implementations§

source§

impl Hs384Key

source

pub fn generate<R: CryptoRng + RngCore>(rng: &mut R) -> StrongKey<Self>

Generates a random key using a cryptographically secure RNG.

+
source

pub fn new(bytes: impl AsRef<[u8]>) -> Self

Creates a key from the specified bytes.

+

Trait Implementations§

source§

impl AsMut<[u8]> for Hs384Key

source§

fn as_mut(&mut self) -> &mut [u8]

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<[u8]> for Hs384Key

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Hs384Key

source§

fn clone(&self) -> Hs384Key

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs384Key

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<&[u8]> for Hs384Key

source§

fn from(bytes: &[u8]) -> Self

Converts to this type from the input type.
source§

impl<'a> From<&'a Hs384Key> for JsonWebKey<'a>

source§

fn from(key: &'a Hs384Key) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl SigningKey<Hs384> for Hs384Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn to_verifying_key(&self) -> Self

Converts a signing key to a verification key.
source§

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes. Read more
source§

impl TryFrom<&JsonWebKey<'_>> for Hs384Key

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Hs384Key> for StrongKey<Hs384Key>

§

type Error = WeakKeyError<Hs384Key>

The type returned in the event of a conversion error.
source§

fn try_from(value: Hs384Key) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl VerifyingKey<Hs384> for Hs384Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Returns the key as raw bytes. Read more
source§

impl Zeroize for Hs384Key

source§

fn zeroize(&mut self)

Zero out this object from memory using Rust intrinsics which ensure the +zeroization operation is not “optimized away” by the compiler.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToHex for Twhere + T: AsRef<[u8]>,

source§

fn encode_hex<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Lower case +letters are used (e.g. f9b4ca)
source§

fn encode_hex_upper<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Upper case +letters are used (e.g. F9B4CA)
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs384Signature.html b/jwt_compact/alg/struct.Hs384Signature.html new file mode 100644 index 00000000..4e3919c5 --- /dev/null +++ b/jwt_compact/alg/struct.Hs384Signature.html @@ -0,0 +1,18 @@ +Hs384Signature in jwt_compact::alg - Rust
pub struct Hs384Signature(/* private fields */);
Expand description

Signature produced by the Hs384 algorithm.

+

Trait Implementations§

source§

impl AlgorithmSignature for Hs384Signature

source§

const LENGTH: Option<NonZeroUsize> = _

Constant byte length of signatures supported by the Algorithm, or None if +the signature length is variable. Read more
source§

fn try_from_slice(bytes: &[u8]) -> Result<Self>

Attempts to restore a signature from a byte slice. This method may fail +if the slice is malformed.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Represents this signature as bytes.
source§

impl Clone for Hs384Signature

source§

fn clone(&self) -> Hs384Signature

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs384Signature

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<Hs384Signature> for Hs384Signature

source§

fn eq(&self, other: &Hs384Signature) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Hs384Signature

source§

impl StructuralEq for Hs384Signature

source§

impl StructuralPartialEq for Hs384Signature

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs512.html b/jwt_compact/alg/struct.Hs512.html new file mode 100644 index 00000000..2bb757ed --- /dev/null +++ b/jwt_compact/alg/struct.Hs512.html @@ -0,0 +1,58 @@ +Hs512 in jwt_compact::alg - Rust

Struct jwt_compact::alg::Hs512

source ·
pub struct Hs512;
Expand description

HS512 signing algorithm.

+

See RFC 7518 for the algorithm specification.

+

Trait Implementations§

source§

impl Algorithm for Hs512

§

type SigningKey = Hs512Key

Key used when issuing new tokens.
§

type VerifyingKey = Hs512Key

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = Hs512Signature

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl Clone for Hs512

source§

fn clone(&self) -> Hs512

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs512

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Hs512

source§

fn default() -> Hs512

Returns the “default value” for a type. Read more
source§

impl Hash for Hs512

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Hs512> for Hs512

source§

fn eq(&self, other: &Hs512) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl SigningKey<Hs512> for Hs512Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn to_verifying_key(&self) -> Self

Converts a signing key to a verification key.
source§

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes. Read more
source§

impl VerifyingKey<Hs512> for Hs512Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Returns the key as raw bytes. Read more
source§

impl Copy for Hs512

source§

impl Eq for Hs512

source§

impl StructuralEq for Hs512

source§

impl StructuralPartialEq for Hs512

Auto Trait Implementations§

§

impl RefUnwindSafe for Hs512

§

impl Send for Hs512

§

impl Sync for Hs512

§

impl Unpin for Hs512

§

impl UnwindSafe for Hs512

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs512Key.html b/jwt_compact/alg/struct.Hs512Key.html new file mode 100644 index 00000000..42f6b956 --- /dev/null +++ b/jwt_compact/alg/struct.Hs512Key.html @@ -0,0 +1,24 @@ +Hs512Key in jwt_compact::alg - Rust

Struct jwt_compact::alg::Hs512Key

source ·
pub struct Hs512Key(/* private fields */);
Expand description

Signing / verifying key for HS512 algorithm. Zeroed on drop.

+

Implementations§

source§

impl Hs512Key

source

pub fn generate<R: CryptoRng + RngCore>(rng: &mut R) -> StrongKey<Self>

Generates a random key using a cryptographically secure RNG.

+
source

pub fn new(bytes: impl AsRef<[u8]>) -> Self

Creates a key from the specified bytes.

+

Trait Implementations§

source§

impl AsMut<[u8]> for Hs512Key

source§

fn as_mut(&mut self) -> &mut [u8]

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<[u8]> for Hs512Key

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Hs512Key

source§

fn clone(&self) -> Hs512Key

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs512Key

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<&[u8]> for Hs512Key

source§

fn from(bytes: &[u8]) -> Self

Converts to this type from the input type.
source§

impl<'a> From<&'a Hs512Key> for JsonWebKey<'a>

source§

fn from(key: &'a Hs512Key) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl SigningKey<Hs512> for Hs512Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn to_verifying_key(&self) -> Self

Converts a signing key to a verification key.
source§

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes. Read more
source§

impl TryFrom<&JsonWebKey<'_>> for Hs512Key

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Hs512Key> for StrongKey<Hs512Key>

§

type Error = WeakKeyError<Hs512Key>

The type returned in the event of a conversion error.
source§

fn try_from(value: Hs512Key) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl VerifyingKey<Hs512> for Hs512Key

source§

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Returns the key as raw bytes. Read more
source§

impl Zeroize for Hs512Key

source§

fn zeroize(&mut self)

Zero out this object from memory using Rust intrinsics which ensure the +zeroization operation is not “optimized away” by the compiler.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToHex for Twhere + T: AsRef<[u8]>,

source§

fn encode_hex<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Lower case +letters are used (e.g. f9b4ca)
source§

fn encode_hex_upper<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Upper case +letters are used (e.g. F9B4CA)
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Hs512Signature.html b/jwt_compact/alg/struct.Hs512Signature.html new file mode 100644 index 00000000..f4a927a1 --- /dev/null +++ b/jwt_compact/alg/struct.Hs512Signature.html @@ -0,0 +1,18 @@ +Hs512Signature in jwt_compact::alg - Rust
pub struct Hs512Signature(/* private fields */);
Expand description

Signature produced by the Hs512 algorithm.

+

Trait Implementations§

source§

impl AlgorithmSignature for Hs512Signature

source§

const LENGTH: Option<NonZeroUsize> = _

Constant byte length of signatures supported by the Algorithm, or None if +the signature length is variable. Read more
source§

fn try_from_slice(bytes: &[u8]) -> Result<Self>

Attempts to restore a signature from a byte slice. This method may fail +if the slice is malformed.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Represents this signature as bytes.
source§

impl Clone for Hs512Signature

source§

fn clone(&self) -> Hs512Signature

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hs512Signature

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<Hs512Signature> for Hs512Signature

source§

fn eq(&self, other: &Hs512Signature) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Hs512Signature

source§

impl StructuralEq for Hs512Signature

source§

impl StructuralPartialEq for Hs512Signature

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.ModulusBitsError.html b/jwt_compact/alg/struct.ModulusBitsError.html new file mode 100644 index 00000000..86325a79 --- /dev/null +++ b/jwt_compact/alg/struct.ModulusBitsError.html @@ -0,0 +1,14 @@ +ModulusBitsError in jwt_compact::alg - Rust
pub struct ModulusBitsError(/* private fields */);
Available on crate feature rsa only.
Expand description

Error type returned when a conversion of an integer into ModulusBits fails.

+

Trait Implementations§

source§

impl Debug for ModulusBitsError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ModulusBitsError

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ModulusBitsError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.Rsa.html b/jwt_compact/alg/struct.Rsa.html new file mode 100644 index 00000000..4e1ab360 --- /dev/null +++ b/jwt_compact/alg/struct.Rsa.html @@ -0,0 +1,83 @@ +Rsa in jwt_compact::alg - Rust

Struct jwt_compact::alg::Rsa

source ·
pub struct Rsa { /* private fields */ }
Available on crate feature rsa only.
Expand description

Integrity algorithm using RSA digital signatures.

+

Depending on the variation, the algorithm employs PKCS#1 v1.5 or PSS padding and +one of the hash functions from the SHA-2 family: SHA-256, SHA-384, or SHA-512. +See RFC 7518 for more details. Depending on the chosen parameters, +the name of the algorithm is one of RS256, RS384, RS512, PS256, PS384, PS512:

+
    +
  • R / P denote the padding scheme: PKCS#1 v1.5 for R, PSS for P
  • +
  • 256 / 384 / 512 denote the hash function
  • +
+

The length of RSA keys is not unequivocally specified by the algorithm; nevertheless, +it MUST be at least 2048 bits as per RFC 7518. To minimize risks of misconfiguration, +use StrongAlg wrapper around Rsa:

+ +
const ALG: StrongAlg<Rsa> = StrongAlg(Rsa::rs256());
+// `ALG` will not support RSA keys with unsecure lengths by design!
+

Implementations§

source§

impl Rsa

source

pub const fn rs256() -> Rsa

RSA with SHA-256 and PKCS#1 v1.5 padding.

+
source

pub const fn rs384() -> Rsa

RSA with SHA-384 and PKCS#1 v1.5 padding.

+
source

pub const fn rs512() -> Rsa

RSA with SHA-512 and PKCS#1 v1.5 padding.

+
source

pub const fn ps256() -> Rsa

RSA with SHA-256 and PSS padding.

+
source

pub const fn ps384() -> Rsa

RSA with SHA-384 and PSS padding.

+
source

pub const fn ps512() -> Rsa

RSA with SHA-512 and PSS padding.

+
source

pub fn with_name(name: &str) -> Self

RSA based on the specified algorithm name.

+
Panics
+
    +
  • Panics if the name is not one of the six RSA-based JWS algorithms. Prefer using +the FromStr trait if the conversion is potentially fallible.
  • +
+
source

pub fn generate<R: CryptoRng + RngCore>( + rng: &mut R, + modulus_bits: ModulusBits +) -> Result<(StrongKey<RsaPrivateKey>, StrongKey<RsaPublicKey>)>

Generates a new key pair with the specified modulus bit length (aka key length).

+

Trait Implementations§

source§

impl Algorithm for Rsa

§

type SigningKey = RsaPrivateKey

Key used when issuing new tokens.
§

type VerifyingKey = RsaPublicKey

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = RsaSignature

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl Clone for Rsa

source§

fn clone(&self) -> Rsa

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Rsa

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for Rsa

§

type Err = RsaParseError

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl PartialEq<Rsa> for Rsa

source§

fn eq(&self, other: &Rsa) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Rsa

source§

impl Eq for Rsa

source§

impl StructuralEq for Rsa

source§

impl StructuralPartialEq for Rsa

Auto Trait Implementations§

§

impl RefUnwindSafe for Rsa

§

impl Send for Rsa

§

impl Sync for Rsa

§

impl Unpin for Rsa

§

impl UnwindSafe for Rsa

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.RsaParseError.html b/jwt_compact/alg/struct.RsaParseError.html new file mode 100644 index 00000000..84c72ef1 --- /dev/null +++ b/jwt_compact/alg/struct.RsaParseError.html @@ -0,0 +1,14 @@ +RsaParseError in jwt_compact::alg - Rust
pub struct RsaParseError(/* private fields */);
Available on crate feature rsa only.
Expand description

Errors that can occur when parsing an Rsa algorithm from a string.

+

Trait Implementations§

source§

impl Debug for RsaParseError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for RsaParseError

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for RsaParseError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.RsaPrivateKey.html b/jwt_compact/alg/struct.RsaPrivateKey.html new file mode 100644 index 00000000..1aa8d941 --- /dev/null +++ b/jwt_compact/alg/struct.RsaPrivateKey.html @@ -0,0 +1,122 @@ +RsaPrivateKey in jwt_compact::alg - Rust
pub struct RsaPrivateKey { /* private fields */ }
Available on crate feature rsa only.
Expand description

Represents a whole RSA key, public and private parts.

+

Implementations§

source§

impl RsaPrivateKey

source

pub fn new<R>(rng: &mut R, bit_size: usize) -> Result<RsaPrivateKey, Error>where + R: CryptoRngCore + ?Sized,

Generate a new Rsa key pair of the given bit size using the passed in rng.

+
source

pub fn new_with_exp<R>( + rng: &mut R, + bit_size: usize, + exp: &BigUint +) -> Result<RsaPrivateKey, Error>where + R: CryptoRngCore + ?Sized,

Generate a new RSA key pair of the given bit size and the public exponent +using the passed in rng.

+

Unless you have specific needs, you should use RsaPrivateKey::new instead.

+
source

pub fn from_components( + n: BigUint, + e: BigUint, + d: BigUint, + primes: Vec<BigUint, Global> +) -> Result<RsaPrivateKey, Error>

Constructs an RSA key pair from individual components:

+
    +
  • n: RSA modulus
  • +
  • e: public exponent (i.e. encrypting exponent)
  • +
  • d: private exponent (i.e. decrypting exponent)
  • +
  • primes: prime factors of n: typically two primes p and q. More than two primes can +be provided for multiprime RSA, however this is generally not recommended. If no primes +are provided, a prime factor recovery algorithm will be employed to attempt to recover the +factors (as described in NIST SP 800-56B Revision 2 Appendix C.2). This algorithm only +works if there are just two prime factors p and q (as opposed to multiprime), and e +is between 2^16 and 2^256.
  • +
+
source

pub fn from_p_q( + p: BigUint, + q: BigUint, + public_exponent: BigUint +) -> Result<RsaPrivateKey, Error>

Constructs an RSA key pair from its two primes p and q.

+

This will rebuild the private exponent and the modulus.

+

Private exponent will be rebuilt using the method defined in +NIST 800-56B Section 6.2.1.

+
source

pub fn from_primes( + primes: Vec<BigUint, Global>, + public_exponent: BigUint +) -> Result<RsaPrivateKey, Error>

Constructs an RSA key pair from its primes.

+

This will rebuild the private exponent and the modulus.

+
source

pub fn to_public_key(&self) -> RsaPublicKey

Get the public key from the private key, cloning n and e.

+

Generally this is not needed since RsaPrivateKey implements the PublicKey trait, +but it can occasionally be useful to discard the private information entirely.

+
source

pub fn precompute(&mut self) -> Result<(), Error>

Performs some calculations to speed up private key operations.

+
source

pub fn clear_precomputed(&mut self)

Clears precomputed values by setting to None

+
source

pub fn crt_coefficient(&self) -> Option<BigUint>

Compute CRT coefficient: (1/q) mod p.

+
source

pub fn validate(&self) -> Result<(), Error>

Performs basic sanity checks on the key. +Returns Ok(()) if everything is good, otherwise an appropriate error.

+
source

pub fn decrypt<P>( + &self, + padding: P, + ciphertext: &[u8] +) -> Result<Vec<u8, Global>, Error>where + P: PaddingScheme,

Decrypt the given message.

+
source

pub fn decrypt_blinded<R, P>( + &self, + rng: &mut R, + padding: P, + ciphertext: &[u8] +) -> Result<Vec<u8, Global>, Error>where + R: CryptoRngCore, + P: PaddingScheme,

Decrypt the given message.

+

Uses rng to blind the decryption process.

+
source

pub fn sign<S>( + &self, + padding: S, + digest_in: &[u8] +) -> Result<Vec<u8, Global>, Error>where + S: SignatureScheme,

Sign the given digest.

+
source

pub fn sign_with_rng<R, S>( + &self, + rng: &mut R, + padding: S, + digest_in: &[u8] +) -> Result<Vec<u8, Global>, Error>where + R: CryptoRngCore, + S: SignatureScheme,

Sign the given digest using the provided rng, which is used in the +following ways depending on the SignatureScheme:

+
    +
  • Pkcs1v15Sign padding: uses the RNG +to mask the private key operation with random blinding, which helps +mitigate sidechannel attacks.
  • +
  • Pss always requires randomness. Use +Pss::new for a standard RSASSA-PSS signature, or +Pss::new_blinded for RSA-BSSA blind +signatures.
  • +
+

Trait Implementations§

source§

impl AsRef<RsaPublicKey> for RsaPrivateKey

source§

fn as_ref(&self) -> &RsaPublicKey

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for RsaPrivateKey

source§

fn clone(&self) -> RsaPrivateKey

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for RsaPrivateKey

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Drop for RsaPrivateKey

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl EncodePrivateKey for RsaPrivateKey

source§

fn to_pkcs8_der(&self) -> Result<SecretDocument, Error>

Serialize a [SecretDocument] containing a PKCS#8-encoded private key.
source§

impl<'a> From<&'a RsaPrivateKey> for JsonWebKey<'a>

Warning. Contrary to RFC 7518, this implementation does not set dp, dq, and qi +fields in the JWK root object, as well as d and t fields for additional factors +(i.e., in the oth array).

+
source§

fn from(key: &'a RsaPrivateKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl From<&RsaPrivateKey> for RsaPublicKey

source§

fn from(private_key: &RsaPrivateKey) -> RsaPublicKey

Converts to this type from the input type.
source§

impl<D> From<BlindedSigningKey<D>> for RsaPrivateKeywhere + D: Digest,

source§

fn from(key: BlindedSigningKey<D>) -> RsaPrivateKey

Converts to this type from the input type.
source§

impl From<RsaPrivateKey> for RsaPublicKey

source§

fn from(private_key: RsaPrivateKey) -> RsaPublicKey

Converts to this type from the input type.
source§

impl<D> From<SigningKey<D>> for RsaPrivateKeywhere + D: Digest,

source§

fn from(key: SigningKey<D>) -> RsaPrivateKey

Converts to this type from the input type.
source§

impl<D> From<SigningKey<D>> for RsaPrivateKeywhere + D: Digest,

source§

fn from(key: SigningKey<D>) -> RsaPrivateKey

Converts to this type from the input type.
source§

impl Hash for RsaPrivateKey

source§

fn hash<H>(&self, state: &mut H)where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<RsaPrivateKey> for RsaPrivateKey

source§

fn eq(&self, other: &RsaPrivateKey) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PrivateKeyParts for RsaPrivateKey

source§

fn d(&self) -> &BigUint

Returns the private exponent of the key.
source§

fn primes(&self) -> &[BigUint]

Returns the prime factors.
source§

fn dp(&self) -> Option<&BigUint>

Returns the precomputed dp value, D mod (P-1)
source§

fn dq(&self) -> Option<&BigUint>

Returns the precomputed dq value, D mod (Q-1)
source§

fn qinv(&self) -> Option<&BigInt>

Returns the precomputed qinv value, Q^-1 mod P
source§

fn crt_values(&self) -> Option<&[CrtValue]>

Returns an iterator over the CRT Values
source§

impl PublicKeyParts for RsaPrivateKey

source§

fn n(&self) -> &BigUint

Returns the modulus of the key.
source§

fn e(&self) -> &BigUint

Returns the public exponent of the key.
source§

fn size(&self) -> usize

Returns the modulus size in bytes. Raw signatures and ciphertexts for +or by this public key will have the same size.
source§

impl TryFrom<&JsonWebKey<'_>> for RsaPrivateKey

Warning. Contrary to RFC 7518 (at least, in spirit), this conversion ignores +dp, dq, and qi fields from JWK, as well as d and t fields for additional factors.

+
§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<PrivateKeyInfo<'_>> for RsaPrivateKey

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from( + private_key_info: PrivateKeyInfo<'_> +) -> Result<RsaPrivateKey, Error>

Performs the conversion.
source§

impl TryFrom<RsaPrivateKey> for StrongKey<RsaPrivateKey>

§

type Error = WeakKeyError<RsaPrivateKey>

The type returned in the event of a conversion error.
source§

fn try_from(key: RsaPrivateKey) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl Eq for RsaPrivateKey

source§

impl ZeroizeOnDrop for RsaPrivateKey

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> DecodePrivateKey for Twhere + T: for<'a> TryFrom<PrivateKeyInfo<'a>, Error = Error>,

§

fn from_pkcs8_der(bytes: &[u8]) -> Result<T, Error>

Deserialize PKCS#8 private key from ASN.1 DER-encoded data +(binary format).
§

impl<T> DecodeRsaPrivateKey for Twhere + T: for<'a> TryFrom<PrivateKeyInfo<'a>, Error = Error>,

§

fn from_pkcs1_der(private_key: &[u8]) -> Result<T, Error>

Deserialize PKCS#1 private key from ASN.1 DER-encoded data +(binary format).
§

impl<T> EncodeRsaPrivateKey for Twhere + T: EncodePrivateKey,

§

fn to_pkcs1_der(&self) -> Result<SecretDocument, Error>

Serialize a [SecretDocument] containing a PKCS#1-encoded private key.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.RsaPublicKey.html b/jwt_compact/alg/struct.RsaPublicKey.html new file mode 100644 index 00000000..32f99a39 --- /dev/null +++ b/jwt_compact/alg/struct.RsaPublicKey.html @@ -0,0 +1,63 @@ +RsaPublicKey in jwt_compact::alg - Rust
pub struct RsaPublicKey { /* private fields */ }
Available on crate feature rsa only.
Expand description

Represents the public part of an RSA key.

+

Implementations§

source§

impl RsaPublicKey

source

pub fn encrypt<R, P>( + &self, + rng: &mut R, + padding: P, + msg: &[u8] +) -> Result<Vec<u8, Global>, Error>where + R: CryptoRngCore, + P: PaddingScheme,

Encrypt the given message.

+
source

pub fn verify<S>( + &self, + scheme: S, + hashed: &[u8], + sig: &[u8] +) -> Result<(), Error>where + S: SignatureScheme,

Verify a signed message.

+

hashed must be the result of hashing the input using the hashing function +passed in through hash.

+

If the message is valid Ok(()) is returned, otherwise an Err indicating failure.

+
source§

impl RsaPublicKey

source

pub const MIN_PUB_EXPONENT: u64 = 2u64

Minimum value of the public exponent e.

+
source

pub const MAX_PUB_EXPONENT: u64 = 8_589_934_591u64

Maximum value of the public exponent e.

+
source

pub const MAX_SIZE: usize = 4_096usize

Maximum size of the modulus n in bits.

+
source

pub fn new(n: BigUint, e: BigUint) -> Result<RsaPublicKey, Error>

Create a new public key from its components.

+

This function accepts public keys with a modulus size up to 4096-bits, +i.e. RsaPublicKey::MAX_SIZE.

+
source

pub fn new_with_max_size( + n: BigUint, + e: BigUint, + max_size: usize +) -> Result<RsaPublicKey, Error>

Create a new public key from its components.

+
source

pub fn new_unchecked(n: BigUint, e: BigUint) -> RsaPublicKey

Create a new public key, bypassing checks around the modulus and public +exponent size.

+

This method is not recommended, and only intended for unusual use cases. +Most applications should use RsaPublicKey::new or +RsaPublicKey::new_with_max_size instead.

+

Trait Implementations§

source§

impl AsRef<RsaPublicKey> for RsaPrivateKey

source§

fn as_ref(&self) -> &RsaPublicKey

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for RsaPublicKey

source§

fn clone(&self) -> RsaPublicKey

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for RsaPublicKey

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl EncodePublicKey for RsaPublicKey

source§

fn to_public_key_der(&self) -> Result<Document, Error>

Serialize a [Document] containing a SPKI-encoded public key.
source§

impl<'a> From<&'a RsaPublicKey> for JsonWebKey<'a>

source§

fn from(key: &'a RsaPublicKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl From<&RsaPrivateKey> for RsaPublicKey

source§

fn from(private_key: &RsaPrivateKey) -> RsaPublicKey

Converts to this type from the input type.
source§

impl From<RsaPrivateKey> for RsaPublicKey

source§

fn from(private_key: RsaPrivateKey) -> RsaPublicKey

Converts to this type from the input type.
source§

impl<D> From<VerifyingKey<D>> for RsaPublicKeywhere + D: Digest,

source§

fn from(key: VerifyingKey<D>) -> RsaPublicKey

Converts to this type from the input type.
source§

impl<D> From<VerifyingKey<D>> for RsaPublicKeywhere + D: Digest,

source§

fn from(key: VerifyingKey<D>) -> RsaPublicKey

Converts to this type from the input type.
source§

impl Hash for RsaPublicKey

source§

fn hash<__H>(&self, state: &mut __H)where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<RsaPublicKey> for RsaPublicKey

source§

fn eq(&self, other: &RsaPublicKey) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PublicKeyParts for RsaPublicKey

source§

fn n(&self) -> &BigUint

Returns the modulus of the key.
source§

fn e(&self) -> &BigUint

Returns the public exponent of the key.
source§

fn size(&self) -> usize

Returns the modulus size in bytes. Raw signatures and ciphertexts for +or by this public key will have the same size.
source§

impl TryFrom<&JsonWebKey<'_>> for RsaPublicKey

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<RsaPublicKey> for StrongKey<RsaPublicKey>

§

type Error = WeakKeyError<RsaPublicKey>

The type returned in the event of a conversion error.
source§

fn try_from(key: RsaPublicKey) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<SubjectPublicKeyInfo<AnyRef<'_>, BitStringRef<'_>>> for RsaPublicKey

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from( + spki: SubjectPublicKeyInfo<AnyRef<'_>, BitStringRef<'_>> +) -> Result<RsaPublicKey, Error>

Performs the conversion.
source§

impl Eq for RsaPublicKey

source§

impl StructuralEq for RsaPublicKey

source§

impl StructuralPartialEq for RsaPublicKey

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> DecodePublicKey for Twhere + T: for<'a> TryFrom<SubjectPublicKeyInfo<AnyRef<'a>, BitStringRef<'a>>, Error = Error>,

§

fn from_public_key_der(bytes: &[u8]) -> Result<T, Error>

Deserialize object from ASN.1 DER-encoded [SubjectPublicKeyInfo] +(binary format).
§

impl<T> DecodeRsaPublicKey for Twhere + T: for<'a> TryFrom<SubjectPublicKeyInfo<AnyRef<'a>, BitStringRef<'a>>, Error = Error>,

§

fn from_pkcs1_der(public_key: &[u8]) -> Result<T, Error>

Deserialize object from ASN.1 DER-encoded [RsaPublicKey] +(binary format).
§

impl<T> EncodeRsaPublicKey for Twhere + T: EncodePublicKey,

§

fn to_pkcs1_der(&self) -> Result<Document, Error>

Serialize a [Document] containing a PKCS#1-encoded public key.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.RsaSignature.html b/jwt_compact/alg/struct.RsaSignature.html new file mode 100644 index 00000000..51404f18 --- /dev/null +++ b/jwt_compact/alg/struct.RsaSignature.html @@ -0,0 +1,15 @@ +RsaSignature in jwt_compact::alg - Rust
pub struct RsaSignature(/* private fields */);
Available on crate feature rsa only.
Expand description

RSA signature.

+

Trait Implementations§

source§

impl AlgorithmSignature for RsaSignature

source§

fn try_from_slice(bytes: &[u8]) -> Result<Self>

Attempts to restore a signature from a byte slice. This method may fail +if the slice is malformed.
source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Represents this signature as bytes.
source§

const LENGTH: Option<NonZeroUsize> = None

Constant byte length of signatures supported by the Algorithm, or None if +the signature length is variable. Read more
source§

impl Debug for RsaSignature

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.SecretBytes.html b/jwt_compact/alg/struct.SecretBytes.html new file mode 100644 index 00000000..563b33bd --- /dev/null +++ b/jwt_compact/alg/struct.SecretBytes.html @@ -0,0 +1,1089 @@ +SecretBytes in jwt_compact::alg - Rust
pub struct SecretBytes<'a>(/* private fields */);
Expand description

Generic container for secret bytes, which can be either owned or borrowed. +If owned, bytes are zeroized on drop.

+

Comparisons on SecretBytes are constant-time, but other operations (e.g., deserialization) +may be var-time.

+

Serialization

+

Represented in human-readable formats (JSON, TOML, YAML, etc.) as a base64-url encoded string +with no padding. For other formats (e.g., CBOR), SecretBytes will be serialized directly +as a byte sequence.

+

Implementations§

source§

impl<'a> SecretBytes<'a>

source

pub fn borrowed(bytes: &'a [u8]) -> Self

Creates secret bytes from a borrowed slice.

+
source

pub fn owned(bytes: Vec<u8>) -> Self

Creates secret bytes from an owned Vec.

+

Methods from Deref<Target = [u8]>§

source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the first N elements of the slice, or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the last N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk::<2>() {
+    assert_eq!(last, &[1, 2]);
+    assert_eq!(elements, &[0]);
+}
+
source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the last element of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+
Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
Panics
+

Panics if size is 0.

+
Examples
+
let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
source

pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>where + F: FnMut(&T, &T) -> bool,

🔬This is a nightly-only experimental API. (slice_group_by)

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

🔬This is a nightly-only experimental API. (slice_split_at_unchecked)

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T])

🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.split_array_ref::<0>();
+   assert_eq!(left, &[]);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<2>();
+    assert_eq!(left, &[1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<6>();
+    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N])

🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index from +the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index len - N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.rsplit_array_ref::<0>();
+   assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+   assert_eq!(right, &[]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<2>();
+    assert_eq!(left, [1, 2, 3, 4]);
+    assert_eq!(right, &[5, 6]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<6>();
+    assert_eq!(left, []);
+    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+}
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn contains(&self, x: &T) -> boolwhere + T: PartialEq<T>,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> boolwhere + T: PartialEq<T>,

Returns true if needle is a prefix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> boolwhere + T: PartialEq<T>,

Returns true if needle is a suffix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq<T>,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice.

+

If the slice does not start with prefix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq<T>,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice.

+

If the slice does not end with suffix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
Examples
+
#![feature(portable_simd)]
+use core::simd::SimdFloat;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    use std::simd::f32x4;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn is_sorted(&self) -> boolwhere + T: PartialOrd<T>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> boolwhere + F: FnMut(&'a T, &'a T) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine the ordering of two elements. Apart from that, it’s equivalent to +is_sorted; see its documentation for more information.

+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> boolwhere + F: FnMut(&'a T) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usizewhere + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
source

pub fn trim_ascii_start(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
source

pub fn trim_ascii_end(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
source

pub fn trim_ascii(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn flatten(&self) -> &[T]

🔬This is a nightly-only experimental API. (slice_flatten)

Takes a &[[T; N]], and flattens it to a &[T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].flatten(),
+    [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T, Global>where + T: Clone,

Copies self into a new Vec.

+
Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)

Copies self into a new Vec with an allocator.

+
Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T, Global>where + T: Copy,

Creates a vector by copying a slice n times.

+
Panics
+

This function will panic if the capacity would overflow.

+
Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8, Global>

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8, Global>

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl AsRef<[u8]> for SecretBytes<'_>

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<'a> Clone for SecretBytes<'a>

source§

fn clone(&self) -> SecretBytes<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for SecretBytes<'_>

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for SecretBytes<'_>

§

type Target = [u8]

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<'de> Deserialize<'de> for SecretBytes<'_>

source§

fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>

Deserialize this value from the given Serde deserializer. Read more
source§

impl Drop for SecretBytes<'_>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl PartialEq<SecretBytes<'_>> for SecretBytes<'_>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Serialize for SecretBytes<'_>

source§

fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for SecretBytes<'a>

§

impl<'a> Send for SecretBytes<'a>

§

impl<'a> Sync for SecretBytes<'a>

§

impl<'a> Unpin for SecretBytes<'a>

§

impl<'a> UnwindSafe for SecretBytes<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToHex for Twhere + T: AsRef<[u8]>,

source§

fn encode_hex<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Lower case +letters are used (e.g. f9b4ca)
source§

fn encode_hex_upper<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Upper case +letters are used (e.g. F9B4CA)
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/jwt_compact/alg/struct.StrongAlg.html b/jwt_compact/alg/struct.StrongAlg.html new file mode 100644 index 00000000..e8c2345f --- /dev/null +++ b/jwt_compact/alg/struct.StrongAlg.html @@ -0,0 +1,69 @@ +StrongAlg in jwt_compact::alg - Rust

Struct jwt_compact::alg::StrongAlg

source ·
pub struct StrongAlg<T>(pub T);
Expand description

Wrapper around a JWT algorithm signalling that it supports only StrongKeys.

+

The wrapper will implement Algorithm if the wrapped value is an Algorithm with both +signing and verifying keys convertible to StrongKeys.

+

Examples

+
let weak_key = Hs256Key::new(b"too short!");
+assert!(StrongKey::try_from(weak_key).is_err());
+// There is no way to create a `StrongKey` from `weak_key`!
+
+let strong_key: StrongKey<_> = Hs256Key::generate(&mut thread_rng());
+let claims = // ...
+let token = StrongAlg(Hs256)
+    .token(&Header::empty(), &claims, &strong_key)?;
+

Tuple Fields§

§0: T

Trait Implementations§

source§

impl<T: Algorithm> Algorithm for StrongAlg<T>where + StrongKey<T::SigningKey>: TryFrom<T::SigningKey>, + StrongKey<T::VerifyingKey>: TryFrom<T::VerifyingKey>,

§

type SigningKey = StrongKey<<T as Algorithm>::SigningKey>

Key used when issuing new tokens.
§

type VerifyingKey = StrongKey<<T as Algorithm>::VerifyingKey>

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = <T as Algorithm>::Signature

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl<T: Clone> Clone for StrongAlg<T>

source§

fn clone(&self) -> StrongAlg<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for StrongAlg<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Default> Default for StrongAlg<T>

source§

fn default() -> StrongAlg<T>

Returns the “default value” for a type. Read more
source§

impl<T: Copy> Copy for StrongAlg<T>

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for StrongAlg<T>where + T: RefUnwindSafe,

§

impl<T> Send for StrongAlg<T>where + T: Send,

§

impl<T> Sync for StrongAlg<T>where + T: Sync,

§

impl<T> Unpin for StrongAlg<T>where + T: Unpin,

§

impl<T> UnwindSafe for StrongAlg<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.StrongKey.html b/jwt_compact/alg/struct.StrongKey.html new file mode 100644 index 00000000..d859bf26 --- /dev/null +++ b/jwt_compact/alg/struct.StrongKey.html @@ -0,0 +1,40 @@ +StrongKey in jwt_compact::alg - Rust

Struct jwt_compact::alg::StrongKey

source ·
pub struct StrongKey<T>(/* private fields */);
Expand description

Wrapper around keys allowing to enforce key strength requirements.

+

The wrapper signifies that the key has supported strength as per the corresponding +algorithm spec. For example, RSA keys must have length at least 2,048 bits per RFC 7518. +Likewise, HS* keys must have at least the length of the hash output +(e.g., 32 bytes for HS256). Since these requirements sometimes clash with backward +compatibility (and sometimes a lesser level of security is enough), +notion of key strength is implemented in such an opt-in, composable way.

+

It’s easy to convert a StrongKey<T> to T via into_inner() or to +access &T via AsRef impl. In contrast, the reverse transformation is fallible, and +is defined with the help of TryFrom. The error type for TryFrom is WeakKeyError, +a simple wrapper around a weak key.

+

Examples

+

See StrongAlg docs for an example of usage.

+

Implementations§

source§

impl StrongKey<RsaPrivateKey>

source

pub fn to_public_key(&self) -> StrongKey<RsaPublicKey>

Converts this private key to a public key.

+
source§

impl<T> StrongKey<T>

source

pub fn into_inner(self) -> T

Returns the wrapped value.

+

Trait Implementations§

source§

impl<T> AsRef<T> for StrongKey<T>

source§

fn as_ref(&self) -> &T

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<T: Clone> Clone for StrongKey<T>

source§

fn clone(&self) -> StrongKey<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for StrongKey<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: PartialEq> PartialEq<StrongKey<T>> for StrongKey<T>

source§

fn eq(&self, other: &StrongKey<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryFrom<Hs256Key> for StrongKey<Hs256Key>

§

type Error = WeakKeyError<Hs256Key>

The type returned in the event of a conversion error.
source§

fn try_from(value: Hs256Key) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Hs384Key> for StrongKey<Hs384Key>

§

type Error = WeakKeyError<Hs384Key>

The type returned in the event of a conversion error.
source§

fn try_from(value: Hs384Key) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Hs512Key> for StrongKey<Hs512Key>

§

type Error = WeakKeyError<Hs512Key>

The type returned in the event of a conversion error.
source§

fn try_from(value: Hs512Key) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<RsaPrivateKey> for StrongKey<RsaPrivateKey>

§

type Error = WeakKeyError<RsaPrivateKey>

The type returned in the event of a conversion error.
source§

fn try_from(key: RsaPrivateKey) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<RsaPublicKey> for StrongKey<RsaPublicKey>

§

type Error = WeakKeyError<RsaPublicKey>

The type returned in the event of a conversion error.
source§

fn try_from(key: RsaPublicKey) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl<T: Copy> Copy for StrongKey<T>

source§

impl<T: Eq> Eq for StrongKey<T>

source§

impl<T> StructuralEq for StrongKey<T>

source§

impl<T> StructuralPartialEq for StrongKey<T>

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for StrongKey<T>where + T: RefUnwindSafe,

§

impl<T> Send for StrongKey<T>where + T: Send,

§

impl<T> Sync for StrongKey<T>where + T: Sync,

§

impl<T> Unpin for StrongKey<T>where + T: Unpin,

§

impl<T> UnwindSafe for StrongKey<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToHex for Twhere + T: AsRef<[u8]>,

source§

fn encode_hex<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Lower case +letters are used (e.g. f9b4ca)
source§

fn encode_hex_upper<U>(&self) -> Uwhere + U: FromIterator<char>,

Encode the hex strict representing self into the result. Upper case +letters are used (e.g. F9B4CA)
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/struct.WeakKeyError.html b/jwt_compact/alg/struct.WeakKeyError.html new file mode 100644 index 00000000..ff1b7b9e --- /dev/null +++ b/jwt_compact/alg/struct.WeakKeyError.html @@ -0,0 +1,20 @@ +WeakKeyError in jwt_compact::alg - Rust
pub struct WeakKeyError<T>(pub T);
Expand description

Error type used for fallible conversion into a StrongKey.

+

The error wraps around a weak key, which can be extracted for further use.

+

Tuple Fields§

§0: T

Trait Implementations§

source§

impl<T: Debug> Debug for WeakKeyError<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Display for WeakKeyError<T>

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Debug + 'static> Error for WeakKeyError<T>

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for WeakKeyError<T>where + T: RefUnwindSafe,

§

impl<T> Send for WeakKeyError<T>where + T: Send,

§

impl<T> Sync for WeakKeyError<T>where + T: Sync,

§

impl<T> Unpin for WeakKeyError<T>where + T: Unpin,

§

impl<T> UnwindSafe for WeakKeyError<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/alg/trait.SigningKey.html b/jwt_compact/alg/trait.SigningKey.html new file mode 100644 index 00000000..965c482b --- /dev/null +++ b/jwt_compact/alg/trait.SigningKey.html @@ -0,0 +1,17 @@ +SigningKey in jwt_compact::alg - Rust
pub trait SigningKey<T>: Sizedwhere
+    T: Algorithm<SigningKey = Self>,{
+    // Required methods
+    fn from_slice(raw: &[u8]) -> Result<Self>;
+    fn to_verifying_key(&self) -> T::VerifyingKey;
+    fn as_bytes(&self) -> SecretBytes<'_>;
+}
Expand description

Signing key for a specific signature cryptosystem. In the case of public-key cryptosystems, +this is a private key.

+

This trait provides a uniform interface for different backends / implementations +of the same cryptosystem.

+

Required Methods§

source

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.

+
source

fn to_verifying_key(&self) -> T::VerifyingKey

Converts a signing key to a verification key.

+
source

fn as_bytes(&self) -> SecretBytes<'_>

Returns the key as raw bytes.

+

Implementations should return Cow::Borrowed whenever possible (that is, if the bytes +are actually stored within the implementing data structure).

+

Implementations on Foreign Types§

source§

impl SigningKey<Es256> for SigningKey

source§

fn from_slice(raw: &[u8]) -> Result<Self>

source§

fn to_verifying_key(&self) -> VerifyingKey

source§

fn as_bytes(&self) -> SecretBytes<'_>

source§

impl SigningKey<Ed25519> for SecretKey

source§

fn from_slice(raw: &[u8]) -> Result<Self>

source§

fn to_verifying_key(&self) -> PublicKey

source§

fn as_bytes(&self) -> SecretBytes<'_>

Implementors§

\ No newline at end of file diff --git a/jwt_compact/alg/trait.VerifyingKey.html b/jwt_compact/alg/trait.VerifyingKey.html new file mode 100644 index 00000000..99cdbe9a --- /dev/null +++ b/jwt_compact/alg/trait.VerifyingKey.html @@ -0,0 +1,16 @@ +VerifyingKey in jwt_compact::alg - Rust
pub trait VerifyingKey<T>: Sizedwhere
+    T: Algorithm<VerifyingKey = Self>,{
+    // Required methods
+    fn from_slice(raw: &[u8]) -> Result<Self>;
+    fn as_bytes(&self) -> Cow<'_, [u8]>;
+}
Expand description

Verifying key for a specific signature cryptosystem. In the case of public-key cryptosystems, +this is a public key.

+

This trait provides a uniform interface for different backends / implementations +of the same cryptosystem.

+

Required Methods§

source

fn from_slice(raw: &[u8]) -> Result<Self>

Creates a key from raw bytes. Returns an error if the bytes do not represent +a valid key.

+
source

fn as_bytes(&self) -> Cow<'_, [u8]>

Returns the key as raw bytes.

+

Implementations should return Cow::Borrowed whenever possible (that is, if the bytes +are actually stored within the implementing data structure).

+

Implementations on Foreign Types§

source§

impl VerifyingKey<Ed25519> for PublicKey

source§

fn from_slice(raw: &[u8]) -> Result<Self>

source§

fn as_bytes(&self) -> Cow<'_, [u8]>

source§

impl VerifyingKey<Es256> for VerifyingKey

source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Serializes the key as a 33-byte compressed form.

+
source§

fn from_slice(raw: &[u8]) -> Result<Self>

Implementors§

\ No newline at end of file diff --git a/jwt_compact/all.html b/jwt_compact/all.html new file mode 100644 index 00000000..c16e5502 --- /dev/null +++ b/jwt_compact/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

\ No newline at end of file diff --git a/jwt_compact/claims/struct.Claims.html b/jwt_compact/claims/struct.Claims.html new file mode 100644 index 00000000..aef8a732 --- /dev/null +++ b/jwt_compact/claims/struct.Claims.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.Claims.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/claims/struct.Empty.html b/jwt_compact/claims/struct.Empty.html new file mode 100644 index 00000000..cf59a24c --- /dev/null +++ b/jwt_compact/claims/struct.Empty.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.Empty.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/claims/struct.TimeOptions.html b/jwt_compact/claims/struct.TimeOptions.html new file mode 100644 index 00000000..bd946457 --- /dev/null +++ b/jwt_compact/claims/struct.TimeOptions.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.TimeOptions.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/enum.Claim.html b/jwt_compact/enum.Claim.html new file mode 100644 index 00000000..087b8eac --- /dev/null +++ b/jwt_compact/enum.Claim.html @@ -0,0 +1,22 @@ +Claim in jwt_compact - Rust

Enum jwt_compact::Claim

source ·
#[non_exhaustive]
pub enum Claim { + Expiration, + NotBefore, +}
Expand description

Identifier of a claim in Claims.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Expiration

exp claim (expiration time).

+
§

NotBefore

nbf claim (valid not before).

+

Trait Implementations§

source§

impl Clone for Claim

source§

fn clone(&self) -> Claim

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Claim

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Claim

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<Claim> for Claim

source§

fn eq(&self, other: &Claim) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Claim

source§

impl StructuralEq for Claim

source§

impl StructuralPartialEq for Claim

Auto Trait Implementations§

§

impl RefUnwindSafe for Claim

§

impl Send for Claim

§

impl Sync for Claim

§

impl Unpin for Claim

§

impl UnwindSafe for Claim

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/enum.CreationError.html b/jwt_compact/enum.CreationError.html new file mode 100644 index 00000000..59de509c --- /dev/null +++ b/jwt_compact/enum.CreationError.html @@ -0,0 +1,21 @@ +CreationError in jwt_compact - Rust
#[non_exhaustive]
pub enum CreationError { + Header(Error), + Claims(Error), + CborClaims(Error<Infallible>), +}
Expand description

Errors that can occur during token creation.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Header(Error)

Token header cannot be serialized.

+
§

Claims(Error)

Token claims cannot be serialized into JSON.

+
§

CborClaims(Error<Infallible>)

Available on crate feature ciborium only.

Token claims cannot be serialized into CBOR.

+

Trait Implementations§

source§

impl Debug for CreationError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for CreationError

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for CreationError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/enum.ParseError.html b/jwt_compact/enum.ParseError.html new file mode 100644 index 00000000..e78a7121 --- /dev/null +++ b/jwt_compact/enum.ParseError.html @@ -0,0 +1,27 @@ +ParseError in jwt_compact - Rust
#[non_exhaustive]
pub enum ParseError { + InvalidTokenStructure, + InvalidBase64Encoding, + MalformedHeader(Error), + UnsupportedContentType(String), +}
Expand description

Errors that may occur during token parsing.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

InvalidTokenStructure

Token has invalid structure.

+

Valid tokens must consist of 3 base64url-encoded parts (header, claims, and signature) +separated by periods.

+
§

InvalidBase64Encoding

Cannot decode base64.

+
§

MalformedHeader(Error)

Token header cannot be parsed.

+
§

UnsupportedContentType(String)

Content type mentioned in the token header is not supported.

+

Supported content types are JSON (used by default) and CBOR (only if the ciborium +crate feature is enabled, which it is by default).

+

Trait Implementations§

source§

impl Debug for ParseError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ParseError

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ParseError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/enum.Thumbprint.html b/jwt_compact/enum.Thumbprint.html new file mode 100644 index 00000000..d8323dbb --- /dev/null +++ b/jwt_compact/enum.Thumbprint.html @@ -0,0 +1,51 @@ +Thumbprint in jwt_compact - Rust
#[non_exhaustive]
pub enum Thumbprint<const N: usize> { + Bytes([u8; N]), + String(String), +}
Expand description

Representation of a X.509 certificate thumbprint (x5t and x5t#S256 fields in +the JWT Header).

+

As per the JWS spec in RFC 7515, a certificate thumbprint (i.e., the SHA-1 / SHA-256 +digest of the certificate) must be base64url-encoded. Some JWS implementations however +encode not the thumbprint itself, but rather its hex encoding, sometimes even +with additional chars spliced within. To account for these implementations, +a thumbprint is represented as an enum – either a properly encoded hash digest, +or an opaque base64-encoded string.

+

Examples

+
let key = Hs256Key::new(b"super_secret_key_donut_steel");
+
+// Creates a token with a custom-encoded SHA-1 thumbprint.
+let thumbprint = "65:AF:69:09:B1:B0:75:8E:06:C6:E0:48:C4:60:02:B5:C6:95:E3:6B";
+let header = Header::empty()
+    .with_key_id("my_key")
+    .with_certificate_sha1_thumbprint(thumbprint);
+let token = Hs256.token(&header, &Claims::empty(), &key)?;
+println!("{token}");
+
+// Deserialize the token and check that its header fields are readable.
+let token = UntrustedToken::new(&token)?;
+let deserialized_thumbprint =
+    token.header().certificate_sha1_thumbprint.as_ref();
+assert_matches!(
+    deserialized_thumbprint,
+    Some(Thumbprint::String(s)) if s == thumbprint
+);
+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Bytes([u8; N])

Byte representation of a SHA-1 or SHA-256 digest.

+
§

String(String)

Opaque string representation of the thumbprint. It is the responsibility +of an application to verify that this value is valid.

+

Trait Implementations§

source§

impl<const N: usize> Clone for Thumbprint<N>

source§

fn clone(&self) -> Thumbprint<N>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<const N: usize> Debug for Thumbprint<N>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, const N: usize> Deserialize<'de> for Thumbprint<N>

source§

fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>

Deserialize this value from the given Serde deserializer. Read more
source§

impl<const N: usize> From<&str> for Thumbprint<N>

source§

fn from(s: &str) -> Self

Converts to this type from the input type.
source§

impl<const N: usize> From<[u8; N]> for Thumbprint<N>

source§

fn from(value: [u8; N]) -> Self

Converts to this type from the input type.
source§

impl<const N: usize> From<String> for Thumbprint<N>

source§

fn from(s: String) -> Self

Converts to this type from the input type.
source§

impl<const N: usize> Hash for Thumbprint<N>

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<const N: usize> PartialEq<Thumbprint<N>> for Thumbprint<N>

source§

fn eq(&self, other: &Thumbprint<N>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<const N: usize> Serialize for Thumbprint<N>

source§

fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>

Serialize this value into the given Serde serializer. Read more
source§

impl<const N: usize> Eq for Thumbprint<N>

source§

impl<const N: usize> StructuralEq for Thumbprint<N>

source§

impl<const N: usize> StructuralPartialEq for Thumbprint<N>

Auto Trait Implementations§

§

impl<const N: usize> RefUnwindSafe for Thumbprint<N>

§

impl<const N: usize> Send for Thumbprint<N>

§

impl<const N: usize> Sync for Thumbprint<N>

§

impl<const N: usize> Unpin for Thumbprint<N>

§

impl<const N: usize> UnwindSafe for Thumbprint<N>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/jwt_compact/enum.ValidationError.html b/jwt_compact/enum.ValidationError.html new file mode 100644 index 00000000..9b3899ae --- /dev/null +++ b/jwt_compact/enum.ValidationError.html @@ -0,0 +1,43 @@ +ValidationError in jwt_compact - Rust
#[non_exhaustive]
pub enum ValidationError { + AlgorithmMismatch { + expected: String, + actual: String, + }, + InvalidSignatureLen { + expected: usize, + actual: usize, + }, + MalformedSignature(Error), + InvalidSignature, + MalformedClaims(Error), + MalformedCborClaims(Error<Error>), + NoClaim(Claim), + Expired, + NotMature, +}
Expand description

Errors that can occur during token validation.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

AlgorithmMismatch

Fields

§expected: String

Expected algorithm name.

+
§actual: String

Actual algorithm in the token.

+

Algorithm mentioned in the token header differs from invoked one.

+
§

InvalidSignatureLen

Fields

§expected: usize

Expected signature length.

+
§actual: usize

Actual signature length.

+

Token signature has invalid byte length.

+
§

MalformedSignature(Error)

Token signature is malformed.

+
§

InvalidSignature

Token signature has failed verification.

+
§

MalformedClaims(Error)

Token claims cannot be deserialized from JSON.

+
§

MalformedCborClaims(Error<Error>)

Available on crate feature ciborium only.

Token claims cannot be deserialized from CBOR.

+
§

NoClaim(Claim)

Claim requested during validation is not present in the token.

+
§

Expired

Token has expired.

+
§

NotMature

Token is not yet valid as per nbf claim.

+

Trait Implementations§

source§

impl Debug for ValidationError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ValidationError

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ValidationError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/error/enum.Claim.html b/jwt_compact/error/enum.Claim.html new file mode 100644 index 00000000..6fa91ca7 --- /dev/null +++ b/jwt_compact/error/enum.Claim.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/enum.Claim.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/error/enum.CreationError.html b/jwt_compact/error/enum.CreationError.html new file mode 100644 index 00000000..5822c7e2 --- /dev/null +++ b/jwt_compact/error/enum.CreationError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/enum.CreationError.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/error/enum.ParseError.html b/jwt_compact/error/enum.ParseError.html new file mode 100644 index 00000000..b345b4ef --- /dev/null +++ b/jwt_compact/error/enum.ParseError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/enum.ParseError.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/error/enum.ValidationError.html b/jwt_compact/error/enum.ValidationError.html new file mode 100644 index 00000000..d663cde0 --- /dev/null +++ b/jwt_compact/error/enum.ValidationError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/enum.ValidationError.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/index.html b/jwt_compact/index.html new file mode 100644 index 00000000..13e0f3fc --- /dev/null +++ b/jwt_compact/index.html @@ -0,0 +1,172 @@ +jwt_compact - Rust

Crate jwt_compact

source ·
Expand description

Minimalistic JSON web token (JWT) implementation with focus on type safety +and secure cryptographic primitives.

+

Design choices

+
    +
  • JWT signature algorithms (i.e., cryptographic algorithms providing JWT integrity) +are expressed via the Algorithm trait, which uses fully typed keys and signatures.
  • +
  • JWT header is represented by the Header struct. Notably, Header does not +expose the alg field. +Instead, alg is filled automatically during token creation, and is compared to the +expected value during verification. (If you do not know the JWT signature algorithm during +verification, you’re doing something wrong.) This eliminates the possibility +of algorithm switching attacks.
  • +
+

Additional features

+
    +
  • The crate supports more compact CBOR encoding of the claims. This feature is enabled +via the ciborium feature.
  • +
  • The crate supports EdDSA algorithm with the Ed25519 elliptic curve, and ES256K algorithm +with the secp256k1 elliptic curve.
  • +
  • Supports basic JSON Web Key functionality, +e.g., for converting keys to / from JSON or computing +a key thumbprint.
  • +
+

Supported algorithms

+ + + + + + + + +
Algorithm(s)FeatureDescription
HS256, HS384, HS512-Uses pure Rust sha2 crate
EdDSA (Ed25519)exonum-cryptolibsodium binding
EdDSA (Ed25519)ed25519-dalekPure Rust implementation
EdDSA (Ed25519)ed25519-compactCompact pure Rust implementation, WASM-compatible
ES256Kes256kRust binding for libsecp256k1
ES256Kk256Pure Rust implementation
ES256p256Pure Rust implementation
RS*, PS* (RSA)rsaUses pure Rust rsa crate with blinding
+
+

Beware that the rsa crate (along with other RSA implementations) may be susceptible to +the “Marvin” timing side-channel attack +at the time of writing; use with caution.

+

EdDSA and ES256K algorithms are somewhat less frequently supported by JWT implementations +than others since they are recent additions to the JSON Web Algorithms (JWA) suit. +They both work with elliptic curves +(Curve25519 and secp256k1; both are widely used in crypto community and believed to be +securely generated). These algs have 128-bit security, making them an alternative +to ES256.

+

RSA support requires a system-wide RNG retrieved via the getrandom crate. +In case of a compilation failure in the getrandom crate, you may want +to include it as a direct dependency and specify one of its features +to assist getrandom with choosing an appropriate RNG implementation; consult getrandom docs +for more details. See also WASM and bare-metal E2E tests included +in the source code repository of this crate.

+

CBOR support

+

If the ciborium crate feature is enabled (and it is enabled by default), token claims can +be encoded using CBOR with the AlgorithmExt::compact_token() method. +The compactly encoded JWTs have the cty field (content type) in their header +set to "CBOR". Tokens with such encoding can be verified in the same way as ordinary tokens; +see examples below.

+

If the ciborium feature is disabled, AlgorithmExt::compact_token() is not available. +Verifying CBOR-encoded tokens in this case is not supported either; +a ParseError::UnsupportedContentType will be returned when creating an UntrustedToken +from the token string.

+

no_std support

+

The crate supports a no_std compilation mode. This is controlled by two features: +clock and std; both are on by default.

+
    +
  • The clock feature enables getting the current time using Utc::now() from chrono. +Without it, some TimeOptions constructors, such as the Default impl, +are not available. It is still possible to create TimeOptions with an explicitly specified +clock function, or to set / verify time-related Claims fields manually.
  • +
  • The std feature is propagated to the core dependencies and enables std-specific +functionality (such as error types implementing the standard Error trait).
  • +
+

Some alloc types are still used in the no_std mode, such as String, Vec and Cow.

+

Note that not all crypto backends are no_std-compatible.

+

Examples

+

Basic JWT lifecycle:

+ +
use chrono::{Duration, Utc};
+use jwt_compact::{prelude::*, alg::{Hs256, Hs256Key}};
+use serde::{Serialize, Deserialize};
+
+/// Custom claims encoded in the token.
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+struct CustomClaims {
+    /// `sub` is a standard claim which denotes claim subject:
+    /// https://tools.ietf.org/html/rfc7519#section-4.1.2
+    #[serde(rename = "sub")]
+    subject: String,
+}
+
+// Choose time-related options for token creation / validation.
+let time_options = TimeOptions::default();
+// Create a symmetric HMAC key, which will be used both to create and verify tokens.
+let key = Hs256Key::new(b"super_secret_key_donut_steel");
+// Create a token.
+let header = Header::empty().with_key_id("my-key");
+let claims = Claims::new(CustomClaims { subject: "alice".to_owned() })
+    .set_duration_and_issuance(&time_options, Duration::days(7))
+    .set_not_before(Utc::now() - Duration::hours(1));
+let token_string = Hs256.token(&header, &claims, &key)?;
+println!("token: {token_string}");
+
+// Parse the token.
+let token = UntrustedToken::new(&token_string)?;
+// Before verifying the token, we might find the key which has signed the token
+// using the `Header.key_id` field.
+assert_eq!(token.header().key_id, Some("my-key".to_owned()));
+// Validate the token integrity.
+let token: Token<CustomClaims> = Hs256.validator(&key).validate(&token)?;
+// Validate additional conditions.
+token.claims()
+    .validate_expiration(&time_options)?
+    .validate_maturity(&time_options)?;
+// Now, we can extract information from the token (e.g., its subject).
+let subject = &token.claims().custom.subject;
+assert_eq!(subject, "alice");
+

Compact JWT

+
/// Custom claims encoded in the token.
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+struct CustomClaims {
+    /// `sub` is a standard claim which denotes claim subject:
+    ///     https://tools.ietf.org/html/rfc7519#section-4.1.2
+    /// The custom serializer we use allows to efficiently
+    /// encode the subject in CBOR.
+    #[serde(rename = "sub", with = "HexForm")]
+    subject: [u8; 32],
+}
+
+let time_options = TimeOptions::default();
+let key = Hs256Key::new(b"super_secret_key_donut_steel");
+let claims = Claims::new(CustomClaims { subject: [111; 32] })
+    .set_duration_and_issuance(&time_options, Duration::days(7));
+let token = Hs256.token(&Header::empty(), &claims, &key)?;
+println!("token: {token}");
+let compact_token = Hs256.compact_token(&Header::empty(), &claims, &key)?;
+println!("compact token: {compact_token}");
+// The compact token should be ~40 chars shorter.
+
+// Parse the compact token.
+let token = UntrustedToken::new(&compact_token)?;
+let token: Token<CustomClaims> = Hs256.validator(&key).validate(&token)?;
+token.claims().validate_expiration(&time_options)?;
+// Now, we can extract information from the token (e.g., its subject).
+assert_eq!(token.claims().custom.subject, [111; 32]);
+

JWT with custom header fields

+
#[derive(Debug, PartialEq, Serialize, Deserialize)]
+struct CustomClaims { subject: [u8; 32] }
+
+/// Additional fields in the token header.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+struct HeaderExtensions { custom: bool }
+
+let time_options = TimeOptions::default();
+let key = Hs256Key::new(b"super_secret_key_donut_steel");
+let claims = Claims::new(CustomClaims { subject: [111; 32] })
+    .set_duration_and_issuance(&time_options, Duration::days(7));
+let header = Header::new(HeaderExtensions { custom: true })
+    .with_key_id("my-key");
+let token = Hs256.token(&header, &claims, &key)?;
+print!("token: {token}");
+
+// Parse the token.
+let token: UntrustedToken<HeaderExtensions> =
+    token.as_str().try_into()?;
+// Token header (incl. custom fields) can be accessed right away.
+assert_eq!(token.header().key_id.as_deref(), Some("my-key"));
+assert!(token.header().other_fields.custom);
+// Token can then be validated as usual.
+let token = Hs256.validator::<CustomClaims>(&key).validate(&token)?;
+assert_eq!(token.claims().custom.subject, [111; 32]);
+

Modules

  • Implementations of JWT signing / verification algorithms. Also contains generic traits +for signing and verifying keys.
  • Basic support of JSON Web Keys (JWK).
  • Prelude to neatly import all necessary stuff from the crate.

Structs

  • Claims encoded in a token.
  • A structure with no fields that can be used as a type parameter to Claims.
  • JWT header.
  • Algorithm that uses a custom name when creating and validating tokens.
  • Token together with the validated token signature.
  • Time-related options for token creation and validation.
  • Token with validated integrity.
  • Parsed, but unvalidated token.
  • Validator for a certain signing Algorithm associated with a specific verifying key +and a claims type. Produced by the AlgorithmExt::validator() method.

Enums

  • Identifier of a claim in Claims.
  • Errors that can occur during token creation.
  • Errors that may occur during token parsing.
  • Representation of a X.509 certificate thumbprint (x5t and x5t#S256 fields in +the JWT Header).
  • Errors that can occur during token validation.

Traits

\ No newline at end of file diff --git a/jwt_compact/jwk/enum.JsonWebKey.html b/jwt_compact/jwk/enum.JsonWebKey.html new file mode 100644 index 00000000..8b2d59ab --- /dev/null +++ b/jwt_compact/jwk/enum.JsonWebKey.html @@ -0,0 +1,91 @@ +JsonWebKey in jwt_compact::jwk - Rust
#[non_exhaustive]
pub enum JsonWebKey<'a> { + Rsa { + modulus: Cow<'a, [u8]>, + public_exponent: Cow<'a, [u8]>, + private_parts: Option<RsaPrivateParts<'a>>, + }, + EllipticCurve { + curve: Cow<'a, str>, + x: Cow<'a, [u8]>, + y: Cow<'a, [u8]>, + secret: Option<SecretBytes<'a>>, + }, + Symmetric { + secret: SecretBytes<'a>, + }, + KeyPair { + curve: Cow<'a, str>, + x: Cow<'a, [u8]>, + secret: Option<SecretBytes<'a>>, + }, +}
Expand description

Basic JWK functionality: (de)serialization and creating thumbprints.

+

See RFC 7518 for the details about the fields for various key types.

+

Self::thumbprint() and the Display implementation +allow to get the overall presentation of the key. The latter returns JSON serialization +of the key with fields ordered alphabetically. That is, this output for verifying keys +can be used to compute key thumbprints.

+

Serialization

+

For human-readable formats (e.g., JSON, TOML, YAML), byte fields in JsonWebKey +and embedded types (SecretBytes, RsaPrivateParts, RsaPrimeFactor) will be +serialized in base64-url encoding with no padding, as per the JWK spec. +For other formats (e.g., CBOR), byte fields will be serialized as byte sequences.

+

Because of the limitations +of the CBOR support in serde, a JsonWebKey serialized in CBOR is not compliant +with the CBOR Object Signing and Encryption spec (COSE). It can still be a good +way to decrease the serialized key size.

+

Conversions

+

A JWK can be obtained from signing and verifying keys defined in the alg +module via From / Into traits. Conversion from a JWK to a specific key is fallible +and can be performed via TryFrom with JwkError as an error +type.

+

As a part of conversion for asymmetric signing keys, it is checked whether +the signing and verifying parts of the JWK match; JwkError::MismatchedKeys is returned +otherwise. This check is not performed for verifying keys even if the necessary data +is present in the provided JWK.

+

Warning. Conversions for private RSA keys are not fully compliant with RFC 7518. +See the docs for the relevant impls for more details.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Rsa

Fields

§modulus: Cow<'a, [u8]>

Key modulus (n).

+
§public_exponent: Cow<'a, [u8]>

Public exponent (e).

+
§private_parts: Option<RsaPrivateParts<'a>>

Private RSA parameters. Only present for private keys.

+

Public or private RSA key. Has kty field set to RSA.

+
§

EllipticCurve

Fields

§curve: Cow<'a, str>

Curve name (crv), such as secp256k1.

+
§x: Cow<'a, [u8]>

x coordinate of the curve point.

+
§y: Cow<'a, [u8]>

y coordinate of the curve point.

+
§secret: Option<SecretBytes<'a>>

Secret scalar (d); not present for public keys.

+

Public or private key in an ECDSA crypto system. Has kty field set to EC.

+
§

Symmetric

Fields

§secret: SecretBytes<'a>

Bytes representing this key.

+

Generic symmetric key, e.g. for HS256 algorithm. Has kty field set to oct.

+
§

KeyPair

Fields

§curve: Cow<'a, str>

Curve name (crv), such as Ed25519.

+
§x: Cow<'a, [u8]>

Public key. For Ed25519, this is the standard 32-byte public key presentation +(x coordinate of a point on the curve + sign).

+
§secret: Option<SecretBytes<'a>>

Secret key (d). For Ed25519, this is the seed.

+

Generic asymmetric keypair. This key type is used e.g. for Ed25519 keys.

+

Implementations§

source§

impl JsonWebKey<'_>

source

pub fn key_type(&self) -> KeyType

Gets the type of this key.

+
source

pub fn is_signing_key(&self) -> bool

Returns true if this key can be used for signing (has SecretBytes fields).

+
source

pub fn to_verifying_key(&self) -> Self

Returns a copy of this key with parts not necessary for signature verification removed.

+
source

pub fn thumbprint<D: Digest>(&self) -> Output<D>

Computes a thumbprint of this JWK. The result complies with the key thumbprint defined +in RFC 7638.

+

Trait Implementations§

source§

impl<'a> Clone for JsonWebKey<'a>

source§

fn clone(&self) -> JsonWebKey<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for JsonWebKey<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, 'a> Deserialize<'de> for JsonWebKey<'a>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Display for JsonWebKey<'_>

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a Hs256Key> for JsonWebKey<'a>

source§

fn from(key: &'a Hs256Key) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a Hs384Key> for JsonWebKey<'a>

source§

fn from(key: &'a Hs384Key) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a Hs512Key> for JsonWebKey<'a>

source§

fn from(key: &'a Hs512Key) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a PublicKey> for JsonWebKey<'a>

source§

fn from(key: &'a PublicKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a PublicKey> for JsonWebKey<'a>

source§

fn from(key: &'a PublicKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a RsaPrivateKey> for JsonWebKey<'a>

Warning. Contrary to RFC 7518, this implementation does not set dp, dq, and qi +fields in the JWK root object, as well as d and t fields for additional factors +(i.e., in the oth array).

+
source§

fn from(key: &'a RsaPrivateKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a RsaPublicKey> for JsonWebKey<'a>

source§

fn from(key: &'a RsaPublicKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a SecretKey> for JsonWebKey<'a>

source§

fn from(key: &'a SecretKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a SecretKey> for JsonWebKey<'a>

source§

fn from(key: &'a SecretKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a SigningKey<NistP256>> for JsonWebKey<'a>

source§

fn from(key: &'a SigningKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> From<&'a VerifyingKey<NistP256>> for JsonWebKey<'a>

source§

fn from(key: &'a VerifyingKey) -> JsonWebKey<'a>

Converts to this type from the input type.
source§

impl<'a> PartialEq<JsonWebKey<'a>> for JsonWebKey<'a>

source§

fn eq(&self, other: &JsonWebKey<'a>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> Serialize for JsonWebKey<'a>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl TryFrom<&JsonWebKey<'_>> for Hs256Key

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for Hs384Key

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for Hs512Key

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for PublicKey

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for PublicKey

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for RsaPrivateKey

Warning. Contrary to RFC 7518 (at least, in spirit), this conversion ignores +dp, dq, and qi fields from JWK, as well as d and t fields for additional factors.

+
§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for RsaPublicKey

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for SecretKey

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for SecretKey

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for SigningKey

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&JsonWebKey<'_>> for VerifyingKey

§

type Error = JwkError

The type returned in the event of a conversion error.
source§

fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl<'a> StructuralPartialEq for JsonWebKey<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for JsonWebKey<'a>

§

impl<'a> Send for JsonWebKey<'a>

§

impl<'a> Sync for JsonWebKey<'a>

§

impl<'a> Unpin for JsonWebKey<'a>

§

impl<'a> UnwindSafe for JsonWebKey<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/jwt_compact/jwk/enum.JwkError.html b/jwt_compact/jwk/enum.JwkError.html new file mode 100644 index 00000000..812bd9cd --- /dev/null +++ b/jwt_compact/jwk/enum.JwkError.html @@ -0,0 +1,48 @@ +JwkError in jwt_compact::jwk - Rust
#[non_exhaustive]
pub enum JwkError { + NoField(String), + UnexpectedKeyType { + expected: KeyType, + actual: KeyType, + }, + UnexpectedValue { + field: String, + expected: String, + actual: String, + }, + UnexpectedLen { + field: String, + expected: usize, + actual: usize, + }, + MismatchedKeys, + Custom(Error), +}
Expand description

Errors that can occur when transforming a JsonWebKey into the presentation specific for +a crypto backend, using the TryFrom trait.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

NoField(String)

Required field is absent from JWK.

+
§

UnexpectedKeyType

Fields

§expected: KeyType

Expected key type.

+
§actual: KeyType

Actual key type.

+

Key type (the kty field) is not as expected.

+
§

UnexpectedValue

Fields

§field: String

Field name.

+
§expected: String

Expected value of the field.

+
§actual: String

Actual value of the field.

+

JWK field has an unexpected value.

+
§

UnexpectedLen

Fields

§field: String

Field name.

+
§expected: usize

Expected byte length of the field.

+
§actual: usize

Actual byte length of the field.

+

JWK field has an unexpected byte length.

+
§

MismatchedKeys

Signing and verifying keys do not match.

+
§

Custom(Error)

Custom error specific to a crypto backend.

+

Implementations§

source§

impl JwkError

source

pub fn custom(err: impl Into<Error>) -> Self

Creates a Custom error variant.

+

Trait Implementations§

source§

impl Debug for JwkError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for JwkError

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for JwkError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/jwk/enum.KeyType.html b/jwt_compact/jwk/enum.KeyType.html new file mode 100644 index 00000000..93e32275 --- /dev/null +++ b/jwt_compact/jwk/enum.KeyType.html @@ -0,0 +1,29 @@ +KeyType in jwt_compact::jwk - Rust

Enum jwt_compact::jwk::KeyType

source ·
#[non_exhaustive]
pub enum KeyType { + Rsa, + EllipticCurve, + Symmetric, + KeyPair, +}
Expand description

Type of a JsonWebKey.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Rsa

Public or private RSA key. Corresponds to the RSA value of the kty field for JWKs.

+
§

EllipticCurve

Public or private key in an ECDSA crypto system. Corresponds to the EC value +of the kty field for JWKs.

+
§

Symmetric

Symmetric key. Corresponds to the oct value of the kty field for JWKs.

+
§

KeyPair

Generic asymmetric keypair. Corresponds to the OKP value of the kty field for JWKs.

+

Trait Implementations§

source§

impl Clone for KeyType

source§

fn clone(&self) -> KeyType

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for KeyType

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for KeyType

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Hash for KeyType

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<KeyType> for KeyType

source§

fn eq(&self, other: &KeyType) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for KeyType

source§

impl Eq for KeyType

source§

impl StructuralEq for KeyType

source§

impl StructuralPartialEq for KeyType

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/jwk/index.html b/jwt_compact/jwk/index.html new file mode 100644 index 00000000..f11db2f8 --- /dev/null +++ b/jwt_compact/jwk/index.html @@ -0,0 +1,25 @@ +jwt_compact::jwk - Rust

Module jwt_compact::jwk

source ·
Expand description

Basic support of JSON Web Keys (JWK).

+

The functionality defined in this module allows converting between +the generic JWK format and key presentation specific for the crypto backend. +JsonWebKeys can be (de)serialized using serde infrastructure, and can be used +to compute key thumbprint as per RFC 7638.

+

Examples

+
use jwt_compact::{alg::Hs256Key, jwk::JsonWebKey};
+use sha2::Sha256;
+
+// Load a key from the JWK presentation.
+let json_str = r#"
+    { "kty": "oct", "k": "t-bdv41MJXExXnpquHBuDn7n1YGyX7gLQchVHAoNu50" }
+"#;
+let jwk: JsonWebKey<'_> = serde_json::from_str(json_str)?;
+let key = Hs256Key::try_from(&jwk)?;
+
+// Convert `key` back to JWK.
+let jwk_from_key = JsonWebKey::from(&key);
+assert_eq!(jwk_from_key, jwk);
+println!("{}", serde_json::to_string(&jwk)?);
+
+// Compute the key thumbprint.
+let thumbprint = jwk_from_key.thumbprint::<Sha256>();
+

Structs

Enums

\ No newline at end of file diff --git a/jwt_compact/jwk/sidebar-items.js b/jwt_compact/jwk/sidebar-items.js new file mode 100644 index 00000000..9c1aeee0 --- /dev/null +++ b/jwt_compact/jwk/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["JsonWebKey","JwkError","KeyType"],"struct":["RsaPrimeFactor","RsaPrivateParts"]}; \ No newline at end of file diff --git a/jwt_compact/jwk/struct.RsaPrimeFactor.html b/jwt_compact/jwk/struct.RsaPrimeFactor.html new file mode 100644 index 00000000..372aac37 --- /dev/null +++ b/jwt_compact/jwk/struct.RsaPrimeFactor.html @@ -0,0 +1,30 @@ +RsaPrimeFactor in jwt_compact::jwk - Rust
pub struct RsaPrimeFactor<'a> {
+    pub factor: SecretBytes<'a>,
+    pub crt_exponent: Option<SecretBytes<'a>>,
+    pub crt_coefficient: Option<SecretBytes<'a>>,
+}
Expand description

Block for an additional prime factor in RsaPrivateParts.

+

Serialization

+

Fields of this struct are serialized using the big endian presentation +with the minimum necessary number of bytes. See JsonWebKey notes +on encoding.

+

Fields§

§factor: SecretBytes<'a>

Prime factor (r).

+
§crt_exponent: Option<SecretBytes<'a>>

Factor CRT exponent (d).

+
§crt_coefficient: Option<SecretBytes<'a>>

Factor CRT coefficient (t).

+

Trait Implementations§

source§

impl<'a> Clone for RsaPrimeFactor<'a>

source§

fn clone(&self) -> RsaPrimeFactor<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for RsaPrimeFactor<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, 'a> Deserialize<'de> for RsaPrimeFactor<'a>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<'a> PartialEq<RsaPrimeFactor<'a>> for RsaPrimeFactor<'a>

source§

fn eq(&self, other: &RsaPrimeFactor<'a>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> Serialize for RsaPrimeFactor<'a>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<'a> StructuralPartialEq for RsaPrimeFactor<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for RsaPrimeFactor<'a>

§

impl<'a> Send for RsaPrimeFactor<'a>

§

impl<'a> Sync for RsaPrimeFactor<'a>

§

impl<'a> Unpin for RsaPrimeFactor<'a>

§

impl<'a> UnwindSafe for RsaPrimeFactor<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/jwt_compact/jwk/struct.RsaPrivateParts.html b/jwt_compact/jwk/struct.RsaPrivateParts.html new file mode 100644 index 00000000..f677f516 --- /dev/null +++ b/jwt_compact/jwk/struct.RsaPrivateParts.html @@ -0,0 +1,38 @@ +RsaPrivateParts in jwt_compact::jwk - Rust
pub struct RsaPrivateParts<'a> {
+    pub private_exponent: SecretBytes<'a>,
+    pub prime_factor_p: SecretBytes<'a>,
+    pub prime_factor_q: SecretBytes<'a>,
+    pub p_crt_exponent: Option<SecretBytes<'a>>,
+    pub q_crt_exponent: Option<SecretBytes<'a>>,
+    pub q_crt_coefficient: Option<SecretBytes<'a>>,
+    pub other_prime_factors: Vec<RsaPrimeFactor<'a>>,
+}
Expand description

Parts of JsonWebKey::Rsa that are specific to private keys.

+

Serialization

+

Fields of this struct are serialized using the big endian presentation +with the minimum necessary number of bytes. See JsonWebKey notes +on encoding.

+

Fields§

§private_exponent: SecretBytes<'a>

Private exponent (d).

+
§prime_factor_p: SecretBytes<'a>

First prime factor (p).

+
§prime_factor_q: SecretBytes<'a>

Second prime factor (q).

+
§p_crt_exponent: Option<SecretBytes<'a>>

First factor CRT exponent (dp).

+
§q_crt_exponent: Option<SecretBytes<'a>>

Second factor CRT exponent (dq).

+
§q_crt_coefficient: Option<SecretBytes<'a>>

CRT coefficient of the second factor (qi).

+
§other_prime_factors: Vec<RsaPrimeFactor<'a>>

Other prime factors.

+

Trait Implementations§

source§

impl<'a> Clone for RsaPrivateParts<'a>

source§

fn clone(&self) -> RsaPrivateParts<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for RsaPrivateParts<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, 'a> Deserialize<'de> for RsaPrivateParts<'a>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<'a> PartialEq<RsaPrivateParts<'a>> for RsaPrivateParts<'a>

source§

fn eq(&self, other: &RsaPrivateParts<'a>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> Serialize for RsaPrivateParts<'a>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<'a> StructuralPartialEq for RsaPrivateParts<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for RsaPrivateParts<'a>

§

impl<'a> Send for RsaPrivateParts<'a>

§

impl<'a> Sync for RsaPrivateParts<'a>

§

impl<'a> Unpin for RsaPrivateParts<'a>

§

impl<'a> UnwindSafe for RsaPrivateParts<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/jwt_compact/prelude/index.html b/jwt_compact/prelude/index.html new file mode 100644 index 00000000..1d19cbee --- /dev/null +++ b/jwt_compact/prelude/index.html @@ -0,0 +1,2 @@ +jwt_compact::prelude - Rust

Module jwt_compact::prelude

source ·
Expand description

Prelude to neatly import all necessary stuff from the crate.

+

Re-exports

\ No newline at end of file diff --git a/jwt_compact/prelude/sidebar-items.js b/jwt_compact/prelude/sidebar-items.js new file mode 100644 index 00000000..5244ce01 --- /dev/null +++ b/jwt_compact/prelude/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {}; \ No newline at end of file diff --git a/jwt_compact/sidebar-items.js b/jwt_compact/sidebar-items.js new file mode 100644 index 00000000..7116727c --- /dev/null +++ b/jwt_compact/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Claim","CreationError","ParseError","Thumbprint","ValidationError"],"mod":["alg","jwk","prelude"],"struct":["Claims","Empty","Header","Renamed","SignedToken","TimeOptions","Token","UntrustedToken","Validator"],"trait":["Algorithm","AlgorithmExt","AlgorithmSignature"]}; \ No newline at end of file diff --git a/jwt_compact/struct.Claims.html b/jwt_compact/struct.Claims.html new file mode 100644 index 00000000..b053156b --- /dev/null +++ b/jwt_compact/struct.Claims.html @@ -0,0 +1,69 @@ +Claims in jwt_compact - Rust

Struct jwt_compact::Claims

source ·
#[non_exhaustive]
pub struct Claims<T> { + pub expiration: Option<DateTime<Utc>>, + pub not_before: Option<DateTime<Utc>>, + pub issued_at: Option<DateTime<Utc>>, + pub custom: T, +}
Expand description

Claims encoded in a token.

+

Claims are comprised of a “standard” part (exp, nbf and iat claims as per JWT spec), +and custom fields. iss, sub and aud claims are not in the standard part +due to a variety of data types they can be reasonably represented by.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§expiration: Option<DateTime<Utc>>

Expiration time of the token.

+
§not_before: Option<DateTime<Utc>>

Minimum time at which token is valid.

+
§issued_at: Option<DateTime<Utc>>

Time of token issuance.

+
§custom: T

Custom claims.

+

Implementations§

source§

impl Claims<Empty>

source

pub fn empty() -> Self

Creates an empty claims instance.

+
source§

impl<T> Claims<T>

source

pub fn new(custom_claims: T) -> Self

Creates a new instance with the provided custom claims.

+
source

pub fn set_duration<F>( + self, + options: &TimeOptions<F>, + duration: Duration +) -> Selfwhere + F: Fn() -> DateTime<Utc>,

Sets the expiration claim so that the token has the specified duration. +The current timestamp is taken from options.

+
source

pub fn set_duration_and_issuance<F>( + self, + options: &TimeOptions<F>, + duration: Duration +) -> Selfwhere + F: Fn() -> DateTime<Utc>,

Atomically sets issued_at and expiration claims: first to the current time +(taken from options), and the second to match the specified duration of the token.

+
source

pub fn set_not_before(self, moment: DateTime<Utc>) -> Self

Sets the nbf claim.

+
source

pub fn validate_expiration<F>( + &self, + options: &TimeOptions<F> +) -> Result<&Self, ValidationError>where + F: Fn() -> DateTime<Utc>,

Validates the expiration claim.

+

This method will return an error if the claims do not feature an expiration time, +or if it is in the past (subject to the provided options).

+
source

pub fn validate_maturity<F>( + &self, + options: &TimeOptions<F> +) -> Result<&Self, ValidationError>where + F: Fn() -> DateTime<Utc>,

Validates the maturity time (nbf claim).

+

This method will return an error if the claims do not feature a maturity time, +or if it is in the future (subject to the provided options).

+

Trait Implementations§

source§

impl<T: Clone> Clone for Claims<T>

source§

fn clone(&self) -> Claims<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Claims<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, T> Deserialize<'de> for Claims<T>where + T: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<T: PartialEq> PartialEq<Claims<T>> for Claims<T>

source§

fn eq(&self, other: &Claims<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T> Serialize for Claims<T>where + T: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<T: Eq> Eq for Claims<T>

source§

impl<T> StructuralEq for Claims<T>

source§

impl<T> StructuralPartialEq for Claims<T>

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for Claims<T>where + T: RefUnwindSafe,

§

impl<T> Send for Claims<T>where + T: Send,

§

impl<T> Sync for Claims<T>where + T: Sync,

§

impl<T> Unpin for Claims<T>where + T: Unpin,

§

impl<T> UnwindSafe for Claims<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/jwt_compact/struct.Empty.html b/jwt_compact/struct.Empty.html new file mode 100644 index 00000000..7f63454a --- /dev/null +++ b/jwt_compact/struct.Empty.html @@ -0,0 +1,21 @@ +Empty in jwt_compact - Rust

Struct jwt_compact::Empty

source ·
pub struct Empty {}
Expand description

A structure with no fields that can be used as a type parameter to Claims.

+

Trait Implementations§

source§

impl Clone for Empty

source§

fn clone(&self) -> Empty

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Empty

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Empty

source§

fn default() -> Empty

Returns the “default value” for a type. Read more
source§

impl<'de> Deserialize<'de> for Empty

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Hash for Empty

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Empty> for Empty

source§

fn eq(&self, other: &Empty) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Serialize for Empty

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Copy for Empty

source§

impl Eq for Empty

source§

impl StructuralEq for Empty

source§

impl StructuralPartialEq for Empty

Auto Trait Implementations§

§

impl RefUnwindSafe for Empty

§

impl Send for Empty

§

impl Sync for Empty

§

impl Unpin for Empty

§

impl UnwindSafe for Empty

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/jwt_compact/struct.Header.html b/jwt_compact/struct.Header.html new file mode 100644 index 00000000..deec9abb --- /dev/null +++ b/jwt_compact/struct.Header.html @@ -0,0 +1,81 @@ +Header in jwt_compact - Rust

Struct jwt_compact::Header

source ·
#[non_exhaustive]
pub struct Header<T = Empty> { + pub key_set_url: Option<String>, + pub key_id: Option<String>, + pub certificate_url: Option<String>, + pub certificate_sha1_thumbprint: Option<Thumbprint<20>>, + pub certificate_thumbprint: Option<Thumbprint<32>>, + pub token_type: Option<String>, + pub other_fields: T, +}
Expand description

JWT header.

+

See RFC 7515 for the description +of the fields. The purpose of all fields except token_type is to determine +the verifying key. Since these values will be provided by the adversary in the case of +an attack, they require additional verification (e.g., a provided certificate might +be checked against the list of “acceptable” certificate authorities).

+

A Header can be created using Default implementation, which does not set any fields. +For added fluency, you may use with_* methods:

+ +
use sha2::{digest::Digest, Sha256};
+
+let my_key_cert = // DER-encoded key certificate
+let thumbprint: [u8; 32] = Sha256::digest(my_key_cert).into();
+let header = Header::empty()
+    .with_key_id("my-key-id")
+    .with_certificate_thumbprint(thumbprint);
+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§key_set_url: Option<String>

URL of the JSON Web Key Set containing the key that has signed the token. +This field is renamed to jku for serialization.

+
§key_id: Option<String>

Identifier of the key that has signed the token. This field is renamed to kid +for serialization.

+
§certificate_url: Option<String>

URL of the X.509 certificate for the signing key. This field is renamed to x5u +for serialization.

+
§certificate_sha1_thumbprint: Option<Thumbprint<20>>

SHA-1 thumbprint of the X.509 certificate for the signing key. +This field is renamed to x5t for serialization.

+
§certificate_thumbprint: Option<Thumbprint<32>>

SHA-256 thumbprint of the X.509 certificate for the signing key. +This field is renamed to x5t#S256 for serialization.

+
§token_type: Option<String>

Application-specific token type. This field is renamed to typ for serialization.

+
§other_fields: T

Other fields encoded in the header. These fields may be used by agreement between +the producer and consumer of the token to pass additional information. +See Sections 4.2 and 4.3 of RFC 7515 +for details.

+

For the token creation and validation to work properly, the fields type must Serialize +to a JSON object.

+

Note that these fields do not include the signing algorithm (alg) and the token +content type (cty) since both these fields have predefined semantics and are used +internally by the crate logic.

+

Implementations§

source§

impl Header

source

pub const fn empty() -> Self

Creates an empty header.

+
source§

impl<T> Header<T>

source

pub const fn new(fields: T) -> Header<T>

Creates a header with the specified custom fields.

+
source

pub fn with_key_set_url(self, key_set_url: impl Into<String>) -> Self

Sets the key_set_url field for this header.

+
source

pub fn with_key_id(self, key_id: impl Into<String>) -> Self

Sets the key_id field for this header.

+
source

pub fn with_certificate_url(self, certificate_url: impl Into<String>) -> Self

Sets the certificate_url field for this header.

+
source

pub fn with_certificate_sha1_thumbprint( + self, + certificate_thumbprint: impl Into<Thumbprint<20>> +) -> Self

Sets the certificate_sha1_thumbprint field for this header.

+
source

pub fn with_certificate_thumbprint( + self, + certificate_thumbprint: impl Into<Thumbprint<32>> +) -> Self

Sets the certificate_thumbprint field for this header.

+
source

pub fn with_token_type(self, token_type: impl Into<String>) -> Self

Sets the token_type field for this header.

+

Trait Implementations§

source§

impl<T: Clone> Clone for Header<T>

source§

fn clone(&self) -> Header<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Header<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Default> Default for Header<T>

source§

fn default() -> Header<T>

Returns the “default value” for a type. Read more
source§

impl<'de, T> Deserialize<'de> for Header<T>where + T: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<T> Serialize for Header<T>where + T: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for Header<T>where + T: RefUnwindSafe,

§

impl<T> Send for Header<T>where + T: Send,

§

impl<T> Sync for Header<T>where + T: Sync,

§

impl<T> Unpin for Header<T>where + T: Unpin,

§

impl<T> UnwindSafe for Header<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/jwt_compact/struct.Renamed.html b/jwt_compact/struct.Renamed.html new file mode 100644 index 00000000..3669ccaa --- /dev/null +++ b/jwt_compact/struct.Renamed.html @@ -0,0 +1,72 @@ +Renamed in jwt_compact - Rust

Struct jwt_compact::Renamed

source ·
pub struct Renamed<A> { /* private fields */ }
Expand description

Algorithm that uses a custom name when creating and validating tokens.

+

Examples

+
use jwt_compact::{alg::{Hs256, Hs256Key}, prelude::*, Empty, Renamed};
+
+let alg = Renamed::new(Hs256, "HS2");
+let key = Hs256Key::new(b"super_secret_key_donut_steel");
+let token_string = alg.token(&Header::empty(), &Claims::empty(), &key)?;
+
+let token = UntrustedToken::new(&token_string)?;
+assert_eq!(token.algorithm(), "HS2");
+// Note that the created token cannot be verified against the original algorithm
+// since the algorithm name recorded in the token header doesn't match.
+assert!(Hs256.validator::<Empty>(&key).validate(&token).is_err());
+
+// ...but the modified alg is working as expected.
+assert!(alg.validator::<Empty>(&key).validate(&token).is_ok());
+

Implementations§

source§

impl<A: Algorithm> Renamed<A>

source

pub fn new(algorithm: A, new_name: &'static str) -> Self

Creates a renamed algorithm.

+

Trait Implementations§

source§

impl<A: Algorithm> Algorithm for Renamed<A>

§

type SigningKey = <A as Algorithm>::SigningKey

Key used when issuing new tokens.
§

type VerifyingKey = <A as Algorithm>::VerifyingKey

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).
§

type Signature = <A as Algorithm>::Signature

Signature produced by the algorithm.
source§

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.
source§

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.
source§

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.
source§

impl<A: Clone> Clone for Renamed<A>

source§

fn clone(&self) -> Renamed<A>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<A: Debug> Debug for Renamed<A>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<A: Copy> Copy for Renamed<A>

Auto Trait Implementations§

§

impl<A> RefUnwindSafe for Renamed<A>where + A: RefUnwindSafe,

§

impl<A> Send for Renamed<A>where + A: Send,

§

impl<A> Sync for Renamed<A>where + A: Sync,

§

impl<A> Unpin for Renamed<A>where + A: Unpin,

§

impl<A> UnwindSafe for Renamed<A>where + A: UnwindSafe,

Blanket Implementations§

source§

impl<A> AlgorithmExt for Awhere + A: Algorithm,

source§

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.
source§

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &<A as Algorithm>::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.
Creates a new token with CBOR-encoded claims and serializes it to string.
source§

fn validator<T, 'a>( + &'a self, + verifying_key: &'a <A as Algorithm>::VerifyingKey +) -> Validator<'a, A, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.
source§

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<Token<T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility
Validates the token integrity against the provided verifying_key.
source§

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_, Empty>, + verifying_key: &<A as Algorithm>::VerifyingKey +) -> Result<SignedToken<A, T, Empty>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility
Validates the token integrity against the provided verifying_key. Read more
source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/struct.SignedToken.html b/jwt_compact/struct.SignedToken.html new file mode 100644 index 00000000..28196b73 --- /dev/null +++ b/jwt_compact/struct.SignedToken.html @@ -0,0 +1,59 @@ +SignedToken in jwt_compact - Rust
#[non_exhaustive]
pub struct SignedToken<A: Algorithm + ?Sized, T, H = Empty> { + pub signature: A::Signature, + pub token: Token<T, H>, +}
Expand description

Token together with the validated token signature.

+

Examples

+
#[derive(Serialize, Deserialize)]
+struct MyClaims {
+    // Custom claims in the token...
+}
+
+let token_string: String = // token from an external source
+let token = UntrustedToken::new(&token_string)?;
+let signed = Hs256.validator::<MyClaims>(&key)
+    .validate_for_signed_token(&token)?;
+
+// `signature` is strongly typed.
+let signature: Hs256Signature = signed.signature;
+// Token itself is available via `token` field.
+let claims = signed.token.claims();
+claims.validate_expiration(&TimeOptions::default())?;
+// Process the claims...
+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§signature: A::Signature

Token signature.

+
§token: Token<T, H>

Verified token.

+

Trait Implementations§

source§

impl<A, T, H> Clone for SignedToken<A, T, H>where + A: Algorithm, + A::Signature: Clone, + T: Clone, + H: Clone,

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<A, T, H> Debug for SignedToken<A, T, H>where + A: Algorithm, + A::Signature: Debug, + T: Debug, + H: Debug,

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<A: ?Sized, T, H> RefUnwindSafe for SignedToken<A, T, H>where + H: RefUnwindSafe, + T: RefUnwindSafe, + <A as Algorithm>::Signature: RefUnwindSafe,

§

impl<A: ?Sized, T, H> Send for SignedToken<A, T, H>where + H: Send, + T: Send, + <A as Algorithm>::Signature: Send,

§

impl<A: ?Sized, T, H> Sync for SignedToken<A, T, H>where + H: Sync, + T: Sync, + <A as Algorithm>::Signature: Sync,

§

impl<A: ?Sized, T, H> Unpin for SignedToken<A, T, H>where + H: Unpin, + T: Unpin, + <A as Algorithm>::Signature: Unpin,

§

impl<A: ?Sized, T, H> UnwindSafe for SignedToken<A, T, H>where + H: UnwindSafe, + T: UnwindSafe, + <A as Algorithm>::Signature: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/struct.TimeOptions.html b/jwt_compact/struct.TimeOptions.html new file mode 100644 index 00000000..94446f82 --- /dev/null +++ b/jwt_compact/struct.TimeOptions.html @@ -0,0 +1,40 @@ +TimeOptions in jwt_compact - Rust
#[non_exhaustive]
pub struct TimeOptions<F = fn() -> DateTime<Utc>> { + pub leeway: Duration, + pub clock_fn: F, +}
Expand description

Time-related options for token creation and validation.

+

If the clock crate feature is on (and it’s on by default), TimeOptions can be created +using the Default impl or Self::from_leeway(). If the feature is off, +you can still create options using a generic constructor.

+

Examples

+
// Default options.
+let default_options = TimeOptions::default();
+let options_with_custom_leeway =
+    TimeOptions::from_leeway(Duration::seconds(5));
+// Options that have a fixed time. Can be useful for testing.
+let clock_time = Utc::now();
+let options_with_stopped_clock =
+    TimeOptions::new(Duration::seconds(10), move || clock_time);
+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§leeway: Duration

Leeway to use during validation.

+
§clock_fn: F

Source of the current timestamps.

+

Implementations§

source§

impl<F: Fn() -> DateTime<Utc>> TimeOptions<F>

source

pub fn new(leeway: Duration, clock_fn: F) -> Self

Creates options based on the specified time leeway and clock function.

+
source§

impl TimeOptions

source

pub fn from_leeway(leeway: Duration) -> Self

Available on crate feature clock only.

Creates options based on the specified time leeway. The clock source is Utc::now().

+

Trait Implementations§

source§

impl<F: Clone> Clone for TimeOptions<F>

source§

fn clone(&self) -> TimeOptions<F>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<F: Debug> Debug for TimeOptions<F>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for TimeOptions

Creates options with a default leeway (60 seconds) and the Utc::now() clock.

+

This impl is supported on crate feature clock only.

+
source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<F: Copy> Copy for TimeOptions<F>

Auto Trait Implementations§

§

impl<F> RefUnwindSafe for TimeOptions<F>where + F: RefUnwindSafe,

§

impl<F> Send for TimeOptions<F>where + F: Send,

§

impl<F> Sync for TimeOptions<F>where + F: Sync,

§

impl<F> Unpin for TimeOptions<F>where + F: Unpin,

§

impl<F> UnwindSafe for TimeOptions<F>where + F: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/struct.Token.html b/jwt_compact/struct.Token.html new file mode 100644 index 00000000..0656687d --- /dev/null +++ b/jwt_compact/struct.Token.html @@ -0,0 +1,29 @@ +Token in jwt_compact - Rust

Struct jwt_compact::Token

source ·
pub struct Token<T, H = Empty> { /* private fields */ }
Expand description

Token with validated integrity.

+

Claims encoded in the token can be verified by invoking Claims methods +via Self::claims().

+

Implementations§

source§

impl<T, H> Token<T, H>

source

pub fn header(&self) -> &Header<H>

Gets token header.

+
source

pub fn claims(&self) -> &Claims<T>

Gets token claims.

+
source

pub fn into_parts(self) -> (Header<H>, Claims<T>)

Splits the Token into the respective Header and Claims while consuming it.

+

Trait Implementations§

source§

impl<T: Clone, H: Clone> Clone for Token<T, H>

source§

fn clone(&self) -> Token<T, H>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug, H: Debug> Debug for Token<T, H>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T, H> RefUnwindSafe for Token<T, H>where + H: RefUnwindSafe, + T: RefUnwindSafe,

§

impl<T, H> Send for Token<T, H>where + H: Send, + T: Send,

§

impl<T, H> Sync for Token<T, H>where + H: Sync, + T: Sync,

§

impl<T, H> Unpin for Token<T, H>where + H: Unpin, + T: Unpin,

§

impl<T, H> UnwindSafe for Token<T, H>where + H: UnwindSafe, + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/struct.UntrustedToken.html b/jwt_compact/struct.UntrustedToken.html new file mode 100644 index 00000000..f4da1727 --- /dev/null +++ b/jwt_compact/struct.UntrustedToken.html @@ -0,0 +1,60 @@ +UntrustedToken in jwt_compact - Rust
pub struct UntrustedToken<'a, H = Empty> { /* private fields */ }
Expand description

Parsed, but unvalidated token.

+

The type param (Empty by default) corresponds to the additional information enclosed +in the token Header.

+

An UntrustedToken can be parsed from a string using the TryFrom implementation. +This checks that a token is well-formed (has a header, claims and a signature), +but does not validate the signature. +As a shortcut, a token without additional header info can be created using Self::new().

+

Examples

+
let token_str = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJp\
+    c3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leG\
+    FtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJ\
+    U1p1r_wW1gFWFOEjXk";
+let token: UntrustedToken = token_str.try_into()?;
+// The same operation using a shortcut:
+let same_token = UntrustedToken::new(token_str)?;
+// Token header can be accessed to select the verifying key etc.
+let key_id: Option<&str> = token.header().key_id.as_deref();
+

Handling tokens with custom header fields

+
#[derive(Debug, Clone, Deserialize)]
+struct HeaderExtensions {
+    custom: String,
+}
+
+let token_str = "eyJhbGciOiJIUzI1NiIsImtpZCI6InRlc3Rfa2V5Iiwid\
+    HlwIjoiSldUIiwiY3VzdG9tIjoiY3VzdG9tIn0.eyJzdWIiOiIxMjM0NTY\
+    3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9._27Fb6nF\
+    Tg-HSt3vO4ylaLGcU_ZV2VhMJR4HL7KaQik";
+let token: UntrustedToken<HeaderExtensions> = token_str.try_into()?;
+let extensions = &token.header().other_fields;
+println!("{}", extensions.custom);
+

Implementations§

source§

impl<'a> UntrustedToken<'a>

source

pub fn new<S: AsRef<str> + ?Sized>(s: &'a S) -> Result<Self, ParseError>

Creates an untrusted token from a string. This is a shortcut for calling the TryFrom +conversion.

+
source§

impl<H> UntrustedToken<'_, H>

source

pub fn into_owned(self) -> UntrustedToken<'static, H>

Converts this token to an owned form.

+
source

pub fn header(&self) -> &Header<H>

Gets the token header.

+
source

pub fn algorithm(&self) -> &str

Gets the integrity algorithm used to secure the token.

+
source

pub fn signature_bytes(&self) -> &[u8]

Returns signature bytes from the token. These bytes are not guaranteed to form a valid +signature.

+
source

pub fn deserialize_claims_unchecked<T>( + &self +) -> Result<Claims<T>, ValidationError>where + T: DeserializeOwned,

Deserializes claims from this token without checking token integrity. The resulting +claims are thus not guaranteed to be valid.

+

Trait Implementations§

source§

impl<'a, H: Clone> Clone for UntrustedToken<'a, H>

source§

fn clone(&self) -> UntrustedToken<'a, H>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, H: Debug> Debug for UntrustedToken<'a, H>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, H: DeserializeOwned> TryFrom<&'a str> for UntrustedToken<'a, H>

§

type Error = ParseError

The type returned in the event of a conversion error.
source§

fn try_from(s: &'a str) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl<'a, H> RefUnwindSafe for UntrustedToken<'a, H>where + H: RefUnwindSafe,

§

impl<'a, H> Send for UntrustedToken<'a, H>where + H: Send,

§

impl<'a, H> Sync for UntrustedToken<'a, H>where + H: Sync,

§

impl<'a, H> Unpin for UntrustedToken<'a, H>where + H: Unpin,

§

impl<'a, H> UnwindSafe for UntrustedToken<'a, H>where + H: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/struct.Validator.html b/jwt_compact/struct.Validator.html new file mode 100644 index 00000000..3c519abf --- /dev/null +++ b/jwt_compact/struct.Validator.html @@ -0,0 +1,33 @@ +Validator in jwt_compact - Rust

Struct jwt_compact::Validator

source ·
pub struct Validator<'a, A: Algorithm + ?Sized, T> { /* private fields */ }
Expand description

Validator for a certain signing Algorithm associated with a specific verifying key +and a claims type. Produced by the AlgorithmExt::validator() method.

+

Implementations§

source§

impl<A: Algorithm + ?Sized, T: DeserializeOwned> Validator<'_, A, T>

source

pub fn validate<H: Clone>( + self, + token: &UntrustedToken<'_, H> +) -> Result<Token<T, H>, ValidationError>

Validates the token integrity against a verifying key enclosed in this validator.

+
source

pub fn validate_for_signed_token<H: Clone>( + self, + token: &UntrustedToken<'_, H> +) -> Result<SignedToken<A, T, H>, ValidationError>

Validates the token integrity against a verifying key enclosed in this validator, +and returns the validated Token together with its signature.

+

Trait Implementations§

source§

impl<A: Algorithm + ?Sized, T> Clone for Validator<'_, A, T>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, A: Debug + Algorithm + ?Sized, T: Debug> Debug for Validator<'a, A, T>where + A::VerifyingKey: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<A: Algorithm + ?Sized, T> Copy for Validator<'_, A, T>

Auto Trait Implementations§

§

impl<'a, A: ?Sized, T> RefUnwindSafe for Validator<'a, A, T>where + A: RefUnwindSafe, + <A as Algorithm>::VerifyingKey: RefUnwindSafe,

§

impl<'a, A: ?Sized, T> Send for Validator<'a, A, T>where + A: Sync, + <A as Algorithm>::VerifyingKey: Sync,

§

impl<'a, A: ?Sized, T> Sync for Validator<'a, A, T>where + A: Sync, + <A as Algorithm>::VerifyingKey: Sync,

§

impl<'a, A: ?Sized, T> Unpin for Validator<'a, A, T>

§

impl<'a, A: ?Sized, T> UnwindSafe for Validator<'a, A, T>where + A: RefUnwindSafe, + <A as Algorithm>::VerifyingKey: RefUnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/jwt_compact/token/enum.Thumbprint.html b/jwt_compact/token/enum.Thumbprint.html new file mode 100644 index 00000000..ced1329c --- /dev/null +++ b/jwt_compact/token/enum.Thumbprint.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/enum.Thumbprint.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/token/struct.Header.html b/jwt_compact/token/struct.Header.html new file mode 100644 index 00000000..88bc535b --- /dev/null +++ b/jwt_compact/token/struct.Header.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.Header.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/token/struct.SignedToken.html b/jwt_compact/token/struct.SignedToken.html new file mode 100644 index 00000000..1ed36159 --- /dev/null +++ b/jwt_compact/token/struct.SignedToken.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.SignedToken.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/token/struct.Token.html b/jwt_compact/token/struct.Token.html new file mode 100644 index 00000000..9cf524ce --- /dev/null +++ b/jwt_compact/token/struct.Token.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.Token.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/token/struct.UntrustedToken.html b/jwt_compact/token/struct.UntrustedToken.html new file mode 100644 index 00000000..b9b730ca --- /dev/null +++ b/jwt_compact/token/struct.UntrustedToken.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.UntrustedToken.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/trait.Algorithm.html b/jwt_compact/trait.Algorithm.html new file mode 100644 index 00000000..fc89845f --- /dev/null +++ b/jwt_compact/trait.Algorithm.html @@ -0,0 +1,39 @@ +Algorithm in jwt_compact - Rust
pub trait Algorithm {
+    type SigningKey;
+    type VerifyingKey;
+    type Signature: AlgorithmSignature;
+
+    // Required methods
+    fn name(&self) -> Cow<'static, str>;
+    fn sign(
+        &self,
+        signing_key: &Self::SigningKey,
+        message: &[u8]
+    ) -> Self::Signature;
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8]
+    ) -> bool;
+}
Expand description

JWT signing algorithm.

+

Required Associated Types§

source

type SigningKey

Key used when issuing new tokens.

+
source

type VerifyingKey

Key used when verifying tokens. May coincide with Self::SigningKey for symmetric +algorithms (e.g., HS*).

+
source

type Signature: AlgorithmSignature

Signature produced by the algorithm.

+

Required Methods§

source

fn name(&self) -> Cow<'static, str>

Returns the name of this algorithm, as mentioned in the alg field of the JWT header.

+
source

fn sign( + &self, + signing_key: &Self::SigningKey, + message: &[u8] +) -> Self::Signature

Signs a message with the signing_key.

+
source

fn verify_signature( + &self, + signature: &Self::Signature, + verifying_key: &Self::VerifyingKey, + message: &[u8] +) -> bool

Verifies the message against the signature and verifying_key.

+

Implementors§

source§

impl Algorithm for Ed25519

§

type SigningKey = SecretKey

§

type VerifyingKey = PublicKey

§

type Signature = Signature

source§

impl Algorithm for Es256

§

type SigningKey = SigningKey<NistP256>

§

type VerifyingKey = VerifyingKey<NistP256>

§

type Signature = Signature<NistP256>

source§

impl Algorithm for Hs256

source§

impl Algorithm for Hs384

source§

impl Algorithm for Hs512

source§

impl Algorithm for Rsa

source§

impl<A: Algorithm> Algorithm for Renamed<A>

source§

impl<D> Algorithm for Es256k<D>where + D: FixedOutputReset<OutputSize = U32> + BlockSizeUser + Clone + Default + HashMarker,

source§

impl<T: Algorithm> Algorithm for StrongAlg<T>where + StrongKey<T::SigningKey>: TryFrom<T::SigningKey>, + StrongKey<T::VerifyingKey>: TryFrom<T::VerifyingKey>,

\ No newline at end of file diff --git a/jwt_compact/trait.AlgorithmExt.html b/jwt_compact/trait.AlgorithmExt.html new file mode 100644 index 00000000..233417a4 --- /dev/null +++ b/jwt_compact/trait.AlgorithmExt.html @@ -0,0 +1,67 @@ +AlgorithmExt in jwt_compact - Rust
pub trait AlgorithmExt: Algorithm {
+    // Required methods
+    fn token<T>(
+        &self,
+        header: &Header<impl Serialize>,
+        claims: &Claims<T>,
+        signing_key: &Self::SigningKey
+    ) -> Result<String, CreationError>
+       where T: Serialize;
+    fn compact_token<T>(
+        &self,
+        header: &Header<impl Serialize>,
+        claims: &Claims<T>,
+        signing_key: &Self::SigningKey
+    ) -> Result<String, CreationError>
+       where T: Serialize;
+    fn validator<'a, T>(
+        &'a self,
+        verifying_key: &'a Self::VerifyingKey
+    ) -> Validator<'a, Self, T>;
+    fn validate_integrity<T>(
+        &self,
+        token: &UntrustedToken<'_>,
+        verifying_key: &Self::VerifyingKey
+    ) -> Result<Token<T>, ValidationError>
+       where T: DeserializeOwned;
+    fn validate_for_signed_token<T>(
+        &self,
+        token: &UntrustedToken<'_>,
+        verifying_key: &Self::VerifyingKey
+    ) -> Result<SignedToken<Self, T>, ValidationError>
+       where T: DeserializeOwned;
+}
Expand description

Automatically implemented extensions of the Algorithm trait.

+

Required Methods§

source

fn token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &Self::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Creates a new token and serializes it to string.

+
source

fn compact_token<T>( + &self, + header: &Header<impl Serialize>, + claims: &Claims<T>, + signing_key: &Self::SigningKey +) -> Result<String, CreationError>where + T: Serialize,

Available on crate feature ciborium only.

Creates a new token with CBOR-encoded claims and serializes it to string.

+
source

fn validator<'a, T>( + &'a self, + verifying_key: &'a Self::VerifyingKey +) -> Validator<'a, Self, T>

Creates a JWT validator for the specified verifying key and the claims type. +The validator can then be used to validate integrity of one or more tokens.

+
source

fn validate_integrity<T>( + &self, + token: &UntrustedToken<'_>, + verifying_key: &Self::VerifyingKey +) -> Result<Token<T>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate() for added flexibility

Validates the token integrity against the provided verifying_key.

+
source

fn validate_for_signed_token<T>( + &self, + token: &UntrustedToken<'_>, + verifying_key: &Self::VerifyingKey +) -> Result<SignedToken<Self, T>, ValidationError>where + T: DeserializeOwned,

👎Deprecated: Use .validator().validate_for_signed_token() for added flexibility

Validates the token integrity against the provided verifying_key.

+

Unlike validate_integrity, this method retains more +information about the original token, in particular, its signature.

+

Implementors§

\ No newline at end of file diff --git a/jwt_compact/trait.AlgorithmSignature.html b/jwt_compact/trait.AlgorithmSignature.html new file mode 100644 index 00000000..cd350198 --- /dev/null +++ b/jwt_compact/trait.AlgorithmSignature.html @@ -0,0 +1,23 @@ +AlgorithmSignature in jwt_compact - Rust
pub trait AlgorithmSignature: Sized {
+    const LENGTH: Option<NonZeroUsize> = None;
+
+    // Required methods
+    fn try_from_slice(slice: &[u8]) -> Result<Self>;
+    fn as_bytes(&self) -> Cow<'_, [u8]>;
+}
Expand description

Signature for a certain JWT signing Algorithm.

+

We require that signature can be restored from a byte slice, +and can be represented as a byte slice.

+

Provided Associated Constants§

source

const LENGTH: Option<NonZeroUsize> = None

Constant byte length of signatures supported by the Algorithm, or None if +the signature length is variable.

+
    +
  • If this value is Some(_), the signature will be first checked for its length +during token verification. An InvalidSignatureLen error will be raised if the length +is invalid. Self::try_from_slice() will thus always receive a slice with +the expected length.
  • +
  • If this value is None, no length check is performed before calling +Self::try_from_slice().
  • +
+

Required Methods§

source

fn try_from_slice(slice: &[u8]) -> Result<Self>

Attempts to restore a signature from a byte slice. This method may fail +if the slice is malformed.

+
source

fn as_bytes(&self) -> Cow<'_, [u8]>

Represents this signature as bytes.

+

Implementations on Foreign Types§

source§

impl AlgorithmSignature for Signature

source§

const LENGTH: Option<NonZeroUsize> = _

source§

fn try_from_slice(slice: &[u8]) -> Result<Self>

source§

fn as_bytes(&self) -> Cow<'_, [u8]>

source§

impl AlgorithmSignature for Signature

source§

const LENGTH: Option<NonZeroUsize> = _

source§

fn try_from_slice(slice: &[u8]) -> Result<Self>

source§

fn as_bytes(&self) -> Cow<'_, [u8]>

source§

impl AlgorithmSignature for Signature

source§

const LENGTH: Option<NonZeroUsize> = _

source§

fn try_from_slice(bytes: &[u8]) -> Result<Self>

source§

fn as_bytes(&self) -> Cow<'_, [u8]>

Implementors§

\ No newline at end of file diff --git a/jwt_compact/traits/struct.Renamed.html b/jwt_compact/traits/struct.Renamed.html new file mode 100644 index 00000000..d978d602 --- /dev/null +++ b/jwt_compact/traits/struct.Renamed.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.Renamed.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/traits/struct.Validator.html b/jwt_compact/traits/struct.Validator.html new file mode 100644 index 00000000..03dae562 --- /dev/null +++ b/jwt_compact/traits/struct.Validator.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/struct.Validator.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/traits/trait.Algorithm.html b/jwt_compact/traits/trait.Algorithm.html new file mode 100644 index 00000000..c1631c5d --- /dev/null +++ b/jwt_compact/traits/trait.Algorithm.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/trait.Algorithm.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/traits/trait.AlgorithmExt.html b/jwt_compact/traits/trait.AlgorithmExt.html new file mode 100644 index 00000000..987ad6f9 --- /dev/null +++ b/jwt_compact/traits/trait.AlgorithmExt.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/trait.AlgorithmExt.html...

+ + + \ No newline at end of file diff --git a/jwt_compact/traits/trait.AlgorithmSignature.html b/jwt_compact/traits/trait.AlgorithmSignature.html new file mode 100644 index 00000000..28610d17 --- /dev/null +++ b/jwt_compact/traits/trait.AlgorithmSignature.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../jwt_compact/trait.AlgorithmSignature.html...

+ + + \ No newline at end of file diff --git a/search-index.js b/search-index.js new file mode 100644 index 00000000..446f247e --- /dev/null +++ b/search-index.js @@ -0,0 +1,5 @@ +var searchIndex = JSON.parse('{\ +"jwt_compact":{"doc":"Minimalistic JSON web token (JWT) implementation with …","t":"IININNEDNEDNNDNNNNNSSNNNNNNNEDQDQNEDDNDEDQALKLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLMLLLLLLLLLLLLLLLLLLLLLLKLMLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMAMMMKLLLLLLMMALLLLLLLKLMLLLLLLLLLLLLLLLLLLLKLMMLLLLLLLLLLLLLLLKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKLLKLLKLKLLLLLLLLLLLLLLLLLLLLLMMMMDDDNDDDDDDDDDSSSEDDDDDDDIDDNNIDKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNEENNENNNNDDNNNNNLLLLLLLLLLLLLLLLLLMMLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMCCCCCC","n":["Algorithm","AlgorithmExt","AlgorithmMismatch","AlgorithmSignature","Bytes","CborClaims","Claim","Claims","Claims","CreationError","Empty","Expiration","Expired","Header","Header","InvalidBase64Encoding","InvalidSignature","InvalidSignatureLen","InvalidTokenStructure","LENGTH","LENGTH","MalformedCborClaims","MalformedClaims","MalformedHeader","MalformedSignature","NoClaim","NotBefore","NotMature","ParseError","Renamed","Signature","SignedToken","SigningKey","String","Thumbprint","TimeOptions","Token","UnsupportedContentType","UntrustedToken","ValidationError","Validator","VerifyingKey","alg","algorithm","as_bytes","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","certificate_sha1_thumbprint","certificate_thumbprint","certificate_url","claims","clock_fn","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","compact_token","compact_token","custom","default","default","default","deserialize","deserialize","deserialize","deserialize","deserialize_claims_unchecked","empty","empty","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","expiration","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_leeway","hash","hash","header","header","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_owned","into_parts","issued_at","jwk","key_id","key_set_url","leeway","name","name","new","new","new","new","new","not_before","other_fields","prelude","serialize","serialize","serialize","serialize","set_duration","set_duration_and_issuance","set_not_before","sign","sign","signature","signature_bytes","source","source","source","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","token","token","token","token_type","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from_slice","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","validate","validate_expiration","validate_for_signed_token","validate_for_signed_token","validate_for_signed_token","validate_integrity","validate_integrity","validate_maturity","validator","validator","verify_signature","verify_signature","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","with_certificate_sha1_thumbprint","with_certificate_thumbprint","with_certificate_url","with_key_id","with_key_set_url","with_token_type","actual","actual","expected","expected","Ed25519","Es256","Es256k","FourKibibytes","Hs256","Hs256Key","Hs256Signature","Hs384","Hs384Key","Hs384Signature","Hs512","Hs512Key","Hs512Signature","MAX_PUB_EXPONENT","MAX_SIZE","MIN_PUB_EXPONENT","ModulusBits","ModulusBitsError","Rsa","RsaParseError","RsaPrivateKey","RsaPublicKey","RsaSignature","SecretBytes","SigningKey","StrongAlg","StrongKey","ThreeKibibytes","TwoKibibytes","VerifyingKey","WeakKeyError","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_mut","as_mut","as_mut","as_ref","as_ref","as_ref","as_ref","as_ref","as_ref","bits","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrowed","clear_precomputed","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","compact_token","compact_token","compact_token","compact_token","compact_token","compact_token","compact_token","compact_token","crt_coefficient","crt_values","d","decrypt","decrypt_blinded","default","default","default","default","default","default","default","deref","deserialize","dp","dq","drop","drop","e","e","encode_hex","encode_hex","encode_hex","encode_hex","encode_hex","encode_hex_upper","encode_hex_upper","encode_hex_upper","encode_hex_upper","encode_hex_upper","encrypt","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_components","from_p_q","from_pkcs1_der","from_pkcs1_der","from_pkcs8_der","from_primes","from_public_key_der","from_slice","from_slice","from_slice","from_slice","from_slice","from_slice","from_slice","from_slice","from_str","generate","generate","generate","generate","hash","hash","hash","hash","hash","hash","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_inner","n","n","name","name","name","name","name","name","name","name","new","new","new","new","new","new","new_unchecked","new_with_exp","new_with_max_size","owned","precompute","primes","ps256","ps384","ps512","qinv","rs256","rs384","rs512","serialize","sign","sign","sign","sign","sign","sign","sign","sign","sign","sign_with_rng","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_pkcs1_der","to_pkcs1_der","to_pkcs8_der","to_public_key","to_public_key","to_public_key_der","to_string","to_string","to_string","to_verifying_key","to_verifying_key","to_verifying_key","to_verifying_key","token","token","token","token","token","token","token","token","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from_slice","try_from_slice","try_from_slice","try_from_slice","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","validate","validate_for_signed_token","validate_for_signed_token","validate_for_signed_token","validate_for_signed_token","validate_for_signed_token","validate_for_signed_token","validate_for_signed_token","validate_for_signed_token","validate_integrity","validate_integrity","validate_integrity","validate_integrity","validate_integrity","validate_integrity","validate_integrity","validate_integrity","validator","validator","validator","validator","validator","validator","validator","validator","verify","verify_signature","verify_signature","verify_signature","verify_signature","verify_signature","verify_signature","verify_signature","verify_signature","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","with_name","with_specific_name","zeroize","zeroize","zeroize","Custom","EllipticCurve","EllipticCurve","JsonWebKey","JwkError","KeyPair","KeyPair","KeyType","MismatchedKeys","NoField","Rsa","Rsa","RsaPrimeFactor","RsaPrivateParts","Symmetric","Symmetric","UnexpectedKeyType","UnexpectedLen","UnexpectedValue","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","crt_coefficient","crt_exponent","custom","deserialize","deserialize","deserialize","eq","eq","eq","eq","equivalent","factor","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","hash","into","into","into","into","into","is_signing_key","key_type","other_prime_factors","p_crt_exponent","prime_factor_p","prime_factor_q","private_exponent","q_crt_coefficient","q_crt_exponent","serialize","serialize","serialize","source","thumbprint","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_verifying_key","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","curve","curve","modulus","private_parts","public_exponent","secret","secret","secret","x","x","y","actual","actual","actual","expected","expected","expected","field","field","Claims","Header","TimeOptions","Token","UntrustedToken","_"],"q":[[0,"jwt_compact"],[302,"jwt_compact::ValidationError"],[306,"jwt_compact::alg"],[840,"jwt_compact::jwk"],[961,"jwt_compact::jwk::JsonWebKey"],[972,"jwt_compact::jwk::JwkError"],[980,"jwt_compact::prelude"],[986,"alloc::borrow"],[987,"core::clone"],[988,"core::marker"],[989,"serde::ser"],[990,"alloc::string"],[991,"core::result"],[992,"core::default"],[993,"serde::de"],[994,"serde::de"],[995,"core::fmt"],[996,"core::fmt"],[997,"core::hash"],[998,"core::ops::function"],[999,"core::convert"],[1000,"serde::ser"],[1001,"chrono::datetime"],[1002,"core::error"],[1003,"core::option"],[1004,"anyhow"],[1005,"core::any"],[1006,"core::convert"],[1007,"rsa::traits::keys"],[1008,"rsa::traits::padding"],[1009,"alloc::alloc"],[1010,"alloc::vec"],[1011,"rsa::errors"],[1012,"rand_core"],[1013,"digest"],[1014,"crypto_common"],[1015,"digest::digest"],[1016,"core::iter::traits::collect"],[1017,"core::fmt"],[1018,"rsa::pss::verifying_key"],[1019,"rsa::pss::signing_key"],[1020,"rsa::pkcs1v15::signing_key"],[1021,"rsa::pss::blinded_signing_key"],[1022,"pkcs1::error"],[1023,"pkcs8::error"],[1024,"spki::error"],[1025,"rand_core"],[1026,"secp256k1"],[1027,"num_bigint_dig::bigint"],[1028,"rsa::traits::padding"],[1029,"der::document"],[1030,"der::asn1::bit_string"],[1031,"spki::spki"],[1032,"pkcs8::private_key_info"],[1033,"anyhow"],[1034,"p256::ecdsa"],[1035,"exonum_crypto"],[1036,"p256::ecdsa"]],"d":["JWT signing algorithm.","Automatically implemented extensions of the Algorithm …","Algorithm mentioned in the token header differs from …","Signature for a certain JWT signing Algorithm.","Byte representation of a SHA-1 or SHA-256 digest.","Token claims cannot be serialized into CBOR.","Identifier of a claim in Claims.","Claims encoded in a token.","Token claims cannot be serialized into JSON.","Errors that can occur during token creation.","A structure with no fields that can be used as a type …","exp claim (expiration time).","Token has expired.","JWT header.","Token header cannot be serialized.","Cannot decode base64.","Token signature has failed verification.","Token signature has invalid byte length.","Token has invalid structure.","Constant byte length of signatures supported by the …","Constant byte length of signatures supported by the …","Token claims cannot be deserialized from CBOR.","Token claims cannot be deserialized from JSON.","Token header cannot be parsed.","Token signature is malformed.","Claim requested during validation is not present in the …","nbf claim (valid not before).","Token is not yet valid as per nbf claim.","Errors that may occur during token parsing.","Algorithm that uses a custom name when creating and …","Signature produced by the algorithm.","Token together with the validated token signature.","Key used when issuing new tokens.","Opaque string representation of the thumbprint. It is the …","Representation of a X.509 certificate thumbprint (x5t and …","Time-related options for token creation and validation.","Token with validated integrity.","Content type mentioned in the token header is not …","Parsed, but unvalidated token.","Errors that can occur during token validation.","Validator for a certain signing Algorithm associated with …","Key used when verifying tokens. May coincide with …","Implementations of JWT signing / verification algorithms. …","Gets the integrity algorithm used to secure the token.","Represents this signature as bytes.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","SHA-1 thumbprint of the X.509 certificate for the signing …","SHA-256 thumbprint of the X.509 certificate for the …","URL of the X.509 certificate for the signing key. This …","Gets token claims.","Source of the current timestamps.","","","","","","","","","","","","","","","","","","","","","","","Creates a new token with CBOR-encoded claims and …","","Custom claims.","","","","","","","","Deserializes claims from this token without checking token …","Creates an empty claims instance.","Creates an empty header.","","","","","","","","","Expiration time of the token.","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Creates options based on the specified time leeway. The …","","","Gets the token header.","Gets token header.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Converts this token to an owned form.","Splits the Token into the respective Header and Claims …","Time of token issuance.","Basic support of JSON Web Keys (JWK).","Identifier of the key that has signed the token. This …","URL of the JSON Web Key Set containing the key that has …","Leeway to use during validation.","Returns the name of this algorithm, as mentioned in the alg…","","Creates options based on the specified time leeway and …","Creates a new instance with the provided custom claims.","Creates a header with the specified custom fields.","Creates an untrusted token from a string. This is a …","Creates a renamed algorithm.","Minimum time at which token is valid.","Other fields encoded in the header. These fields may be …","Prelude to neatly import all necessary stuff from the …","","","","","Sets the expiration claim so that the token has the …","Atomically sets issued_at and expiration claims: first to …","Sets the nbf claim.","Signs a message with the signing_key.","","Token signature.","Returns signature bytes from the token. These bytes are not…","","","","","","","","","","","","","","","","","","","Creates a new token and serializes it to string.","","Verified token.","Application-specific token type. This field is renamed to …","","","","","","","","","","","","","","","","Attempts to restore a signature from a byte slice. This …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Validates the token integrity against a verifying key …","Validates the expiration claim.","Validates the token integrity against the provided …","","Validates the token integrity against a verifying key …","Validates the token integrity against the provided …","","Validates the maturity time (nbf claim).","Creates a JWT validator for the specified verifying key …","","Verifies the message against the signature and …","","","","","","","","","","","","","","","","Sets the certificate_sha1_thumbprint field for this header.","Sets the certificate_thumbprint field for this header.","Sets the certificate_url field for this header.","Sets the key_id field for this header.","Sets the key_set_url field for this header.","Sets the token_type field for this header.","Actual algorithm in the token.","Actual signature length.","Expected algorithm name.","Expected signature length.","Integrity algorithm using digital signatures on the …","ES256 signing algorithm. Implements elliptic curve digital …","Algorithm implementing elliptic curve digital signatures …","4096 bits.","HS256 signing algorithm.","Signing / verifying key for HS256 algorithm. Zeroed on …","Signature produced by the Hs256 algorithm.","HS384 signing algorithm.","Signing / verifying key for HS384 algorithm. Zeroed on …","Signature produced by the Hs384 algorithm.","HS512 signing algorithm.","Signing / verifying key for HS512 algorithm. Zeroed on …","Signature produced by the Hs512 algorithm.","Maximum value of the public exponent e.","Maximum size of the modulus n in bits.","Minimum value of the public exponent e.","Bit length of an RSA key modulus (aka RSA key length).","Error type returned when a conversion of an integer into …","Integrity algorithm using RSA digital signatures.","Errors that can occur when parsing an Rsa algorithm from a …","Represents a whole RSA key, public and private parts.","Represents the public part of an RSA key.","RSA signature.","Generic container for secret bytes, which can be either …","Signing key for a specific signature cryptosystem. In the …","Wrapper around a JWT algorithm signalling that it supports …","Wrapper around keys allowing to enforce key strength …","3072 bits.","2048 bits. This is the minimum recommended key length as …","Verifying key for a specific signature cryptosystem. In …","Error type used for fallible conversion into a StrongKey.","Returns the key as raw bytes.","Returns the key as raw bytes.","","","","","","","","","","","","","","","","","","","","Converts this length to the numeric value.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Creates secret bytes from a borrowed slice.","Clears precomputed values by setting to None","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Compute CRT coefficient: (1/q) mod p.","","","Decrypt the given message.","Decrypt the given message.","","","","","","","","","","","","","","","","","","","","","","","","","","Encrypt the given message.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","","Constructs an RSA key pair from individual components:","Constructs an RSA key pair from its two primes p and q.","","","","Constructs an RSA key pair from its primes.","","Creates a key from raw bytes. Returns an error if the …","Creates a key from raw bytes. Returns an error if the …","","","","","","","","Generates a random key using a cryptographically secure …","Generates a random key using a cryptographically secure …","Generates a random key using a cryptographically secure …","Generates a new key pair with the specified modulus bit …","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Returns the wrapped value.","","","","","","","","","","","Creates a key from the specified bytes.","Creates a key from the specified bytes.","Creates a key from the specified bytes.","Creates a new algorithm instance. This is a (moderately) …","Create a new public key from its components.","Generate a new Rsa key pair of the given bit size using …","Create a new public key, bypassing checks around the …","Generate a new RSA key pair of the given bit size and the …","Create a new public key from its components.","Creates secret bytes from an owned Vec.","Performs some calculations to speed up private key …","","RSA with SHA-256 and PSS padding.","RSA with SHA-384 and PSS padding.","RSA with SHA-512 and PSS padding.","","RSA with SHA-256 and PKCS#1 v1.5 padding.","RSA with SHA-384 and PKCS#1 v1.5 padding.","RSA with SHA-512 and PKCS#1 v1.5 padding.","","","","","","","","","","Sign the given digest.","Sign the given digest using the provided rng, which is …","","","","","","","","","","","","","","","","","","","","","Converts this private key to a public key.","Get the public key from the private key, cloning n and e.","","","","","Converts a signing key to a verification key.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Performs basic sanity checks on the key. Returns Ok(()) if …","","","","","","","","","","","","","","","","","","","","","","","","","Verify a signed message.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","RSA based on the specified algorithm name.","Creates an algorithm instance with the algorithm name …","","","","Custom error specific to a crypto backend.","Public or private key in an ECDSA crypto system. …","Public or private key in an ECDSA crypto system. Has kty …","Basic JWK functionality: (de)serialization and creating …","Errors that can occur when transforming a JsonWebKey into …","Generic asymmetric keypair. Corresponds to the OKP value …","Generic asymmetric keypair. This key type is used e.g. for …","Type of a JsonWebKey.","Signing and verifying keys do not match.","Required field is absent from JWK.","Public or private RSA key. Corresponds to the RSA value of …","Public or private RSA key. Has kty field set to RSA.","Block for an additional prime factor in RsaPrivateParts.","Parts of JsonWebKey::Rsa that are specific to private keys.","Symmetric key. Corresponds to the oct value of the kty …","Generic symmetric key, e.g. for HS256 algorithm. Has kty …","Key type (the kty field) is not as expected.","JWK field has an unexpected byte length.","JWK field has an unexpected value.","","","","","","","","","","","","","","","","","","","Factor CRT coefficient (t).","Factor CRT exponent (d).","Creates a Custom error variant.","","","","","","","","","Prime factor (r).","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","","Returns the argument unchanged.","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Returns true if this key can be used for signing (has …","Gets the type of this key.","Other prime factors.","First factor CRT exponent (dp).","First prime factor (p).","Second prime factor (q).","Private exponent (d).","CRT coefficient of the second factor (qi).","Second factor CRT exponent (dq).","","","","","Computes a thumbprint of this JWK. The result complies …","","","","","","","","Returns a copy of this key with parts not necessary for …","","","","","","","","","","","","","","","","","","","","","Curve name (crv), such as secp256k1.","Curve name (crv), such as Ed25519.","Key modulus (n).","Private RSA parameters. Only present for private keys.","Public exponent (e).","Secret scalar (d); not present for public keys.","Bytes representing this key.","Secret key (d). For Ed25519, this is the seed.","x coordinate of the curve point.","Public key. For Ed25519, this is the standard 32-byte …","y coordinate of the curve point.","Actual key type.","Actual value of the field.","Actual byte length of the field.","Expected key type.","Expected value of the field.","Expected byte length of the field.","Field name.","Field name.","","","","","",""],"i":[0,0,27,0,14,21,0,0,21,0,0,13,27,0,21,33,27,27,33,119,119,27,27,33,27,27,13,27,0,0,8,0,8,14,0,0,0,33,0,0,0,8,0,1,119,10,11,12,7,33,27,13,21,14,15,1,6,16,18,10,11,12,7,33,27,13,21,14,15,1,6,16,18,15,15,15,6,11,10,11,12,7,13,14,15,1,6,16,18,10,11,12,7,13,14,15,1,6,16,18,120,16,7,11,12,15,12,7,14,15,1,7,15,12,7,13,14,12,7,13,14,7,10,11,12,7,33,33,27,27,13,13,21,21,14,15,1,6,16,18,10,11,12,7,33,27,13,21,14,14,14,14,15,1,6,16,18,11,12,14,1,6,10,11,12,7,33,27,13,21,14,15,1,6,16,18,1,6,7,0,15,15,11,8,16,11,7,15,1,16,7,15,0,12,7,14,15,7,7,7,8,16,10,1,33,27,21,10,11,12,7,13,14,15,1,6,16,18,33,27,13,21,120,16,10,15,10,11,12,7,33,27,13,21,14,15,1,1,6,16,18,119,10,11,12,7,33,27,13,21,14,15,1,6,16,18,10,11,12,7,33,27,13,21,14,15,1,6,16,18,18,7,120,16,18,120,16,7,120,16,8,16,10,11,12,7,33,27,13,21,14,15,1,6,16,18,15,15,15,15,15,15,121,122,121,122,0,0,0,58,0,0,0,0,0,0,0,0,0,57,57,57,0,0,0,0,0,0,0,0,0,0,0,58,58,0,0,123,124,48,49,50,51,51,52,52,53,53,54,51,52,53,47,51,52,53,55,56,58,47,48,49,50,51,52,53,60,61,62,76,63,77,54,58,80,64,81,55,82,65,57,56,47,48,49,50,51,52,53,60,61,62,76,63,77,54,58,80,64,81,55,82,65,57,56,47,56,47,48,49,50,51,52,53,60,61,62,63,58,64,55,65,57,56,47,48,49,50,51,52,53,60,61,62,63,58,64,55,65,57,56,60,61,62,76,63,77,64,65,56,56,56,56,56,60,61,62,76,63,77,65,47,47,56,56,47,56,57,56,47,51,52,53,55,47,51,52,53,55,57,47,48,49,50,60,61,62,63,58,64,55,57,56,48,49,50,60,61,62,63,58,64,55,57,56,47,48,49,50,51,52,53,60,61,62,76,63,77,54,58,80,80,64,81,81,55,82,82,65,57,56,47,48,49,50,51,51,52,52,53,53,60,61,62,76,63,77,54,58,80,64,81,55,82,65,57,57,57,57,57,56,56,56,56,56,56,57,56,56,56,57,123,124,51,51,52,52,53,53,64,51,52,53,64,60,61,62,63,57,56,47,48,49,50,51,52,53,60,61,62,76,63,77,54,58,80,64,81,55,82,65,57,56,55,57,56,60,61,62,76,63,77,64,65,51,52,53,76,57,56,57,56,57,47,56,56,64,64,64,56,64,64,64,47,60,61,62,76,63,77,64,65,56,56,47,48,49,50,51,52,53,60,61,62,63,58,64,55,65,57,56,57,56,56,55,56,57,80,81,82,124,51,52,53,60,61,62,76,63,77,64,65,47,48,49,50,51,51,52,52,53,53,60,61,62,76,63,77,54,58,58,80,64,81,55,55,55,55,55,55,82,65,57,57,57,56,56,56,48,49,50,54,47,48,49,50,51,52,53,60,61,62,76,63,77,54,58,80,64,81,55,82,65,57,56,47,48,49,50,51,52,53,60,61,62,76,63,77,54,58,80,64,81,55,82,65,57,56,56,60,61,62,76,63,77,64,65,60,61,62,76,63,77,64,65,60,61,62,76,63,77,64,65,57,60,61,62,76,63,77,64,65,47,48,49,50,51,52,53,60,61,62,76,63,77,54,58,80,64,81,55,82,65,57,56,64,63,51,52,53,111,107,102,0,0,107,102,0,111,111,107,102,0,0,107,102,111,111,111,107,111,102,108,109,107,111,102,108,109,107,102,108,109,107,102,108,109,109,109,111,102,108,109,107,102,108,109,107,109,107,107,111,111,102,102,108,109,107,111,102,102,102,102,102,102,102,102,102,102,102,102,108,109,107,107,111,102,108,109,102,102,108,108,108,108,108,108,108,102,108,109,111,102,107,102,108,109,107,111,102,102,107,111,102,108,109,107,111,102,108,109,107,111,102,108,109,107,111,102,108,109,125,126,127,127,127,125,128,126,125,126,125,129,130,131,129,130,131,130,131,0,0,0,0,0,0],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[1,2],[[],[[5,[[4,[3]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,[6,7],0,[[[10,[8,9,9]]],[[10,[8,9,9]]]],[[[11,[9]]],[[11,[9]]]],[12,12],[[[7,[9]]],[[7,[9]]]],[13,13],[14,14],[[[15,[9]]],[[15,[9]]]],[[[1,[9]]],[[1,[9]]]],[[[6,[9,9]]],[[6,[9,9]]]],[[[16,[9]]],[[16,[9]]]],[[[18,[[0,[8,17]]]]],[[18,[[0,[8,17]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],0,[[],11],[[],12],[[],[[15,[23]]]],[24,[[22,[12]]]],[24,[[22,[[7,[25]]]]]],[24,[[22,[14]]]],[24,[[22,[[15,[25]]]]]],[1,[[22,[[7,[26]],27]]]],[[],[[7,[12]]]],[[],15],[[12,12],28],[[[7,[29]],[7,[29]]],28],[[13,13],28],[[14,14],28],[[],28],[[],28],[[],28],[[],28],0,[[[10,[8,30,30]],31],32],[[[11,[30]],31],32],[[12,31],32],[[[7,[30]],31],32],[[33,31],32],[[33,31],32],[[27,31],32],[[27,31],32],[[13,31],32],[[13,31],32],[[21,31],32],[[21,31],32],[[14,31],32],[[[15,[30]],31],32],[[[1,[30]],31],32],[[[6,[30,30]],31],32],[[[16,[30]],31],32],[[[18,[[0,[30,8,17]],30]],31],32],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[2,14],[[]],[20,14],[[[34,[3]]],14],[[]],[[]],[[]],[[]],[[]],[35,11],[[12,36]],[[14,36]],[1,15],[6,15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[1,1],[6],0,0,0,0,0,[[],[[5,[2]]]],[[[16,[8]]],[[5,[2]]]],[[35,37],[[11,[37]]]],[[],7],[[],15],[[[0,[[38,[2]],17]]],[[22,[1,33]]]],[[8,2],[[16,[8]]]],0,0,0,[[12,39],22],[[[7,[19]],39],22],[[14,39],22],[[[15,[19]],39],22],[[7,[11,[37]],35],7],[[7,[11,[37]],35],7],[[7,[41,[40]]],7],[[[4,[3]]]],[[[16,[8]],[4,[3]]]],0,[1,[[4,[3]]]],[33,[[43,[42]]]],[27,[[43,[42]]]],[21,[[43,[42]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],20],[[],20],[[],20],[[],20],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],0,0,[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[2,[[22,[[1,[26]]]]]],[[],22],[[],22],[[],22],[[],22],[[[4,[3]]],44],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[[18,[[0,[8,17]],26]],[1,[9]]],[[22,[[6,[26,9]],27]]]],[[7,[11,[37]]],[[22,[7,27]]]],[1,[[22,[[10,[26]],27]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[18,[[0,[8,17]],26]],[1,[9]]],[[22,[[10,[[0,[8,17]],26,9]],27]]]],[1,[[22,[[6,[26]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[7,[11,[37]]],[[22,[7,27]]]],[[],18],[[],18],[[[4,[3]]],28],[[[16,[8]],[4,[3]]],28],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[15,[46,[14]]],15],[[15,[46,[14]]],15],[[15,[46,[20]]],15],[[15,[46,[20]]],15],[[15,[46,[20]]],15],[[15,[46,[20]]],15],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],[[5,[[4,[3]]]]]],[[],47],[48,[[5,[[4,[3]]]]]],[49,[[5,[[4,[3]]]]]],[50,[[5,[[4,[3]]]]]],[51,47],[51,[[5,[[4,[3]]]]]],[52,47],[52,[[5,[[4,[3]]]]]],[53,47],[53,[[5,[[4,[3]]]]]],[54,[[5,[[4,[3]]]]]],[51,[[4,[3]]]],[52,[[4,[3]]]],[53,[[4,[3]]]],[47,[[4,[3]]]],[51,[[4,[3]]]],[52,[[4,[3]]]],[53,[[4,[3]]]],[55],[56,57],[58,59],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[4,[3]]],47],[56],[47,47],[48,48],[49,49],[50,50],[51,51],[52,52],[53,53],[60,60],[61,61],[62,62],[63,63],[58,58],[64,64],[[[55,[9]]],[[55,[9]]]],[[[65,[9]]],[[65,[9]]]],[57,57],[56,56],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[56,[[43,[66]]]],[56,[[43,[[4,[67]]]]]],[56,66],[[56,68,[4,[3]]],[[22,[[70,[3,69]],71]]]],[[56,72,68,[4,[3]]],[[22,[[70,[3,69]],71]]]],[[],60],[[],61],[[],62],[[],[[76,[[0,[73,74,9,23,75]]]]]],[[],63],[[],77],[[],[[65,[23]]]],[47],[24,[[22,[47]]]],[56,[[43,[66]]]],[56,[[43,[66]]]],[47],[56],[57,66],[56,66],[[],[[79,[78]]]],[[],[[79,[78]]]],[[],[[79,[78]]]],[[],[[79,[78]]]],[[],[[79,[78]]]],[[],[[79,[78]]]],[[],[[79,[78]]]],[[],[[79,[78]]]],[[],[[79,[78]]]],[[],[[79,[78]]]],[[57,72,68,[4,[3]]],[[22,[[70,[3,69]],71]]]],[[47,47],28],[[48,48],28],[[49,49],28],[[50,50],28],[[60,60],28],[[61,61],28],[[62,62],28],[[63,63],28],[[58,58],28],[[64,64],28],[[[55,[29]],[55,[29]]],28],[[57,57],28],[[56,56],28],[[],28],[[],28],[[],28],[[],28],[[],28],[[],28],[[],28],[[],28],[[],28],[[],28],[[],28],[[],28],[[47,31],32],[[48,31],32],[[49,31],32],[[50,31],32],[[51,31],32],[[52,31],32],[[53,31],32],[[60,31],32],[[61,31],32],[[62,31],32],[[[76,[30]],31],32],[[63,31],32],[[77,31],32],[[54,31],32],[[58,31],32],[[80,31],32],[[80,31],32],[[64,31],32],[[81,31],32],[[81,31],32],[[[55,[30]],31],32],[[[82,[30]],31],32],[[82,31],32],[[[65,[30]],31],32],[[57,31],[[22,[83]]]],[[56,31],[[22,[83]]]],[[]],[[]],[[]],[[]],[[]],[[[4,[3]]],51],[[[4,[3]]],52],[[]],[[]],[[[4,[3]]],53],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[56,57],[[[85,[84]]],57],[[[86,[84]]],57],[56,57],[[]],[[[87,[84]]],56],[[[88,[84]]],56],[[]],[[[89,[84]]],56],[[66,66,66,[70,[66,69]]],[[22,[56,71]]]],[[66,66,66],[[22,[56,71]]]],[[[4,[3]]],[[22,[90]]]],[[[4,[3]]],[[22,[90]]]],[[[4,[3]]],[[22,[91]]]],[[[70,[66,69]],66],[[22,[56,71]]]],[[[4,[3]]],[[22,[92]]]],[[[4,[3]]],44],[[[4,[3]]],44],[[[4,[3]]],[[44,[51]]]],[[[4,[3]]],[[44,[51]]]],[[[4,[3]]],[[44,[52]]]],[[[4,[3]]],[[44,[52]]]],[[[4,[3]]],[[44,[53]]]],[[[4,[3]]],[[44,[53]]]],[2,[[22,[64]]]],[[[0,[93,94]]],[[55,[51]]]],[[[0,[93,94]]],[[55,[52]]]],[[[0,[93,94]]],[[55,[53]]]],[[[0,[93,94]],58],95],[[60,36]],[[61,36]],[[62,36]],[[63,36]],[[57,36]],[[56,36]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[55],[57,66],[56,66],[60,[[5,[2]]]],[61,[[5,[2]]]],[62,[[5,[2]]]],[[[76,[[0,[73,74,9,23,75]]]]],[[5,[2]]]],[63,[[5,[2]]]],[77,[[5,[2]]]],[64,[[5,[2]]]],[[[65,[8]]],[[5,[2]]]],[[[38,[[4,[3]]]]],51],[[[38,[[4,[3]]]]],52],[[[38,[[4,[3]]]]],53],[[[97,[96]]],[[76,[[0,[73,74,9,23,75]]]]]],[[66,66],[[22,[57,71]]]],[[[0,[72,17]],59],[[22,[56,71]]]],[[66,66],57],[[[0,[72,17]],59,66],[[22,[56,71]]]],[[66,66,59],[[22,[57,71]]]],[[[70,[3]]],47],[56,[[22,[71]]]],[56,[[4,[66]]]],[[],64],[[],64],[[],64],[56,[[43,[98]]]],[[],64],[[],64],[[],64],[[47,39],22],[[60,[4,[3]]]],[[61,[4,[3]]]],[[62,[4,[3]]]],[[[76,[[0,[73,74,9,23,75]]]],[4,[3]]]],[[63,[4,[3]]]],[[77,[4,[3]]]],[[64,[4,[3]]]],[[[65,[8]],[4,[3]]]],[[56,99,[4,[3]]],[[22,[[70,[3,69]],71]]]],[[56,72,99,[4,[3]]],[[22,[[70,[3,69]],71]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],[[22,[100,90]]]],[[],[[22,[101,90]]]],[56,[[22,[101,91]]]],[[[55,[56]]],[[55,[57]]]],[56,57],[57,[[22,[100,92]]]],[[],20],[[],20],[[],20],[[]],[51,51],[52,52],[53,53],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[[15,[19]],[7,[19]]],[[22,[20,21]]]],[[],22],[[],22],[[],22],[[],22],[102,[[22,[51]]]],[[],22],[102,[[22,[52]]]],[[],22],[[],22],[102,[[22,[53]]]],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[59,[[22,[58]]]],[[],22],[[],22],[[],22],[[],22],[56,[[22,[[55,[56]]]]]],[51,[[22,[[55,[51]]]]]],[53,[[22,[[55,[53]]]]]],[57,[[22,[[55,[57]]]]]],[52,[[22,[[55,[52]]]]]],[[],22],[[],22],[[[105,[103,104]]],[[22,[57,92]]]],[102,[[22,[57]]]],[[],22],[102,[[22,[56]]]],[106,[[22,[56,91]]]],[[],22],[[[4,[3]]],[[44,[48]]]],[[[4,[3]]],[[44,[49]]]],[[[4,[3]]],[[44,[50]]]],[[[4,[3]]],[[44,[54]]]],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[[],45],[56,[[22,[71]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[1,[12]]],[[22,[[10,[26,12]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[[1,[12]]],[[22,[[6,[26,12]],27]]]],[[],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[57,99,[4,[3]],[4,[3]]],[[22,[71]]]],[[60,[4,[3]]],28],[[61,[4,[3]]],28],[[62,[4,[3]]],28],[[[76,[[0,[73,74,9,23,75]]]],[4,[3]]],28],[[63,[4,[3]]],28],[[77,[4,[3]]],28],[[64,[4,[3]]],28],[[[65,[8]],[4,[3]]],28],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[2,64],[[],[[16,[63]]]],[51],[52],[53],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[107,107],[102,102],[108,108],[109,109],[[]],[[]],[[]],[[]],0,0,[[[46,[110]]],111],[24,[[22,[102]]]],[24,[[22,[108]]]],[24,[[22,[109]]]],[[107,107],28],[[102,102],28],[[108,108],28],[[109,109],28],[[],28],0,[[107,31],32],[[107,31],32],[[111,31],32],[[111,31],32],[[102,31],32],[[102,31],32],[[108,31],32],[[109,31],32],[[]],[[]],[112,102],[57,102],[56,102],[[]],[113,102],[114,102],[53,102],[115,102],[51,102],[116,102],[52,102],[117,102],[[]],[[]],[[107,36]],[[]],[[]],[[]],[[]],[[]],[102,28],[102,107],0,0,0,0,0,0,0,[[102,39],22],[[108,39],22],[[109,39],22],[111,[[43,[42]]]],[102,[[118,[84]]]],[[]],[[]],[[]],[[]],[[],20],[[],20],[[],20],[102,102],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],22],[[],45],[[],45],[[],45],[[],45],[[],45],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"c":[272,275],"p":[[3,"UntrustedToken",0],[15,"str"],[15,"u8"],[15,"slice"],[4,"Cow",986],[3,"Token",0],[3,"Claims",0],[8,"Algorithm",0],[8,"Clone",987],[3,"SignedToken",0],[3,"TimeOptions",0],[3,"Empty",0],[4,"Claim",0],[4,"Thumbprint",0],[3,"Header",0],[3,"Renamed",0],[8,"Sized",988],[3,"Validator",0],[8,"Serialize",989],[3,"String",990],[4,"CreationError",0],[4,"Result",991],[8,"Default",992],[8,"Deserializer",993],[8,"Deserialize",993],[8,"DeserializeOwned",993],[4,"ValidationError",0],[15,"bool"],[8,"PartialEq",994],[8,"Debug",995],[3,"Formatter",995],[6,"Result",995],[4,"ParseError",0],[15,"array"],[3,"Duration",996],[8,"Hasher",997],[8,"Fn",998],[8,"AsRef",999],[8,"Serializer",989],[3,"Utc",1000],[3,"DateTime",1001],[8,"Error",1002],[4,"Option",1003],[6,"Result",1004],[3,"TypeId",1005],[8,"Into",999],[3,"SecretBytes",306],[3,"Hs256Signature",306],[3,"Hs384Signature",306],[3,"Hs512Signature",306],[3,"Hs256Key",306],[3,"Hs384Key",306],[3,"Hs512Key",306],[3,"RsaSignature",306],[3,"StrongKey",306],[3,"RsaPrivateKey",306],[3,"RsaPublicKey",306],[4,"ModulusBits",306],[15,"usize"],[3,"Hs256",306],[3,"Hs384",306],[3,"Hs512",306],[3,"Ed25519",306],[3,"Rsa",306],[3,"StrongAlg",306],[3,"BigUint",1006],[3,"CrtValue",1007],[8,"PaddingScheme",1008],[3,"Global",1009],[3,"Vec",1010],[4,"Error",1011],[8,"CryptoRngCore",1012],[8,"FixedOutputReset",1013],[8,"BlockSizeUser",1014],[8,"HashMarker",1015],[3,"Es256k",306],[3,"Es256",306],[15,"char"],[8,"FromIterator",1016],[3,"ModulusBitsError",306],[3,"RsaParseError",306],[3,"WeakKeyError",306],[3,"Error",995],[8,"Digest",1015],[3,"VerifyingKey",1017],[3,"VerifyingKey",1018],[3,"SigningKey",1019],[3,"SigningKey",1020],[3,"BlindedSigningKey",1021],[4,"Error",1022],[4,"Error",1023],[4,"Error",1024],[8,"CryptoRng",1012],[8,"RngCore",1012],[6,"Result",1011],[4,"All",1025],[3,"Secp256k1",1026],[3,"BigInt",1027],[8,"SignatureScheme",1008],[3,"Document",1028],[3,"SecretDocument",1028],[4,"JsonWebKey",840],[3,"AnyRef",1029],[3,"BitStringRef",1030],[3,"SubjectPublicKeyInfo",1031],[3,"PrivateKeyInfo",1032],[4,"KeyType",840],[3,"RsaPrivateParts",840],[3,"RsaPrimeFactor",840],[3,"Error",1004],[4,"JwkError",840],[3,"SecretKey",1033],[6,"SigningKey",1034],[3,"PublicKey",1033],[3,"PublicKey",1035],[6,"VerifyingKey",1034],[3,"SecretKey",1035],[6,"Output",1014],[8,"AlgorithmSignature",0],[8,"AlgorithmExt",0],[13,"AlgorithmMismatch",302],[13,"InvalidSignatureLen",302],[8,"VerifyingKey",306],[8,"SigningKey",306],[13,"EllipticCurve",961],[13,"KeyPair",961],[13,"Rsa",961],[13,"Symmetric",961],[13,"UnexpectedKeyType",972],[13,"UnexpectedValue",972],[13,"UnexpectedLen",972]]}\ +}'); +if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; +if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; diff --git a/settings.html b/settings.html new file mode 100644 index 00000000..88cede9c --- /dev/null +++ b/settings.html @@ -0,0 +1 @@ +Rustdoc settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/src-files.js b/src-files.js new file mode 100644 index 00000000..97649e5a --- /dev/null +++ b/src-files.js @@ -0,0 +1,4 @@ +var srcIndex = JSON.parse('{\ +"jwt_compact":["",[["alg",[],["eddsa_sodium.rs","es256k.rs","generic.rs","hmacs.rs","p256.rs","rsa.rs"]]],["alg.rs","claims.rs","error.rs","jwk.rs","lib.rs","token.rs","traits.rs"]]\ +}'); +createSrcSidebar(); diff --git a/src/jwt_compact/alg.rs.html b/src/jwt_compact/alg.rs.html new file mode 100644 index 00000000..5fa94c25 --- /dev/null +++ b/src/jwt_compact/alg.rs.html @@ -0,0 +1,305 @@ +alg.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+
//! Implementations of JWT signing / verification algorithms. Also contains generic traits
+//! for signing and verifying keys.
+
+use core::fmt;
+
+use crate::{alloc::Cow, Algorithm};
+
+mod generic;
+mod hmacs;
+// Alternative ES256K implementations.
+#[cfg(feature = "secp256k1")]
+mod es256k;
+#[cfg(feature = "k256")]
+mod k256;
+// Alternative EdDSA implementations.
+#[cfg(feature = "ed25519-compact")]
+mod eddsa_compact;
+#[cfg(feature = "ed25519-dalek")]
+mod eddsa_dalek;
+#[cfg(feature = "exonum-crypto")]
+mod eddsa_sodium;
+// ES256 implemenation.
+#[cfg(feature = "p256")]
+mod p256;
+// RSA implementation.
+#[cfg(feature = "rsa")]
+mod rsa;
+
+#[cfg(feature = "ed25519-compact")]
+pub use self::eddsa_compact::*;
+#[cfg(feature = "ed25519-dalek")]
+pub use self::eddsa_dalek::Ed25519;
+#[cfg(feature = "exonum-crypto")]
+pub use self::eddsa_sodium::Ed25519;
+#[cfg(feature = "es256k")]
+pub use self::es256k::Es256k;
+pub use self::generic::{SecretBytes, SigningKey, VerifyingKey};
+pub use self::hmacs::*;
+#[cfg(feature = "k256")]
+pub use self::k256::Es256k;
+#[cfg(feature = "p256")]
+pub use self::p256::Es256;
+#[cfg(feature = "rsa")]
+#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
+pub use self::rsa::{
+    ModulusBits, ModulusBitsError, Rsa, RsaParseError, RsaPrivateKey, RsaPublicKey, RsaSignature,
+};
+
+/// Wrapper around keys allowing to enforce key strength requirements.
+///
+/// The wrapper signifies that the key has supported strength as per the corresponding
+/// algorithm spec. For example, RSA keys must have length at least 2,048 bits per [RFC 7518].
+/// Likewise, `HS*` keys must have at least the length of the hash output
+/// (e.g., 32 bytes for `HS256`). Since these requirements sometimes clash with backward
+/// compatibility (and sometimes a lesser level of security is enough),
+/// notion of key strength is implemented in such an opt-in, composable way.
+///
+/// It's easy to convert a `StrongKey<T>` to `T` via [`into_inner()`](Self::into_inner()) or to
+/// access `&T` via `AsRef` impl. In contrast, the reverse transformation is fallible, and
+/// is defined with the help of [`TryFrom`]. The error type for `TryFrom` is [`WeakKeyError`],
+/// a simple wrapper around a weak key.
+///
+/// # Examples
+///
+/// See [`StrongAlg`] docs for an example of usage.
+///
+/// [RFC 7518]: https://www.rfc-editor.org/rfc/rfc7518.html
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct StrongKey<T>(T);
+
+impl<T> StrongKey<T> {
+    /// Returns the wrapped value.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<T> AsRef<T> for StrongKey<T> {
+    fn as_ref(&self) -> &T {
+        &self.0
+    }
+}
+
+/// Error type used for fallible conversion into a [`StrongKey`].
+///
+/// The error wraps around a weak key, which can be extracted for further use.
+#[derive(Debug)]
+pub struct WeakKeyError<T>(pub T);
+
+impl<T> fmt::Display for WeakKeyError<T> {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        formatter.write_str("Weak cryptographic key")
+    }
+}
+
+#[cfg(feature = "std")]
+impl<T: fmt::Debug + 'static> std::error::Error for WeakKeyError<T> {}
+
+/// Wrapper around a JWT algorithm signalling that it supports only [`StrongKey`]s.
+///
+/// The wrapper will implement `Algorithm` if the wrapped value is an `Algorithm` with both
+/// signing and verifying keys convertible to `StrongKey`s.
+///
+/// # Examples
+///
+/// ```
+/// # use rand::thread_rng;
+/// # use jwt_compact::{prelude::*, alg::{Hs256, Hs256Key, StrongAlg, StrongKey}};
+/// # fn main() -> anyhow::Result<()> {
+/// let weak_key = Hs256Key::new(b"too short!");
+/// assert!(StrongKey::try_from(weak_key).is_err());
+/// // There is no way to create a `StrongKey` from `weak_key`!
+///
+/// let strong_key: StrongKey<_> = Hs256Key::generate(&mut thread_rng());
+/// let claims = // ...
+/// #   Claims::empty();
+/// let token = StrongAlg(Hs256)
+///     .token(&Header::empty(), &claims, &strong_key)?;
+/// # Ok(())
+/// # }
+/// ```
+#[derive(Debug, Clone, Copy, Default)]
+pub struct StrongAlg<T>(pub T);
+
+#[allow(clippy::trait_duplication_in_bounds)] // false positive
+impl<T: Algorithm> Algorithm for StrongAlg<T>
+where
+    StrongKey<T::SigningKey>: TryFrom<T::SigningKey>,
+    StrongKey<T::VerifyingKey>: TryFrom<T::VerifyingKey>,
+{
+    type SigningKey = StrongKey<T::SigningKey>;
+    type VerifyingKey = StrongKey<T::VerifyingKey>;
+    type Signature = T::Signature;
+
+    fn name(&self) -> Cow<'static, str> {
+        self.0.name()
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        self.0.sign(&signing_key.0, message)
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        self.0
+            .verify_signature(signature, &verifying_key.0, message)
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/alg/eddsa_sodium.rs.html b/src/jwt_compact/alg/eddsa_sodium.rs.html new file mode 100644 index 00000000..e4314407 --- /dev/null +++ b/src/jwt_compact/alg/eddsa_sodium.rs.html @@ -0,0 +1,315 @@ +eddsa_sodium.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+
//! `EdDSA` algorithm implementation using the `exonum-crypto` crate.
+
+use anyhow::format_err;
+use exonum_crypto::{
+    gen_keypair_from_seed, sign, verify, PublicKey, SecretKey, Seed, Signature, PUBLIC_KEY_LENGTH,
+    SEED_LENGTH, SIGNATURE_LENGTH,
+};
+
+use core::num::NonZeroUsize;
+
+use crate::{
+    alg::{SecretBytes, SigningKey, VerifyingKey},
+    alloc::Cow,
+    jwk::{JsonWebKey, JwkError, KeyType},
+    Algorithm, AlgorithmSignature, Renamed,
+};
+
+impl AlgorithmSignature for Signature {
+    const LENGTH: Option<NonZeroUsize> = NonZeroUsize::new(SIGNATURE_LENGTH);
+
+    fn try_from_slice(bytes: &[u8]) -> anyhow::Result<Self> {
+        // There are no checks other than by signature length in `from_slice`,
+        // so the `unwrap()` below is safe.
+        Ok(Self::from_slice(bytes).unwrap())
+    }
+
+    fn as_bytes(&self) -> Cow<'_, [u8]> {
+        Cow::Borrowed(self.as_ref())
+    }
+}
+
+/// Integrity algorithm using digital signatures on the Ed25519 elliptic curve.
+///
+/// The name of the algorithm is specified as `EdDSA` as per [IANA registry].
+/// Use `with_specific_name()` to switch to non-standard `Ed25519`.
+///
+/// [IANA registry]: https://www.iana.org/assignments/jose/jose.xhtml
+#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
+#[cfg_attr(
+    docsrs,
+    doc(cfg(any(
+        feature = "exonum-crypto",
+        feature = "ed25519-dalek",
+        feature = "ed25519-compact"
+    )))
+)]
+pub struct Ed25519;
+
+impl Ed25519 {
+    /// Creates an algorithm instance with the algorithm name specified as `Ed25519`.
+    /// This is a non-standard name, but it is used in some apps.
+    pub fn with_specific_name() -> Renamed<Self> {
+        Renamed::new(Self, "Ed25519")
+    }
+}
+
+impl Algorithm for Ed25519 {
+    type SigningKey = SecretKey;
+    type VerifyingKey = PublicKey;
+    type Signature = Signature;
+
+    fn name(&self) -> Cow<'static, str> {
+        Cow::Borrowed("EdDSA")
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        sign(message, signing_key)
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        verify(signature, message, verifying_key)
+    }
+}
+
+impl VerifyingKey<Ed25519> for PublicKey {
+    fn from_slice(raw: &[u8]) -> anyhow::Result<Self> {
+        Self::from_slice(raw).ok_or_else(|| format_err!("Invalid public key length"))
+    }
+
+    fn as_bytes(&self) -> Cow<'_, [u8]> {
+        Cow::Borrowed(self.as_ref())
+    }
+}
+
+impl SigningKey<Ed25519> for SecretKey {
+    fn from_slice(raw: &[u8]) -> anyhow::Result<Self> {
+        Self::from_slice(raw).ok_or_else(|| format_err!("Invalid secret key bytes"))
+    }
+
+    fn to_verifying_key(&self) -> PublicKey {
+        // Slightly hacky. The backend does not expose functions for converting secret keys
+        // to public ones, and we don't want to use `KeyPair` instead of `SecretKey`
+        // for this single purpose.
+        PublicKey::from_slice(&self[SEED_LENGTH..]).unwrap()
+    }
+
+    fn as_bytes(&self) -> SecretBytes<'_> {
+        SecretBytes::borrowed(&self[..])
+    }
+}
+
+impl<'a> From<&'a PublicKey> for JsonWebKey<'a> {
+    fn from(key: &'a PublicKey) -> JsonWebKey<'a> {
+        JsonWebKey::KeyPair {
+            curve: Cow::Borrowed("Ed25519"),
+            x: Cow::Borrowed(key.as_ref()),
+            secret: None,
+        }
+    }
+}
+
+impl TryFrom<&JsonWebKey<'_>> for PublicKey {
+    type Error = JwkError;
+
+    fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+        let JsonWebKey::KeyPair { curve, x, .. } = jwk else {
+            return Err(JwkError::key_type(jwk, KeyType::KeyPair));
+        };
+
+        JsonWebKey::ensure_curve(curve, "Ed25519")?;
+        JsonWebKey::ensure_len("x", x, PUBLIC_KEY_LENGTH)?;
+        Ok(PublicKey::from_slice(x).unwrap())
+        // ^ unlike some other impls, libsodium does not check public key validity on creation
+    }
+}
+
+impl<'a> From<&'a SecretKey> for JsonWebKey<'a> {
+    fn from(key: &'a SecretKey) -> JsonWebKey<'a> {
+        JsonWebKey::KeyPair {
+            curve: Cow::Borrowed("Ed25519"),
+            x: Cow::Borrowed(&key[SEED_LENGTH..]),
+            secret: Some(SecretBytes::borrowed(&key[..SEED_LENGTH])),
+        }
+    }
+}
+
+impl TryFrom<&JsonWebKey<'_>> for SecretKey {
+    type Error = JwkError;
+
+    fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+        let JsonWebKey::KeyPair { secret, .. } = jwk else {
+            return Err(JwkError::key_type(jwk, KeyType::KeyPair));
+        };
+        let seed_bytes = secret.as_deref();
+        let seed_bytes = seed_bytes.ok_or_else(|| JwkError::NoField("d".to_owned()))?;
+
+        JsonWebKey::ensure_len("d", seed_bytes, SEED_LENGTH)?;
+        let seed = Seed::from_slice(seed_bytes).unwrap();
+        let (_, sk) = gen_keypair_from_seed(&seed);
+        jwk.ensure_key_match(sk)
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/alg/es256k.rs.html b/src/jwt_compact/alg/es256k.rs.html new file mode 100644 index 00000000..240d6a91 --- /dev/null +++ b/src/jwt_compact/alg/es256k.rs.html @@ -0,0 +1,423 @@ +es256k.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+
//! `ES256K` algorithm implementation using the `secp256k1` crate.
+
+use lazy_static::lazy_static;
+use secp256k1::{
+    constants::{
+        COMPACT_SIGNATURE_SIZE, FIELD_SIZE, SECRET_KEY_SIZE, UNCOMPRESSED_PUBLIC_KEY_SIZE,
+    },
+    ecdsa::Signature,
+    All, Message, PublicKey, Secp256k1, SecretKey,
+};
+use sha2::{
+    digest::{
+        crypto_common::BlockSizeUser, generic_array::typenum::U32, FixedOutputReset, HashMarker,
+    },
+    Digest, Sha256,
+};
+
+use core::{marker::PhantomData, num::NonZeroUsize};
+
+use crate::{
+    alg::{SecretBytes, SigningKey, VerifyingKey},
+    alloc::Cow,
+    jwk::{JsonWebKey, JwkError, KeyType},
+    Algorithm, AlgorithmSignature,
+};
+
+/// Byte size of a serialized EC coordinate.
+const COORDINATE_SIZE: usize = FIELD_SIZE.len();
+
+impl AlgorithmSignature for Signature {
+    const LENGTH: Option<NonZeroUsize> = NonZeroUsize::new(COMPACT_SIGNATURE_SIZE);
+
+    fn try_from_slice(slice: &[u8]) -> anyhow::Result<Self> {
+        Signature::from_compact(slice).map_err(Into::into)
+    }
+
+    fn as_bytes(&self) -> Cow<'_, [u8]> {
+        Cow::Owned(self.serialize_compact()[..].to_vec())
+    }
+}
+
+/// Algorithm implementing elliptic curve digital signatures (ECDSA) on the secp256k1 curve.
+///
+/// The algorithm does not fix the choice of the message digest algorithm; instead,
+/// it is provided as a type parameter. SHA-256 is the default parameter value,
+/// but it can be set to any cryptographically secure hash function with 32-byte output
+/// (e.g., SHA3-256).
+#[derive(Debug)]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "es256k", feature = "k256"))))]
+pub struct Es256k<D = Sha256> {
+    context: Secp256k1<All>,
+    _digest: PhantomData<D>,
+}
+
+impl<D> Default for Es256k<D>
+where
+    D: FixedOutputReset<OutputSize = U32> + BlockSizeUser + Clone + Default + HashMarker,
+{
+    fn default() -> Self {
+        Es256k {
+            context: Secp256k1::new(),
+            _digest: PhantomData,
+        }
+    }
+}
+
+impl<D> Es256k<D>
+where
+    D: FixedOutputReset<OutputSize = U32> + BlockSizeUser + Clone + Default + HashMarker,
+{
+    /// Creates a new algorithm instance.
+    /// This is a (moderately) expensive operation, so if necessary, the algorithm should
+    /// be `clone()`d rather than created anew.
+    #[cfg_attr(docsrs, doc(cfg(feature = "es256k")))]
+    pub fn new(context: Secp256k1<All>) -> Self {
+        Es256k {
+            context,
+            _digest: PhantomData,
+        }
+    }
+}
+
+impl<D> Algorithm for Es256k<D>
+where
+    D: FixedOutputReset<OutputSize = U32> + BlockSizeUser + Clone + Default + HashMarker,
+{
+    type SigningKey = SecretKey;
+    type VerifyingKey = PublicKey;
+    type Signature = Signature;
+
+    fn name(&self) -> Cow<'static, str> {
+        Cow::Borrowed("ES256K")
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        let mut digest = D::default();
+        digest.update(message);
+        let message = Message::from_digest(digest.finalize().into());
+
+        self.context.sign_ecdsa(&message, signing_key)
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        let mut digest = D::default();
+        digest.update(message);
+        let message = Message::from_digest(digest.finalize().into());
+
+        // Some implementations (e.g., OpenSSL) produce high-S signatures, which
+        // are considered invalid by this implementation. Hence, we perform normalization here.
+        //
+        // See also: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
+        let mut normalized_signature = *signature;
+        normalized_signature.normalize_s();
+
+        self.context
+            .verify_ecdsa(&message, &normalized_signature, verifying_key)
+            .is_ok()
+    }
+}
+
+/// This implementation initializes a `libsecp256k1` context once on the first call to
+/// `to_verifying_key` if it was not initialized previously.
+impl SigningKey<Es256k> for SecretKey {
+    fn from_slice(raw: &[u8]) -> anyhow::Result<Self> {
+        Self::from_slice(raw).map_err(From::from)
+    }
+
+    fn to_verifying_key(&self) -> PublicKey {
+        lazy_static! {
+            static ref CONTEXT: Secp256k1<All> = Secp256k1::new();
+        }
+        PublicKey::from_secret_key(&CONTEXT, self)
+    }
+
+    fn as_bytes(&self) -> SecretBytes<'_> {
+        SecretBytes::borrowed(&self[..])
+    }
+}
+
+impl VerifyingKey<Es256k> for PublicKey {
+    fn from_slice(raw: &[u8]) -> anyhow::Result<Self> {
+        Self::from_slice(raw).map_err(From::from)
+    }
+
+    /// Serializes the key as a 33-byte compressed form, as per [`Self::serialize()`].
+    fn as_bytes(&self) -> Cow<'_, [u8]> {
+        Cow::Owned(self.serialize().to_vec())
+    }
+}
+
+fn create_jwk<'a>(pk: &PublicKey, sk: Option<&'a SecretKey>) -> JsonWebKey<'a> {
+    let uncompressed = pk.serialize_uncompressed();
+    JsonWebKey::EllipticCurve {
+        curve: "secp256k1".into(),
+        x: Cow::Owned(uncompressed[1..=COORDINATE_SIZE].to_vec()),
+        y: Cow::Owned(uncompressed[(1 + COORDINATE_SIZE)..].to_vec()),
+        secret: sk.map(|sk| SecretBytes::borrowed(&sk.as_ref()[..])),
+    }
+}
+
+impl<'a> From<&'a PublicKey> for JsonWebKey<'a> {
+    fn from(key: &'a PublicKey) -> JsonWebKey<'a> {
+        create_jwk(key, None)
+    }
+}
+
+impl TryFrom<&JsonWebKey<'_>> for PublicKey {
+    type Error = JwkError;
+
+    fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+        let JsonWebKey::EllipticCurve { curve, x, y, .. } = jwk else {
+            return Err(JwkError::key_type(jwk, KeyType::EllipticCurve));
+        };
+        JsonWebKey::ensure_curve(curve, "secp256k1")?;
+        JsonWebKey::ensure_len("x", x, COORDINATE_SIZE)?;
+        JsonWebKey::ensure_len("y", y, COORDINATE_SIZE)?;
+
+        let mut key_bytes = [0_u8; UNCOMPRESSED_PUBLIC_KEY_SIZE];
+        key_bytes[0] = 4; // uncompressed key marker
+        key_bytes[1..=COORDINATE_SIZE].copy_from_slice(x);
+        key_bytes[(1 + COORDINATE_SIZE)..].copy_from_slice(y);
+        PublicKey::from_slice(&key_bytes[..]).map_err(JwkError::custom)
+    }
+}
+
+impl<'a> From<&'a SecretKey> for JsonWebKey<'a> {
+    fn from(key: &'a SecretKey) -> JsonWebKey<'a> {
+        create_jwk(&key.to_verifying_key(), Some(key))
+    }
+}
+
+impl TryFrom<&JsonWebKey<'_>> for SecretKey {
+    type Error = JwkError;
+
+    fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+        let JsonWebKey::EllipticCurve { secret, .. } = jwk else {
+            return Err(JwkError::key_type(jwk, KeyType::EllipticCurve));
+        };
+        let sk_bytes = secret.as_deref();
+        let sk_bytes = sk_bytes.ok_or_else(|| JwkError::NoField("d".into()))?;
+        JsonWebKey::ensure_len("d", sk_bytes, SECRET_KEY_SIZE)?;
+
+        let sk = SecretKey::from_slice(sk_bytes).map_err(JwkError::custom)?;
+        jwk.ensure_key_match(sk)
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/alg/generic.rs.html b/src/jwt_compact/alg/generic.rs.html new file mode 100644 index 00000000..241964e6 --- /dev/null +++ b/src/jwt_compact/alg/generic.rs.html @@ -0,0 +1,245 @@ +generic.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+
//! Generic traits providing uniform interfaces for a certain cryptosystem
+//! across different backends.
+
+use zeroize::Zeroize;
+
+use core::{fmt, ops};
+
+use crate::{
+    alloc::{Cow, Vec},
+    Algorithm,
+};
+
+/// Verifying key for a specific signature cryptosystem. In the case of public-key cryptosystems,
+/// this is a public key.
+///
+/// This trait provides a uniform interface for different backends / implementations
+/// of the same cryptosystem.
+pub trait VerifyingKey<T>: Sized
+where
+    T: Algorithm<VerifyingKey = Self>,
+{
+    /// Creates a key from `raw` bytes. Returns an error if the bytes do not represent
+    /// a valid key.
+    fn from_slice(raw: &[u8]) -> anyhow::Result<Self>;
+
+    /// Returns the key as raw bytes.
+    ///
+    /// Implementations should return `Cow::Borrowed` whenever possible (that is, if the bytes
+    /// are actually stored within the implementing data structure).
+    fn as_bytes(&self) -> Cow<'_, [u8]>;
+}
+
+/// Signing key for a specific signature cryptosystem. In the case of public-key cryptosystems,
+/// this is a private key.
+///
+/// This trait provides a uniform interface for different backends / implementations
+/// of the same cryptosystem.
+pub trait SigningKey<T>: Sized
+where
+    T: Algorithm<SigningKey = Self>,
+{
+    /// Creates a key from `raw` bytes. Returns an error if the bytes do not represent
+    /// a valid key.
+    fn from_slice(raw: &[u8]) -> anyhow::Result<Self>;
+
+    /// Converts a signing key to a verification key.
+    fn to_verifying_key(&self) -> T::VerifyingKey;
+
+    /// Returns the key as raw bytes.
+    ///
+    /// Implementations should return `Cow::Borrowed` whenever possible (that is, if the bytes
+    /// are actually stored within the implementing data structure).
+    fn as_bytes(&self) -> SecretBytes<'_>;
+}
+
+/// Generic container for secret bytes, which can be either owned or borrowed.
+/// If owned, bytes are zeroized on drop.
+///
+/// Comparisons on `SecretBytes` are constant-time, but other operations (e.g., deserialization)
+/// may be var-time.
+///
+/// # Serialization
+///
+/// Represented in human-readable formats (JSON, TOML, YAML, etc.) as a base64-url encoded string
+/// with no padding. For other formats (e.g., CBOR), `SecretBytes` will be serialized directly
+/// as a byte sequence.
+#[derive(Clone)]
+pub struct SecretBytes<'a>(Cow<'a, [u8]>);
+
+impl<'a> SecretBytes<'a> {
+    pub(crate) fn new(inner: Cow<'a, [u8]>) -> Self {
+        Self(inner)
+    }
+
+    /// Creates secret bytes from a borrowed slice.
+    pub fn borrowed(bytes: &'a [u8]) -> Self {
+        Self(Cow::Borrowed(bytes))
+    }
+
+    /// Creates secret bytes from an owned `Vec`.
+    pub fn owned(bytes: Vec<u8>) -> Self {
+        Self(Cow::Owned(bytes))
+    }
+}
+
+impl fmt::Debug for SecretBytes<'_> {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        formatter
+            .debug_struct("SecretBytes")
+            .field("len", &self.0.len())
+            .finish()
+    }
+}
+
+impl Drop for SecretBytes<'_> {
+    fn drop(&mut self) {
+        // if bytes are borrowed, we don't need to perform any special cleaning.
+        if let Cow::Owned(bytes) = &mut self.0 {
+            Zeroize::zeroize(bytes);
+        }
+    }
+}
+
+impl ops::Deref for SecretBytes<'_> {
+    type Target = [u8];
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl AsRef<[u8]> for SecretBytes<'_> {
+    fn as_ref(&self) -> &[u8] {
+        self
+    }
+}
+
+impl PartialEq for SecretBytes<'_> {
+    fn eq(&self, other: &Self) -> bool {
+        subtle::ConstantTimeEq::ct_eq(self.as_ref(), other.as_ref()).into()
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/alg/hmacs.rs.html b/src/jwt_compact/alg/hmacs.rs.html new file mode 100644 index 00000000..7d73cef3 --- /dev/null +++ b/src/jwt_compact/alg/hmacs.rs.html @@ -0,0 +1,583 @@ +hmacs.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+
//! JWT algorithms based on HMACs.
+
+use hmac::digest::generic_array::{typenum::Unsigned, GenericArray};
+use hmac::{digest::CtOutput, Hmac, Mac as _};
+use rand_core::{CryptoRng, RngCore};
+use sha2::{
+    digest::{core_api::BlockSizeUser, OutputSizeUser},
+    Sha256, Sha384, Sha512,
+};
+use smallvec::{smallvec, SmallVec};
+use zeroize::Zeroize;
+
+use core::{fmt, num::NonZeroUsize};
+
+use crate::{
+    alg::{SecretBytes, SigningKey, StrongKey, VerifyingKey, WeakKeyError},
+    alloc::Cow,
+    jwk::{JsonWebKey, JwkError, KeyType},
+    Algorithm, AlgorithmSignature,
+};
+
+macro_rules! define_hmac_signature {
+    (
+        $(#[$($attr:meta)+])*
+        struct $name:ident<$digest:ident>;
+    ) => {
+        $(#[$($attr)+])*
+        #[derive(Clone, PartialEq, Eq)]
+        pub struct $name(CtOutput<Hmac<$digest>>);
+
+        impl fmt::Debug for $name {
+            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                formatter.debug_tuple(stringify!($name)).field(&"_").finish()
+            }
+        }
+
+        impl AlgorithmSignature for $name {
+            const LENGTH: Option<NonZeroUsize> =
+                NonZeroUsize::new(<$digest as OutputSizeUser>::OutputSize::USIZE);
+
+            fn try_from_slice(bytes: &[u8]) -> anyhow::Result<Self> {
+                let bytes = GenericArray::clone_from_slice(bytes);
+                Ok(Self(CtOutput::new(bytes)))
+            }
+
+            fn as_bytes(&self) -> Cow<'_, [u8]> {
+                Cow::Owned(self.0.clone().into_bytes().to_vec())
+            }
+        }
+    };
+}
+
+define_hmac_signature!(
+    /// Signature produced by the [`Hs256`] algorithm.
+    struct Hs256Signature<Sha256>;
+);
+define_hmac_signature!(
+    /// Signature produced by the [`Hs384`] algorithm.
+    struct Hs384Signature<Sha384>;
+);
+define_hmac_signature!(
+    /// Signature produced by the [`Hs512`] algorithm.
+    struct Hs512Signature<Sha512>;
+);
+
+macro_rules! define_hmac_key {
+    (
+        $(#[$($attr:meta)+])*
+        struct $name:ident<$digest:ident>([u8; $buffer_size:expr]);
+    ) => {
+        $(#[$($attr)+])*
+        #[derive(Clone, Zeroize)]
+        #[zeroize(drop)]
+        pub struct $name(pub(crate) SmallVec<[u8; $buffer_size]>);
+
+        impl fmt::Debug for $name {
+            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                formatter.debug_tuple(stringify!($name)).field(&"_").finish()
+            }
+        }
+
+        impl $name {
+            /// Generates a random key using a cryptographically secure RNG.
+            pub fn generate<R: CryptoRng + RngCore>(rng: &mut R) -> StrongKey<Self> {
+                let mut key = $name(smallvec![0; <$digest as BlockSizeUser>::BlockSize::to_usize()]);
+                rng.fill_bytes(&mut key.0);
+                StrongKey(key)
+            }
+
+            /// Creates a key from the specified `bytes`.
+            pub fn new(bytes: impl AsRef<[u8]>) -> Self {
+                Self(bytes.as_ref().into())
+            }
+
+            /// Computes HMAC with this key and the specified `message`.
+            fn hmac(&self, message: impl AsRef<[u8]>) -> CtOutput<Hmac<$digest>> {
+                let mut hmac = Hmac::<$digest>::new_from_slice(&self.0)
+                    .expect("HMACs work with any key size");
+                hmac.update(message.as_ref());
+                hmac.finalize()
+            }
+        }
+
+        impl From<&[u8]> for $name {
+            fn from(bytes: &[u8]) -> Self {
+                $name(bytes.into())
+            }
+        }
+
+        impl AsRef<[u8]> for $name {
+            fn as_ref(&self) -> &[u8] {
+                &self.0
+            }
+        }
+
+        impl AsMut<[u8]> for $name {
+            fn as_mut(&mut self) -> &mut [u8] {
+                &mut self.0
+            }
+        }
+
+        impl TryFrom<$name> for StrongKey<$name> {
+            type Error = WeakKeyError<$name>;
+
+            fn try_from(value: $name) -> Result<Self, Self::Error> {
+                if value.0.len() >= <$digest as BlockSizeUser>::BlockSize::to_usize() {
+                    Ok(StrongKey(value))
+                } else {
+                    Err(WeakKeyError(value))
+                }
+            }
+        }
+    };
+}
+
+define_hmac_key! {
+    /// Signing / verifying key for `HS256` algorithm. Zeroed on drop.
+    struct Hs256Key<Sha256>([u8; 64]);
+}
+define_hmac_key! {
+    /// Signing / verifying key for `HS384` algorithm. Zeroed on drop.
+    struct Hs384Key<Sha384>([u8; 128]);
+}
+define_hmac_key! {
+    /// Signing / verifying key for `HS512` algorithm. Zeroed on drop.
+    struct Hs512Key<Sha512>([u8; 128]);
+}
+
+/// `HS256` signing algorithm.
+///
+/// See [RFC 7518] for the algorithm specification.
+///
+/// [RFC 7518]: https://tools.ietf.org/html/rfc7518#section-3.2
+#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
+pub struct Hs256;
+
+impl Algorithm for Hs256 {
+    type SigningKey = Hs256Key;
+    type VerifyingKey = Hs256Key;
+    type Signature = Hs256Signature;
+
+    fn name(&self) -> Cow<'static, str> {
+        Cow::Borrowed("HS256")
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        Hs256Signature(signing_key.hmac(message))
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        verifying_key.hmac(message) == signature.0
+    }
+}
+
+/// `HS384` signing algorithm.
+///
+/// See [RFC 7518] for the algorithm specification.
+///
+/// [RFC 7518]: https://tools.ietf.org/html/rfc7518#section-3.2
+#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
+pub struct Hs384;
+
+impl Algorithm for Hs384 {
+    type SigningKey = Hs384Key;
+    type VerifyingKey = Hs384Key;
+    type Signature = Hs384Signature;
+
+    fn name(&self) -> Cow<'static, str> {
+        Cow::Borrowed("HS384")
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        Hs384Signature(signing_key.hmac(message))
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        verifying_key.hmac(message) == signature.0
+    }
+}
+
+/// `HS512` signing algorithm.
+///
+/// See [RFC 7518] for the algorithm specification.
+///
+/// [RFC 7518]: https://tools.ietf.org/html/rfc7518#section-3.2
+#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
+pub struct Hs512;
+
+impl Algorithm for Hs512 {
+    type SigningKey = Hs512Key;
+    type VerifyingKey = Hs512Key;
+    type Signature = Hs512Signature;
+
+    fn name(&self) -> Cow<'static, str> {
+        Cow::Borrowed("HS512")
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        Hs512Signature(signing_key.hmac(message))
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        verifying_key.hmac(message) == signature.0
+    }
+}
+
+macro_rules! impl_key_traits {
+    ($key:ident<$alg:ident>) => {
+        impl SigningKey<$alg> for $key {
+            fn from_slice(raw: &[u8]) -> anyhow::Result<Self> {
+                Ok(Self::from(raw))
+            }
+
+            fn to_verifying_key(&self) -> Self {
+                self.clone()
+            }
+
+            fn as_bytes(&self) -> SecretBytes<'_> {
+                SecretBytes::borrowed(self.as_ref())
+            }
+        }
+
+        impl VerifyingKey<$alg> for $key {
+            fn from_slice(raw: &[u8]) -> anyhow::Result<Self> {
+                Ok(Self::from(raw))
+            }
+
+            fn as_bytes(&self) -> Cow<'_, [u8]> {
+                Cow::Borrowed(self.as_ref())
+            }
+        }
+
+        impl<'a> From<&'a $key> for JsonWebKey<'a> {
+            fn from(key: &'a $key) -> JsonWebKey<'a> {
+                JsonWebKey::Symmetric {
+                    secret: SecretBytes::borrowed(key.as_ref()),
+                }
+            }
+        }
+
+        impl TryFrom<&JsonWebKey<'_>> for $key {
+            type Error = JwkError;
+
+            fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+                match jwk {
+                    JsonWebKey::Symmetric { secret } => Ok(Self::new(secret)),
+                    _ => Err(JwkError::key_type(jwk, KeyType::Symmetric)),
+                }
+            }
+        }
+    };
+}
+
+impl_key_traits!(Hs256Key<Hs256>);
+impl_key_traits!(Hs384Key<Hs384>);
+impl_key_traits!(Hs512Key<Hs512>);
+
\ No newline at end of file diff --git a/src/jwt_compact/alg/p256.rs.html b/src/jwt_compact/alg/p256.rs.html new file mode 100644 index 00000000..c1b733ac --- /dev/null +++ b/src/jwt_compact/alg/p256.rs.html @@ -0,0 +1,299 @@ +p256.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+
//! `ES256` algorithm implementation using the `p256` crate.
+
+use p256::ecdsa::{
+    signature::{DigestSigner, DigestVerifier},
+    Signature, SigningKey, VerifyingKey,
+};
+use sha2::{Digest, Sha256};
+
+use core::num::NonZeroUsize;
+
+use crate::{
+    alg::{self, SecretBytes},
+    alloc::Cow,
+    jwk::{JsonWebKey, JwkError, KeyType},
+    Algorithm, AlgorithmSignature,
+};
+
+impl AlgorithmSignature for Signature {
+    const LENGTH: Option<NonZeroUsize> = NonZeroUsize::new(64);
+
+    fn try_from_slice(slice: &[u8]) -> anyhow::Result<Self> {
+        Signature::try_from(slice).map_err(|err| anyhow::anyhow!(err))
+    }
+
+    fn as_bytes(&self) -> Cow<'_, [u8]> {
+        Cow::Owned(self.to_bytes().to_vec())
+    }
+}
+
+/// `ES256` signing algorithm. Implements elliptic curve digital signatures (ECDSA)
+/// on the secp256r1 curve (aka P-256).
+#[derive(Debug, Default)]
+#[cfg_attr(docsrs, doc(cfg(feature = "p256")))]
+pub struct Es256;
+
+impl Algorithm for Es256 {
+    type SigningKey = SigningKey;
+    type VerifyingKey = VerifyingKey;
+    type Signature = Signature;
+
+    fn name(&self) -> Cow<'static, str> {
+        Cow::Borrowed("ES256")
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        let mut digest = Sha256::default();
+        digest.update(message);
+        signing_key.sign_digest(digest)
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        let mut digest = Sha256::default();
+        digest.update(message);
+
+        verifying_key.verify_digest(digest, signature).is_ok()
+    }
+}
+
+impl alg::SigningKey<Es256> for SigningKey {
+    fn from_slice(raw: &[u8]) -> anyhow::Result<Self> {
+        Self::from_slice(raw).map_err(|err| anyhow::anyhow!(err))
+    }
+
+    fn to_verifying_key(&self) -> VerifyingKey {
+        *self.verifying_key()
+    }
+
+    fn as_bytes(&self) -> SecretBytes<'_> {
+        SecretBytes::owned(self.to_bytes().to_vec())
+    }
+}
+
+impl alg::VerifyingKey<Es256> for VerifyingKey {
+    fn from_slice(raw: &[u8]) -> anyhow::Result<Self> {
+        Self::from_sec1_bytes(raw).map_err(|err| anyhow::anyhow!(err))
+    }
+
+    /// Serializes the key as a 33-byte compressed form.
+    fn as_bytes(&self) -> Cow<'_, [u8]> {
+        let bytes = self.to_encoded_point(true).as_bytes().to_vec();
+        Cow::Owned(bytes)
+    }
+}
+
+fn create_jwk<'a>(pk: &VerifyingKey, sk: Option<&'a SigningKey>) -> JsonWebKey<'a> {
+    let uncompressed = pk.to_encoded_point(false);
+    JsonWebKey::EllipticCurve {
+        curve: "P-256".into(),
+        x: Cow::Owned(uncompressed.x().expect("x coord").to_vec()),
+        y: Cow::Owned(uncompressed.y().expect("y coord").to_vec()),
+        secret: sk.map(|sk| SecretBytes::owned(sk.to_bytes().to_vec())),
+    }
+}
+
+impl<'a> From<&'a VerifyingKey> for JsonWebKey<'a> {
+    fn from(key: &'a VerifyingKey) -> JsonWebKey<'a> {
+        create_jwk(key, None)
+    }
+}
+
+impl TryFrom<&JsonWebKey<'_>> for VerifyingKey {
+    type Error = JwkError;
+
+    fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+        const COORDINATE_SIZE: usize = 32;
+
+        let JsonWebKey::EllipticCurve { curve, x, y, .. } = jwk else {
+            return Err(JwkError::key_type(jwk, KeyType::EllipticCurve));
+        };
+        JsonWebKey::ensure_curve(curve, "P-256")?;
+        JsonWebKey::ensure_len("x", x, COORDINATE_SIZE)?;
+        JsonWebKey::ensure_len("y", y, COORDINATE_SIZE)?;
+
+        let mut key_bytes = [0_u8; 2 * COORDINATE_SIZE + 1];
+        key_bytes[0] = 4; // uncompressed key marker
+        key_bytes[1..=COORDINATE_SIZE].copy_from_slice(x);
+        key_bytes[(1 + COORDINATE_SIZE)..].copy_from_slice(y);
+        VerifyingKey::from_sec1_bytes(&key_bytes[..])
+            .map_err(|err| JwkError::custom(anyhow::anyhow!(err)))
+    }
+}
+
+impl<'a> From<&'a SigningKey> for JsonWebKey<'a> {
+    fn from(key: &'a SigningKey) -> JsonWebKey<'a> {
+        create_jwk(key.verifying_key(), Some(key))
+    }
+}
+
+impl TryFrom<&JsonWebKey<'_>> for SigningKey {
+    type Error = JwkError;
+
+    fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+        let JsonWebKey::EllipticCurve { secret, .. } = jwk else {
+            return Err(JwkError::key_type(jwk, KeyType::EllipticCurve));
+        };
+        let sk_bytes = secret.as_deref();
+        let sk_bytes = sk_bytes.ok_or_else(|| JwkError::NoField("d".into()))?;
+        JsonWebKey::ensure_len("d", sk_bytes, 32)?;
+
+        let sk =
+            Self::from_slice(sk_bytes).map_err(|err| JwkError::custom(anyhow::anyhow!(err)))?;
+        jwk.ensure_key_match(sk)
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/alg/rsa.rs.html b/src/jwt_compact/alg/rsa.rs.html new file mode 100644 index 00000000..5fd057bc --- /dev/null +++ b/src/jwt_compact/alg/rsa.rs.html @@ -0,0 +1,933 @@ +rsa.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+
//! RSA-based JWT algorithms: `RS*` and `PS*`.
+
+pub use rsa::{errors::Error as RsaError, RsaPrivateKey, RsaPublicKey};
+
+use rand_core::{CryptoRng, RngCore};
+use rsa::{
+    traits::{PrivateKeyParts, PublicKeyParts},
+    BigUint, Pkcs1v15Sign, Pss,
+};
+use sha2::{Digest, Sha256, Sha384, Sha512};
+
+use core::{fmt, str::FromStr};
+
+use crate::{
+    alg::{SecretBytes, StrongKey, WeakKeyError},
+    alloc::{Box, Cow, String, ToOwned, Vec},
+    jwk::{JsonWebKey, JwkError, KeyType, RsaPrimeFactor, RsaPrivateParts},
+    Algorithm, AlgorithmSignature,
+};
+
+/// RSA signature.
+#[derive(Debug)]
+#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
+pub struct RsaSignature(Vec<u8>);
+
+impl AlgorithmSignature for RsaSignature {
+    fn try_from_slice(bytes: &[u8]) -> anyhow::Result<Self> {
+        Ok(RsaSignature(bytes.to_vec()))
+    }
+
+    fn as_bytes(&self) -> Cow<'_, [u8]> {
+        Cow::Borrowed(&self.0)
+    }
+}
+
+/// RSA hash algorithm.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+enum HashAlg {
+    Sha256,
+    Sha384,
+    Sha512,
+}
+
+impl HashAlg {
+    fn digest(self, message: &[u8]) -> Box<[u8]> {
+        match self {
+            Self::Sha256 => {
+                let digest: [u8; 32] = *(Sha256::digest(message).as_ref());
+                Box::new(digest)
+            }
+            Self::Sha384 => {
+                let mut digest = [0_u8; 48];
+                digest.copy_from_slice(Sha384::digest(message).as_ref());
+                Box::new(digest)
+            }
+            Self::Sha512 => {
+                let mut digest = [0_u8; 64];
+                digest.copy_from_slice(Sha512::digest(message).as_ref());
+                Box::new(digest)
+            }
+        }
+    }
+}
+
+/// RSA padding algorithm.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+enum Padding {
+    Pkcs1v15,
+    Pss,
+}
+
+#[derive(Debug)]
+enum PaddingScheme {
+    Pkcs1v15(Pkcs1v15Sign),
+    Pss(Pss),
+}
+
+/// Bit length of an RSA key modulus (aka RSA key length).
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[non_exhaustive]
+#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
+pub enum ModulusBits {
+    /// 2048 bits. This is the minimum recommended key length as of 2020.
+    TwoKibibytes,
+    /// 3072 bits.
+    ThreeKibibytes,
+    /// 4096 bits.
+    FourKibibytes,
+}
+
+impl ModulusBits {
+    /// Converts this length to the numeric value.
+    pub fn bits(self) -> usize {
+        match self {
+            Self::TwoKibibytes => 2_048,
+            Self::ThreeKibibytes => 3_072,
+            Self::FourKibibytes => 4_096,
+        }
+    }
+
+    fn is_valid_bits(bits: usize) -> bool {
+        matches!(bits, 2_048 | 3_072 | 4_096)
+    }
+}
+
+impl TryFrom<usize> for ModulusBits {
+    type Error = ModulusBitsError;
+
+    fn try_from(value: usize) -> Result<Self, Self::Error> {
+        match value {
+            2_048 => Ok(Self::TwoKibibytes),
+            3_072 => Ok(Self::ThreeKibibytes),
+            4_096 => Ok(Self::FourKibibytes),
+            _ => Err(ModulusBitsError(())),
+        }
+    }
+}
+
+/// Error type returned when a conversion of an integer into `ModulusBits` fails.
+#[derive(Debug)]
+#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
+pub struct ModulusBitsError(());
+
+impl fmt::Display for ModulusBitsError {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        formatter.write_str(
+            "Unsupported bit length of RSA modulus; only lengths 2048, 3072 and 4096 \
+            are supported.",
+        )
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ModulusBitsError {}
+
+/// Integrity algorithm using [RSA] digital signatures.
+///
+/// Depending on the variation, the algorithm employs PKCS#1 v1.5 or PSS padding and
+/// one of the hash functions from the SHA-2 family: SHA-256, SHA-384, or SHA-512.
+/// See [RFC 7518] for more details. Depending on the chosen parameters,
+/// the name of the algorithm is one of `RS256`, `RS384`, `RS512`, `PS256`, `PS384`, `PS512`:
+///
+/// - `R` / `P` denote the padding scheme: PKCS#1 v1.5 for `R`, PSS for `P`
+/// - `256` / `384` / `512` denote the hash function
+///
+/// The length of RSA keys is not unequivocally specified by the algorithm; nevertheless,
+/// it **MUST** be at least 2048 bits as per RFC 7518. To minimize risks of misconfiguration,
+/// use [`StrongAlg`](super::StrongAlg) wrapper around `Rsa`:
+///
+/// ```
+/// # use jwt_compact::alg::{StrongAlg, Rsa};
+/// const ALG: StrongAlg<Rsa> = StrongAlg(Rsa::rs256());
+/// // `ALG` will not support RSA keys with unsecure lengths by design!
+/// ```
+///
+/// [RSA]: https://en.wikipedia.org/wiki/RSA_(cryptosystem)
+/// [RFC 7518]: https://www.rfc-editor.org/rfc/rfc7518.html
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
+pub struct Rsa {
+    hash_alg: HashAlg,
+    padding_alg: Padding,
+}
+
+impl Algorithm for Rsa {
+    type SigningKey = RsaPrivateKey;
+    type VerifyingKey = RsaPublicKey;
+    type Signature = RsaSignature;
+
+    fn name(&self) -> Cow<'static, str> {
+        Cow::Borrowed(self.alg_name())
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        let digest = self.hash_alg.digest(message);
+        let signing_result = match self.padding_scheme() {
+            PaddingScheme::Pkcs1v15(padding) => {
+                signing_key.sign_with_rng(&mut rand_core::OsRng, padding, &digest)
+            }
+            PaddingScheme::Pss(padding) => {
+                signing_key.sign_with_rng(&mut rand_core::OsRng, padding, &digest)
+            }
+        };
+        RsaSignature(signing_result.expect("Unexpected RSA signature failure"))
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        let digest = self.hash_alg.digest(message);
+        let verify_result = match self.padding_scheme() {
+            PaddingScheme::Pkcs1v15(padding) => {
+                verifying_key.verify(padding, &digest, &signature.0)
+            }
+            PaddingScheme::Pss(padding) => verifying_key.verify(padding, &digest, &signature.0),
+        };
+        verify_result.is_ok()
+    }
+}
+
+impl Rsa {
+    const fn new(hash_alg: HashAlg, padding_alg: Padding) -> Self {
+        Rsa {
+            hash_alg,
+            padding_alg,
+        }
+    }
+
+    /// RSA with SHA-256 and PKCS#1 v1.5 padding.
+    pub const fn rs256() -> Rsa {
+        Rsa::new(HashAlg::Sha256, Padding::Pkcs1v15)
+    }
+
+    /// RSA with SHA-384 and PKCS#1 v1.5 padding.
+    pub const fn rs384() -> Rsa {
+        Rsa::new(HashAlg::Sha384, Padding::Pkcs1v15)
+    }
+
+    /// RSA with SHA-512 and PKCS#1 v1.5 padding.
+    pub const fn rs512() -> Rsa {
+        Rsa::new(HashAlg::Sha512, Padding::Pkcs1v15)
+    }
+
+    /// RSA with SHA-256 and PSS padding.
+    pub const fn ps256() -> Rsa {
+        Rsa::new(HashAlg::Sha256, Padding::Pss)
+    }
+
+    /// RSA with SHA-384 and PSS padding.
+    pub const fn ps384() -> Rsa {
+        Rsa::new(HashAlg::Sha384, Padding::Pss)
+    }
+
+    /// RSA with SHA-512 and PSS padding.
+    pub const fn ps512() -> Rsa {
+        Rsa::new(HashAlg::Sha512, Padding::Pss)
+    }
+
+    /// RSA based on the specified algorithm name.
+    ///
+    /// # Panics
+    ///
+    /// - Panics if the name is not one of the six RSA-based JWS algorithms. Prefer using
+    ///   the [`FromStr`] trait if the conversion is potentially fallible.
+    pub fn with_name(name: &str) -> Self {
+        name.parse().unwrap()
+    }
+
+    fn padding_scheme(self) -> PaddingScheme {
+        match self.padding_alg {
+            Padding::Pkcs1v15 => PaddingScheme::Pkcs1v15(match self.hash_alg {
+                HashAlg::Sha256 => Pkcs1v15Sign::new::<Sha256>(),
+                HashAlg::Sha384 => Pkcs1v15Sign::new::<Sha384>(),
+                HashAlg::Sha512 => Pkcs1v15Sign::new::<Sha512>(),
+            }),
+            Padding::Pss => {
+                // The salt length needs to be set to the size of hash function output;
+                // see https://www.rfc-editor.org/rfc/rfc7518.html#section-3.5.
+                PaddingScheme::Pss(match self.hash_alg {
+                    HashAlg::Sha256 => Pss::new_with_salt::<Sha256>(Sha256::output_size()),
+                    HashAlg::Sha384 => Pss::new_with_salt::<Sha384>(Sha384::output_size()),
+                    HashAlg::Sha512 => Pss::new_with_salt::<Sha512>(Sha512::output_size()),
+                })
+            }
+        }
+    }
+
+    fn alg_name(self) -> &'static str {
+        match (self.padding_alg, self.hash_alg) {
+            (Padding::Pkcs1v15, HashAlg::Sha256) => "RS256",
+            (Padding::Pkcs1v15, HashAlg::Sha384) => "RS384",
+            (Padding::Pkcs1v15, HashAlg::Sha512) => "RS512",
+            (Padding::Pss, HashAlg::Sha256) => "PS256",
+            (Padding::Pss, HashAlg::Sha384) => "PS384",
+            (Padding::Pss, HashAlg::Sha512) => "PS512",
+        }
+    }
+
+    /// Generates a new key pair with the specified modulus bit length (aka key length).
+    pub fn generate<R: CryptoRng + RngCore>(
+        rng: &mut R,
+        modulus_bits: ModulusBits,
+    ) -> rsa::errors::Result<(StrongKey<RsaPrivateKey>, StrongKey<RsaPublicKey>)> {
+        let signing_key = RsaPrivateKey::new(rng, modulus_bits.bits())?;
+        let verifying_key = signing_key.to_public_key();
+        Ok((StrongKey(signing_key), StrongKey(verifying_key)))
+    }
+}
+
+impl FromStr for Rsa {
+    type Err = RsaParseError;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Ok(match s {
+            "RS256" => Self::rs256(),
+            "RS384" => Self::rs384(),
+            "RS512" => Self::rs512(),
+            "PS256" => Self::ps256(),
+            "PS384" => Self::ps384(),
+            "PS512" => Self::ps512(),
+            _ => return Err(RsaParseError(s.to_owned())),
+        })
+    }
+}
+
+/// Errors that can occur when parsing an [`Rsa`] algorithm from a string.
+#[derive(Debug)]
+#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
+pub struct RsaParseError(String);
+
+impl fmt::Display for RsaParseError {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(formatter, "Invalid RSA algorithm name: {}", self.0)
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for RsaParseError {}
+
+impl StrongKey<RsaPrivateKey> {
+    /// Converts this private key to a public key.
+    pub fn to_public_key(&self) -> StrongKey<RsaPublicKey> {
+        StrongKey(self.0.to_public_key())
+    }
+}
+
+impl TryFrom<RsaPrivateKey> for StrongKey<RsaPrivateKey> {
+    type Error = WeakKeyError<RsaPrivateKey>;
+
+    fn try_from(key: RsaPrivateKey) -> Result<Self, Self::Error> {
+        if ModulusBits::is_valid_bits(key.n().bits()) {
+            Ok(StrongKey(key))
+        } else {
+            Err(WeakKeyError(key))
+        }
+    }
+}
+
+impl TryFrom<RsaPublicKey> for StrongKey<RsaPublicKey> {
+    type Error = WeakKeyError<RsaPublicKey>;
+
+    fn try_from(key: RsaPublicKey) -> Result<Self, Self::Error> {
+        if ModulusBits::is_valid_bits(key.n().bits()) {
+            Ok(StrongKey(key))
+        } else {
+            Err(WeakKeyError(key))
+        }
+    }
+}
+
+impl<'a> From<&'a RsaPublicKey> for JsonWebKey<'a> {
+    fn from(key: &'a RsaPublicKey) -> JsonWebKey<'a> {
+        JsonWebKey::Rsa {
+            modulus: Cow::Owned(key.n().to_bytes_be()),
+            public_exponent: Cow::Owned(key.e().to_bytes_be()),
+            private_parts: None,
+        }
+    }
+}
+
+impl TryFrom<&JsonWebKey<'_>> for RsaPublicKey {
+    type Error = JwkError;
+
+    fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+        let JsonWebKey::Rsa {
+            modulus,
+            public_exponent,
+            ..
+        } = jwk
+        else {
+            return Err(JwkError::key_type(jwk, KeyType::Rsa));
+        };
+
+        let e = BigUint::from_bytes_be(public_exponent);
+        let n = BigUint::from_bytes_be(modulus);
+        Self::new(n, e).map_err(|err| JwkError::custom(anyhow::anyhow!(err)))
+    }
+}
+
+/// ⚠ **Warning.** Contrary to [RFC 7518], this implementation does not set `dp`, `dq`, and `qi`
+/// fields in the JWK root object, as well as `d` and `t` fields for additional factors
+/// (i.e., in the `oth` array).
+///
+/// [RFC 7518]: https://tools.ietf.org/html/rfc7518#section-6.3.2
+impl<'a> From<&'a RsaPrivateKey> for JsonWebKey<'a> {
+    fn from(key: &'a RsaPrivateKey) -> JsonWebKey<'a> {
+        const MSG: &str = "RsaPrivateKey must have at least 2 prime factors";
+
+        let p = key.primes().get(0).expect(MSG);
+        let q = key.primes().get(1).expect(MSG);
+
+        let private_parts = RsaPrivateParts {
+            private_exponent: SecretBytes::owned(key.d().to_bytes_be()),
+            prime_factor_p: SecretBytes::owned(p.to_bytes_be()),
+            prime_factor_q: SecretBytes::owned(q.to_bytes_be()),
+            p_crt_exponent: None,
+            q_crt_exponent: None,
+            q_crt_coefficient: None,
+            other_prime_factors: key.primes()[2..]
+                .iter()
+                .map(|factor| RsaPrimeFactor {
+                    factor: SecretBytes::owned(factor.to_bytes_be()),
+                    crt_exponent: None,
+                    crt_coefficient: None,
+                })
+                .collect(),
+        };
+
+        JsonWebKey::Rsa {
+            modulus: Cow::Owned(key.n().to_bytes_be()),
+            public_exponent: Cow::Owned(key.e().to_bytes_be()),
+            private_parts: Some(private_parts),
+        }
+    }
+}
+
+/// ⚠ **Warning.** Contrary to [RFC 7518] (at least, in spirit), this conversion ignores
+/// `dp`, `dq`, and `qi` fields from JWK, as well as `d` and `t` fields for additional factors.
+///
+/// [RFC 7518]: https://www.rfc-editor.org/rfc/rfc7518.html
+impl TryFrom<&JsonWebKey<'_>> for RsaPrivateKey {
+    type Error = JwkError;
+
+    fn try_from(jwk: &JsonWebKey<'_>) -> Result<Self, Self::Error> {
+        let JsonWebKey::Rsa {
+            modulus,
+            public_exponent,
+            private_parts,
+        } = jwk
+        else {
+            return Err(JwkError::key_type(jwk, KeyType::Rsa));
+        };
+
+        let RsaPrivateParts {
+            private_exponent: d,
+            prime_factor_p,
+            prime_factor_q,
+            other_prime_factors,
+            ..
+        } = private_parts
+            .as_ref()
+            .ok_or_else(|| JwkError::NoField("d".into()))?;
+
+        let e = BigUint::from_bytes_be(public_exponent);
+        let n = BigUint::from_bytes_be(modulus);
+        let d = BigUint::from_bytes_be(d);
+
+        let mut factors = Vec::with_capacity(2 + other_prime_factors.len());
+        factors.push(BigUint::from_bytes_be(prime_factor_p));
+        factors.push(BigUint::from_bytes_be(prime_factor_q));
+        factors.extend(
+            other_prime_factors
+                .iter()
+                .map(|prime| BigUint::from_bytes_be(&prime.factor)),
+        );
+
+        let key = Self::from_components(n, e, d, factors);
+        let key = key.map_err(|err| JwkError::custom(anyhow::anyhow!(err)))?;
+        key.validate()
+            .map_err(|err| JwkError::custom(anyhow::anyhow!(err)))?;
+        Ok(key)
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/claims.rs.html b/src/jwt_compact/claims.rs.html new file mode 100644 index 00000000..9910b0e5 --- /dev/null +++ b/src/jwt_compact/claims.rs.html @@ -0,0 +1,771 @@ +claims.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+
use chrono::{DateTime, Duration, Utc};
+use serde::{Deserialize, Serialize};
+
+use crate::{Claim, ValidationError};
+
+/// Time-related options for token creation and validation.
+///
+/// If the `clock` crate feature is on (and it's on by default), `TimeOptions` can be created
+/// using the `Default` impl or [`Self::from_leeway()`]. If the feature is off,
+/// you can still create options using [a generic constructor](Self::new).
+///
+/// # Examples
+///
+/// ```
+/// # use chrono::{Duration, Utc};
+/// # use jwt_compact::TimeOptions;
+/// // Default options.
+/// let default_options = TimeOptions::default();
+/// let options_with_custom_leeway =
+///     TimeOptions::from_leeway(Duration::seconds(5));
+/// // Options that have a fixed time. Can be useful for testing.
+/// let clock_time = Utc::now();
+/// let options_with_stopped_clock =
+///     TimeOptions::new(Duration::seconds(10), move || clock_time);
+/// ```
+#[derive(Debug, Clone, Copy)]
+#[non_exhaustive]
+pub struct TimeOptions<F = fn() -> DateTime<Utc>> {
+    /// Leeway to use during validation.
+    pub leeway: Duration,
+    /// Source of the current timestamps.
+    pub clock_fn: F,
+}
+
+impl<F: Fn() -> DateTime<Utc>> TimeOptions<F> {
+    /// Creates options based on the specified time leeway and clock function.
+    pub fn new(leeway: Duration, clock_fn: F) -> Self {
+        Self { leeway, clock_fn }
+    }
+}
+
+impl TimeOptions {
+    /// Creates options based on the specified time leeway. The clock source is [`Utc::now()`].
+    #[cfg(feature = "clock")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "clock")))]
+    pub fn from_leeway(leeway: Duration) -> Self {
+        Self {
+            leeway,
+            clock_fn: Utc::now,
+        }
+    }
+}
+
+/// Creates options with a default leeway (60 seconds) and the [`Utc::now()`] clock.
+///
+/// This impl is supported on **crate feature `clock`** only.
+#[cfg(feature = "clock")]
+impl Default for TimeOptions {
+    fn default() -> Self {
+        Self::from_leeway(Duration::seconds(60))
+    }
+}
+
+/// A structure with no fields that can be used as a type parameter to `Claims`.
+#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub struct Empty {}
+
+/// Claims encoded in a token.
+///
+/// Claims are comprised of a "standard" part (`exp`, `nbf` and `iat` claims as per [JWT spec]),
+/// and custom fields. `iss`, `sub` and `aud` claims are not in the standard part
+/// due to a variety of data types they can be reasonably represented by.
+///
+/// [JWT spec]: https://tools.ietf.org/html/rfc7519#section-4.1
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[non_exhaustive]
+pub struct Claims<T> {
+    /// Expiration time of the token.
+    #[serde(
+        rename = "exp",
+        default,
+        skip_serializing_if = "Option::is_none",
+        with = "self::serde_timestamp"
+    )]
+    pub expiration: Option<DateTime<Utc>>,
+
+    /// Minimum time at which token is valid.
+    #[serde(
+        rename = "nbf",
+        default,
+        skip_serializing_if = "Option::is_none",
+        with = "self::serde_timestamp"
+    )]
+    pub not_before: Option<DateTime<Utc>>,
+
+    /// Time of token issuance.
+    #[serde(
+        rename = "iat",
+        default,
+        skip_serializing_if = "Option::is_none",
+        with = "self::serde_timestamp"
+    )]
+    pub issued_at: Option<DateTime<Utc>>,
+
+    /// Custom claims.
+    #[serde(flatten)]
+    pub custom: T,
+}
+
+impl Claims<Empty> {
+    /// Creates an empty claims instance.
+    pub fn empty() -> Self {
+        Self {
+            expiration: None,
+            not_before: None,
+            issued_at: None,
+            custom: Empty {},
+        }
+    }
+}
+
+impl<T> Claims<T> {
+    /// Creates a new instance with the provided custom claims.
+    pub fn new(custom_claims: T) -> Self {
+        Self {
+            expiration: None,
+            not_before: None,
+            issued_at: None,
+            custom: custom_claims,
+        }
+    }
+
+    /// Sets the `expiration` claim so that the token has the specified `duration`.
+    /// The current timestamp is taken from `options`.
+    #[must_use]
+    pub fn set_duration<F>(self, options: &TimeOptions<F>, duration: Duration) -> Self
+    where
+        F: Fn() -> DateTime<Utc>,
+    {
+        Self {
+            expiration: Some((options.clock_fn)() + duration),
+            ..self
+        }
+    }
+
+    /// Atomically sets `issued_at` and `expiration` claims: first to the current time
+    /// (taken from `options`), and the second to match the specified `duration` of the token.
+    #[must_use]
+    pub fn set_duration_and_issuance<F>(self, options: &TimeOptions<F>, duration: Duration) -> Self
+    where
+        F: Fn() -> DateTime<Utc>,
+    {
+        let issued_at = (options.clock_fn)();
+        Self {
+            expiration: Some(issued_at + duration),
+            issued_at: Some(issued_at),
+            ..self
+        }
+    }
+
+    /// Sets the `nbf` claim.
+    #[must_use]
+    pub fn set_not_before(self, moment: DateTime<Utc>) -> Self {
+        Self {
+            not_before: Some(moment),
+            ..self
+        }
+    }
+
+    /// Validates the expiration claim.
+    ///
+    /// This method will return an error if the claims do not feature an expiration time,
+    /// or if it is in the past (subject to the provided `options`).
+    pub fn validate_expiration<F>(&self, options: &TimeOptions<F>) -> Result<&Self, ValidationError>
+    where
+        F: Fn() -> DateTime<Utc>,
+    {
+        self.expiration.map_or(
+            Err(ValidationError::NoClaim(Claim::Expiration)),
+            |expiration| {
+                let expiration_with_leeway = expiration
+                    .checked_add_signed(options.leeway)
+                    .unwrap_or(DateTime::<Utc>::MAX_UTC);
+                if (options.clock_fn)() > expiration_with_leeway {
+                    Err(ValidationError::Expired)
+                } else {
+                    Ok(self)
+                }
+            },
+        )
+    }
+
+    /// Validates the maturity time (`nbf` claim).
+    ///
+    /// This method will return an error if the claims do not feature a maturity time,
+    /// or if it is in the future (subject to the provided `options`).
+    pub fn validate_maturity<F>(&self, options: &TimeOptions<F>) -> Result<&Self, ValidationError>
+    where
+        F: Fn() -> DateTime<Utc>,
+    {
+        self.not_before.map_or(
+            Err(ValidationError::NoClaim(Claim::NotBefore)),
+            |not_before| {
+                if (options.clock_fn)() < not_before - options.leeway {
+                    Err(ValidationError::NotMature)
+                } else {
+                    Ok(self)
+                }
+            },
+        )
+    }
+}
+
+mod serde_timestamp {
+    use chrono::{offset::TimeZone, DateTime, Utc};
+    use serde::{
+        de::{Error as DeError, Visitor},
+        Deserializer, Serializer,
+    };
+
+    use core::fmt;
+
+    struct TimestampVisitor;
+
+    impl<'de> Visitor<'de> for TimestampVisitor {
+        type Value = DateTime<Utc>;
+
+        fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+            formatter.write_str("UTC timestamp")
+        }
+
+        fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+        where
+            E: DeError,
+        {
+            Utc.timestamp_opt(value, 0)
+                .single()
+                .ok_or_else(|| E::custom("UTC timestamp overflow"))
+        }
+
+        fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+        where
+            E: DeError,
+        {
+            let value = i64::try_from(value).map_err(DeError::custom)?;
+            Utc.timestamp_opt(value, 0)
+                .single()
+                .ok_or_else(|| E::custom("UTC timestamp overflow"))
+        }
+
+        #[allow(clippy::cast_possible_truncation)]
+        // ^ If truncation occurs, the `timestamp_opt()` won't return a single value anyway
+        fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
+        where
+            E: DeError,
+        {
+            Utc.timestamp_opt(value as i64, 0)
+                .single()
+                .ok_or_else(|| E::custom("UTC timestamp overflow"))
+        }
+    }
+
+    pub fn serialize<S: Serializer>(
+        time: &Option<DateTime<Utc>>,
+        serializer: S,
+    ) -> Result<S::Ok, S::Error> {
+        // `unwrap` is safe due to `skip_serializing_if` option
+        serializer.serialize_i64(time.unwrap().timestamp())
+    }
+
+    pub fn deserialize<'de, D: Deserializer<'de>>(
+        deserializer: D,
+    ) -> Result<Option<DateTime<Utc>>, D::Error> {
+        deserializer.deserialize_i64(TimestampVisitor).map(Some)
+    }
+}
+
+#[cfg(all(test, feature = "clock"))]
+mod tests {
+    use super::*;
+    use assert_matches::assert_matches;
+    use chrono::TimeZone;
+
+    #[test]
+    fn empty_claims_can_be_serialized() {
+        let mut claims = Claims::empty();
+        assert!(serde_json::to_string(&claims).is_ok());
+        claims.expiration = Some(Utc::now());
+        assert!(serde_json::to_string(&claims).is_ok());
+        claims.not_before = Some(Utc::now());
+        assert!(serde_json::to_string(&claims).is_ok());
+    }
+
+    #[test]
+    #[cfg(feature = "ciborium")]
+    fn empty_claims_can_be_serialized_to_cbor() {
+        let mut claims = Claims::empty();
+        assert!(ciborium::into_writer(&claims, &mut vec![]).is_ok());
+        claims.expiration = Some(Utc::now());
+        assert!(ciborium::into_writer(&claims, &mut vec![]).is_ok());
+        claims.not_before = Some(Utc::now());
+        assert!(ciborium::into_writer(&claims, &mut vec![]).is_ok());
+    }
+
+    #[test]
+    fn expired_claim() {
+        let mut claims = Claims::empty();
+        let time_options = TimeOptions::default();
+        assert_matches!(
+            claims.validate_expiration(&time_options).unwrap_err(),
+            ValidationError::NoClaim(Claim::Expiration)
+        );
+
+        claims.expiration = Some(DateTime::<Utc>::MAX_UTC);
+        assert!(claims.validate_expiration(&time_options).is_ok());
+
+        claims.expiration = Some(Utc::now() - Duration::hours(1));
+        assert_matches!(
+            claims.validate_expiration(&time_options).unwrap_err(),
+            ValidationError::Expired
+        );
+
+        claims.expiration = Some(Utc::now() - Duration::seconds(10));
+        // With the default leeway, this claim is still valid.
+        assert!(claims.validate_expiration(&time_options).is_ok());
+        // If we set leeway lower, then the claim will be considered expired.
+        assert_matches!(
+            claims
+                .validate_expiration(&TimeOptions::from_leeway(Duration::seconds(5)))
+                .unwrap_err(),
+            ValidationError::Expired
+        );
+        // Same if we set the current time in the past.
+        let expiration = claims.expiration.unwrap();
+        assert!(claims
+            .validate_expiration(&TimeOptions::new(Duration::seconds(3), move || {
+                expiration
+            }))
+            .is_ok());
+    }
+
+    #[test]
+    fn immature_claim() {
+        let mut claims = Claims::empty();
+        let time_options = TimeOptions::default();
+        assert_matches!(
+            claims.validate_maturity(&time_options).unwrap_err(),
+            ValidationError::NoClaim(Claim::NotBefore)
+        );
+
+        claims.not_before = Some(Utc::now() + Duration::hours(1));
+        assert_matches!(
+            claims.validate_maturity(&time_options).unwrap_err(),
+            ValidationError::NotMature
+        );
+
+        claims.not_before = Some(Utc::now() + Duration::seconds(10));
+        // With the default leeway, this claim is still valid.
+        assert!(claims.validate_maturity(&time_options).is_ok());
+        // If we set leeway lower, then the claim will be considered expired.
+        assert_matches!(
+            claims
+                .validate_maturity(&TimeOptions::from_leeway(Duration::seconds(5)))
+                .unwrap_err(),
+            ValidationError::NotMature
+        );
+    }
+    #[test]
+    fn float_timestamp() {
+        let claims = "{\"exp\": 1.691203462e+9}";
+        let claims: Claims<Empty> = serde_json::from_str(claims).unwrap();
+        let timestamp = Utc.timestamp_opt(1_691_203_462, 0).single().unwrap();
+        assert_eq!(claims.expiration, Some(timestamp));
+    }
+
+    #[test]
+    fn float_timestamp_errors() {
+        let invalid_claims = ["{\"exp\": 1e20}", "{\"exp\": -1e20}"];
+        for claims in invalid_claims {
+            let err = serde_json::from_str::<Claims<Empty>>(claims).unwrap_err();
+            let err = err.to_string();
+            assert!(err.contains("UTC timestamp overflow"), "{err}");
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/error.rs.html b/src/jwt_compact/error.rs.html new file mode 100644 index 00000000..4a6aefe8 --- /dev/null +++ b/src/jwt_compact/error.rs.html @@ -0,0 +1,375 @@ +error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+
//! Error handling.
+
+#[cfg(feature = "ciborium")]
+use core::convert::Infallible;
+use core::fmt;
+
+use crate::alloc::String;
+
+#[cfg(feature = "ciborium")]
+pub(crate) type CborDeError<E = anyhow::Error> = ciborium::de::Error<E>;
+#[cfg(feature = "ciborium")]
+pub(crate) type CborSerError<E = Infallible> = ciborium::ser::Error<E>;
+
+/// Errors that may occur during token parsing.
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum ParseError {
+    /// Token has invalid structure.
+    ///
+    /// Valid tokens must consist of 3 base64url-encoded parts (header, claims, and signature)
+    /// separated by periods.
+    InvalidTokenStructure,
+    /// Cannot decode base64.
+    InvalidBase64Encoding,
+    /// Token header cannot be parsed.
+    MalformedHeader(serde_json::Error),
+    /// [Content type][cty] mentioned in the token header is not supported.
+    ///
+    /// Supported content types are JSON (used by default) and CBOR (only if the `ciborium`
+    /// crate feature is enabled, which it is by default).
+    ///
+    /// [cty]: https://tools.ietf.org/html/rfc7515#section-4.1.10
+    UnsupportedContentType(String),
+}
+
+impl fmt::Display for ParseError {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::InvalidTokenStructure => formatter.write_str("invalid token structure"),
+            Self::InvalidBase64Encoding => write!(formatter, "invalid base64 decoding"),
+            Self::MalformedHeader(err) => write!(formatter, "malformed token header: {err}"),
+            Self::UnsupportedContentType(ty) => {
+                write!(formatter, "unsupported content type: {ty}")
+            }
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ParseError {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        match self {
+            Self::MalformedHeader(err) => Some(err),
+            _ => None,
+        }
+    }
+}
+
+/// Errors that can occur during token validation.
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum ValidationError {
+    /// Algorithm mentioned in the token header differs from invoked one.
+    AlgorithmMismatch {
+        /// Expected algorithm name.
+        expected: String,
+        /// Actual algorithm in the token.
+        actual: String,
+    },
+    /// Token signature has invalid byte length.
+    InvalidSignatureLen {
+        /// Expected signature length.
+        expected: usize,
+        /// Actual signature length.
+        actual: usize,
+    },
+    /// Token signature is malformed.
+    MalformedSignature(anyhow::Error),
+    /// Token signature has failed verification.
+    InvalidSignature,
+    /// Token claims cannot be deserialized from JSON.
+    MalformedClaims(serde_json::Error),
+    /// Token claims cannot be deserialized from CBOR.
+    #[cfg(feature = "ciborium")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "ciborium")))]
+    MalformedCborClaims(CborDeError),
+    /// Claim requested during validation is not present in the token.
+    NoClaim(Claim),
+    /// Token has expired.
+    Expired,
+    /// Token is not yet valid as per `nbf` claim.
+    NotMature,
+}
+
+/// Identifier of a claim in `Claims`.
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[non_exhaustive]
+pub enum Claim {
+    /// `exp` claim (expiration time).
+    Expiration,
+    /// `nbf` claim (valid not before).
+    NotBefore,
+}
+
+impl fmt::Display for Claim {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        formatter.write_str(match self {
+            Self::Expiration => "exp",
+            Self::NotBefore => "nbf",
+        })
+    }
+}
+
+impl fmt::Display for ValidationError {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::AlgorithmMismatch { expected, actual } => write!(
+                formatter,
+                "token algorithm ({actual}) differs from expected ({expected})"
+            ),
+            Self::InvalidSignatureLen { expected, actual } => write!(
+                formatter,
+                "invalid signature length: expected {expected} bytes, got {actual} bytes"
+            ),
+            Self::MalformedSignature(err) => write!(formatter, "malformed token signature: {err}"),
+            Self::InvalidSignature => formatter.write_str("signature has failed verification"),
+            Self::MalformedClaims(err) => write!(formatter, "cannot deserialize claims: {err}"),
+            #[cfg(feature = "ciborium")]
+            Self::MalformedCborClaims(err) => write!(formatter, "cannot deserialize claims: {err}"),
+            Self::NoClaim(claim) => write!(
+                formatter,
+                "claim `{claim}` requested during validation is not present in the token"
+            ),
+            Self::Expired => formatter.write_str("token has expired"),
+            Self::NotMature => formatter.write_str("token is not yet ready"),
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ValidationError {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        match self {
+            Self::MalformedSignature(err) => Some(err.as_ref()),
+            Self::MalformedClaims(err) => Some(err),
+            #[cfg(feature = "ciborium")]
+            Self::MalformedCborClaims(err) => Some(err),
+            _ => None,
+        }
+    }
+}
+
+/// Errors that can occur during token creation.
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum CreationError {
+    /// Token header cannot be serialized.
+    Header(serde_json::Error),
+    /// Token claims cannot be serialized into JSON.
+    Claims(serde_json::Error),
+    /// Token claims cannot be serialized into CBOR.
+    #[cfg(feature = "ciborium")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "ciborium")))]
+    CborClaims(CborSerError),
+}
+
+impl fmt::Display for CreationError {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::Header(err) => write!(formatter, "cannot serialize header: {err}"),
+            Self::Claims(err) => write!(formatter, "cannot serialize claims: {err}"),
+            #[cfg(feature = "ciborium")]
+            Self::CborClaims(err) => write!(formatter, "cannot serialize claims into CBOR: {err}"),
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for CreationError {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        match self {
+            Self::Header(err) | Self::Claims(err) => Some(err),
+            #[cfg(feature = "ciborium")]
+            Self::CborClaims(err) => Some(err),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/jwk.rs.html b/src/jwt_compact/jwk.rs.html new file mode 100644 index 00000000..cec88615 --- /dev/null +++ b/src/jwt_compact/jwk.rs.html @@ -0,0 +1,1335 @@ +jwk.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+
//! Basic support of [JSON Web Keys](https://tools.ietf.org/html/rfc7517.html) (JWK).
+//!
+//! The functionality defined in this module allows converting between
+//! the [generic JWK format](JsonWebKey) and key presentation specific for the crypto backend.
+//! [`JsonWebKey`]s can be (de)serialized using [`serde`] infrastructure, and can be used
+//! to compute key thumbprint as per [RFC 7638].
+//!
+//! [`serde`]: https://crates.io/crates/serde
+//! [RFC 7638]: https://tools.ietf.org/html/rfc7638
+//!
+//! # Examples
+//!
+//! ```
+//! use jwt_compact::{alg::Hs256Key, jwk::JsonWebKey};
+//! use sha2::Sha256;
+//!
+//! # fn main() -> anyhow::Result<()> {
+//! // Load a key from the JWK presentation.
+//! let json_str = r#"
+//!     { "kty": "oct", "k": "t-bdv41MJXExXnpquHBuDn7n1YGyX7gLQchVHAoNu50" }
+//! "#;
+//! let jwk: JsonWebKey<'_> = serde_json::from_str(json_str)?;
+//! let key = Hs256Key::try_from(&jwk)?;
+//!
+//! // Convert `key` back to JWK.
+//! let jwk_from_key = JsonWebKey::from(&key);
+//! assert_eq!(jwk_from_key, jwk);
+//! println!("{}", serde_json::to_string(&jwk)?);
+//!
+//! // Compute the key thumbprint.
+//! let thumbprint = jwk_from_key.thumbprint::<Sha256>();
+//! # Ok(())
+//! # }
+//! ```
+
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+use sha2::digest::{Digest, Output};
+
+use core::fmt;
+
+use crate::{
+    alg::SecretBytes,
+    alloc::{Cow, String, ToString, Vec},
+};
+
+/// Type of a [`JsonWebKey`].
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[non_exhaustive]
+pub enum KeyType {
+    /// Public or private RSA key. Corresponds to the `RSA` value of the `kty` field for JWKs.
+    Rsa,
+    /// Public or private key in an ECDSA crypto system. Corresponds to the `EC` value
+    /// of the `kty` field for JWKs.
+    EllipticCurve,
+    /// Symmetric key. Corresponds to the `oct` value of the `kty` field for JWKs.
+    Symmetric,
+    /// Generic asymmetric keypair. Corresponds to the `OKP` value of the `kty` field for JWKs.
+    KeyPair,
+}
+
+impl fmt::Display for KeyType {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        formatter.write_str(match self {
+            Self::Rsa => "RSA",
+            Self::EllipticCurve => "EC",
+            Self::Symmetric => "oct",
+            Self::KeyPair => "OKP",
+        })
+    }
+}
+
+/// Errors that can occur when transforming a [`JsonWebKey`] into the presentation specific for
+/// a crypto backend, using the [`TryFrom`] trait.
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum JwkError {
+    /// Required field is absent from JWK.
+    NoField(String),
+    /// Key type (the `kty` field) is not as expected.
+    UnexpectedKeyType {
+        /// Expected key type.
+        expected: KeyType,
+        /// Actual key type.
+        actual: KeyType,
+    },
+    /// JWK field has an unexpected value.
+    UnexpectedValue {
+        /// Field name.
+        field: String,
+        /// Expected value of the field.
+        expected: String,
+        /// Actual value of the field.
+        actual: String,
+    },
+    /// JWK field has an unexpected byte length.
+    UnexpectedLen {
+        /// Field name.
+        field: String,
+        /// Expected byte length of the field.
+        expected: usize,
+        /// Actual byte length of the field.
+        actual: usize,
+    },
+    /// Signing and verifying keys do not match.
+    MismatchedKeys,
+    /// Custom error specific to a crypto backend.
+    Custom(anyhow::Error),
+}
+
+impl fmt::Display for JwkError {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::UnexpectedKeyType { expected, actual } => {
+                write!(
+                    formatter,
+                    "unexpected key type: {actual} (expected {expected})"
+                )
+            }
+            Self::NoField(field) => write!(formatter, "field `{field}` is absent from JWK"),
+            Self::UnexpectedValue {
+                field,
+                expected,
+                actual,
+            } => {
+                write!(
+                    formatter,
+                    "field `{field}` has unexpected value (expected: {expected}, got: {actual})"
+                )
+            }
+            Self::UnexpectedLen {
+                field,
+                expected,
+                actual,
+            } => {
+                write!(
+                    formatter,
+                    "field `{field}` has unexpected length (expected: {expected}, got: {actual})"
+                )
+            }
+            Self::MismatchedKeys => {
+                formatter.write_str("private and public keys encoded in JWK do not match")
+            }
+            Self::Custom(err) => fmt::Display::fmt(err, formatter),
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for JwkError {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        match self {
+            Self::Custom(err) => Some(err.as_ref()),
+            _ => None,
+        }
+    }
+}
+
+impl JwkError {
+    /// Creates a `Custom` error variant.
+    pub fn custom(err: impl Into<anyhow::Error>) -> Self {
+        Self::Custom(err.into())
+    }
+
+    pub(crate) fn key_type(jwk: &JsonWebKey<'_>, expected: KeyType) -> Self {
+        let actual = jwk.key_type();
+        debug_assert_ne!(actual, expected);
+        Self::UnexpectedKeyType { actual, expected }
+    }
+}
+
+impl Serialize for SecretBytes<'_> {
+    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+        base64url::serialize(self.as_ref(), serializer)
+    }
+}
+
+impl<'de> Deserialize<'de> for SecretBytes<'_> {
+    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+        base64url::deserialize(deserializer).map(SecretBytes::new)
+    }
+}
+
+/// Basic [JWK] functionality: (de)serialization and creating thumbprints.
+///
+/// See [RFC 7518] for the details about the fields for various key types.
+///
+/// [`Self::thumbprint()`] and the [`Display`](fmt::Display) implementation
+/// allow to get the overall presentation of the key. The latter returns JSON serialization
+/// of the key with fields ordered alphabetically. That is, this output for verifying keys
+/// can be used to compute key thumbprints.
+///
+/// # Serialization
+///
+/// For human-readable formats (e.g., JSON, TOML, YAML), byte fields in `JsonWebKey`
+/// and embedded types ([`SecretBytes`], [`RsaPrivateParts`], [`RsaPrimeFactor`]) will be
+/// serialized in base64-url encoding with no padding, as per the JWK spec.
+/// For other formats (e.g., CBOR), byte fields will be serialized as byte sequences.
+///
+/// Because of [the limitations](https://github.com/pyfisch/cbor/issues/3)
+/// of the CBOR support in `serde`, a `JsonWebKey` serialized in CBOR is **not** compliant
+/// with the [CBOR Object Signing and Encryption spec][COSE] (COSE). It can still be a good
+/// way to decrease the serialized key size.
+///
+/// # Conversions
+///
+/// A JWK can be obtained from signing and verifying keys defined in the [`alg`](crate::alg)
+/// module via [`From`] / [`Into`] traits. Conversion from a JWK to a specific key is fallible
+/// and can be performed via [`TryFrom`] with [`JwkError`] as an error
+/// type.
+///
+/// As a part of conversion for asymmetric signing keys, it is checked whether
+/// the signing and verifying parts of the JWK match; [`JwkError::MismatchedKeys`] is returned
+/// otherwise. This check is **not** performed for verifying keys even if the necessary data
+/// is present in the provided JWK.
+///
+/// ⚠ **Warning.** Conversions for private RSA keys are not fully compliant with [RFC 7518].
+/// See the docs for the relevant `impl`s for more details.
+///
+/// [RFC 7518]: https://tools.ietf.org/html/rfc7518#section-6
+/// [JWK]: https://tools.ietf.org/html/rfc7517.html
+/// [COSE]: https://tools.ietf.org/html/rfc8152
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(tag = "kty")]
+#[non_exhaustive]
+pub enum JsonWebKey<'a> {
+    /// Public or private RSA key. Has `kty` field set to `RSA`.
+    #[serde(rename = "RSA")]
+    Rsa {
+        /// Key modulus (`n`).
+        #[serde(rename = "n", with = "base64url")]
+        modulus: Cow<'a, [u8]>,
+        /// Public exponent (`e`).
+        #[serde(rename = "e", with = "base64url")]
+        public_exponent: Cow<'a, [u8]>,
+        /// Private RSA parameters. Only present for private keys.
+        #[serde(flatten)]
+        private_parts: Option<RsaPrivateParts<'a>>,
+    },
+    /// Public or private key in an ECDSA crypto system. Has `kty` field set to `EC`.
+    #[serde(rename = "EC")]
+    EllipticCurve {
+        /// Curve name (`crv`), such as `secp256k1`.
+        #[serde(rename = "crv")]
+        curve: Cow<'a, str>,
+        /// `x` coordinate of the curve point.
+        #[serde(with = "base64url")]
+        x: Cow<'a, [u8]>,
+        /// `y` coordinate of the curve point.
+        #[serde(with = "base64url")]
+        y: Cow<'a, [u8]>,
+        /// Secret scalar (`d`); not present for public keys.
+        #[serde(rename = "d", default, skip_serializing_if = "Option::is_none")]
+        secret: Option<SecretBytes<'a>>,
+    },
+    /// Generic symmetric key, e.g. for `HS256` algorithm. Has `kty` field set to `oct`.
+    #[serde(rename = "oct")]
+    Symmetric {
+        /// Bytes representing this key.
+        #[serde(rename = "k")]
+        secret: SecretBytes<'a>,
+    },
+    /// Generic asymmetric keypair. This key type is used e.g. for Ed25519 keys.
+    #[serde(rename = "OKP")]
+    KeyPair {
+        /// Curve name (`crv`), such as `Ed25519`.
+        #[serde(rename = "crv")]
+        curve: Cow<'a, str>,
+        /// Public key. For Ed25519, this is the standard 32-byte public key presentation
+        /// (`x` coordinate of a point on the curve + sign).
+        #[serde(with = "base64url")]
+        x: Cow<'a, [u8]>,
+        /// Secret key (`d`). For Ed25519, this is the seed.
+        #[serde(rename = "d", default, skip_serializing_if = "Option::is_none")]
+        secret: Option<SecretBytes<'a>>,
+    },
+}
+
+impl JsonWebKey<'_> {
+    /// Gets the type of this key.
+    pub fn key_type(&self) -> KeyType {
+        match self {
+            Self::Rsa { .. } => KeyType::Rsa,
+            Self::EllipticCurve { .. } => KeyType::EllipticCurve,
+            Self::Symmetric { .. } => KeyType::Symmetric,
+            Self::KeyPair { .. } => KeyType::KeyPair,
+        }
+    }
+
+    /// Returns `true` if this key can be used for signing (has [`SecretBytes`] fields).
+    pub fn is_signing_key(&self) -> bool {
+        match self {
+            Self::Rsa { private_parts, .. } => private_parts.is_some(),
+            Self::EllipticCurve { secret, .. } | Self::KeyPair { secret, .. } => secret.is_some(),
+            Self::Symmetric { .. } => true,
+        }
+    }
+
+    /// Returns a copy of this key with parts not necessary for signature verification removed.
+    #[must_use]
+    pub fn to_verifying_key(&self) -> Self {
+        match self {
+            Self::Rsa {
+                modulus,
+                public_exponent,
+                ..
+            } => Self::Rsa {
+                modulus: modulus.clone(),
+                public_exponent: public_exponent.clone(),
+                private_parts: None,
+            },
+
+            Self::EllipticCurve { curve, x, y, .. } => Self::EllipticCurve {
+                curve: curve.clone(),
+                x: x.clone(),
+                y: y.clone(),
+                secret: None,
+            },
+
+            Self::Symmetric { secret } => Self::Symmetric {
+                secret: secret.clone(),
+            },
+
+            Self::KeyPair { curve, x, .. } => Self::KeyPair {
+                curve: curve.clone(),
+                x: x.clone(),
+                secret: None,
+            },
+        }
+    }
+
+    /// Computes a thumbprint of this JWK. The result complies with the key thumbprint defined
+    /// in [RFC 7638].
+    ///
+    /// [RFC 7638]: https://tools.ietf.org/html/rfc7638
+    pub fn thumbprint<D: Digest>(&self) -> Output<D> {
+        let hashed_key = if self.is_signing_key() {
+            Cow::Owned(self.to_verifying_key())
+        } else {
+            Cow::Borrowed(self)
+        };
+        D::digest(hashed_key.to_string().as_bytes())
+    }
+}
+
+impl fmt::Display for JsonWebKey<'_> {
+    // TODO: Not the most efficient approach
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let json_value = serde_json::to_value(self).expect("Cannot convert JsonWebKey to JSON");
+        let json_value = json_value.as_object().unwrap();
+        // ^ unwrap() is safe: `JsonWebKey` serialization is always an object.
+
+        let mut json_entries: Vec<_> = json_value.iter().collect();
+        json_entries.sort_unstable_by(|(x, _), (y, _)| x.cmp(y));
+
+        formatter.write_str("{")?;
+        let field_count = json_entries.len();
+        for (i, (name, value)) in json_entries.into_iter().enumerate() {
+            write!(formatter, "\"{name}\":{value}")?;
+            if i + 1 < field_count {
+                formatter.write_str(",")?;
+            }
+        }
+        formatter.write_str("}")
+    }
+}
+
+/// Parts of [`JsonWebKey::Rsa`] that are specific to private keys.
+///
+/// # Serialization
+///
+/// Fields of this struct are serialized using the big endian presentation
+/// with the minimum necessary number of bytes. See [`JsonWebKey` notes](JsonWebKey#serialization)
+/// on encoding.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct RsaPrivateParts<'a> {
+    /// Private exponent (`d`).
+    #[serde(rename = "d")]
+    pub private_exponent: SecretBytes<'a>,
+    /// First prime factor (`p`).
+    #[serde(rename = "p")]
+    pub prime_factor_p: SecretBytes<'a>,
+    /// Second prime factor (`q`).
+    #[serde(rename = "q")]
+    pub prime_factor_q: SecretBytes<'a>,
+    /// First factor CRT exponent (`dp`).
+    #[serde(rename = "dp", default, skip_serializing_if = "Option::is_none")]
+    pub p_crt_exponent: Option<SecretBytes<'a>>,
+    /// Second factor CRT exponent (`dq`).
+    #[serde(rename = "dq", default, skip_serializing_if = "Option::is_none")]
+    pub q_crt_exponent: Option<SecretBytes<'a>>,
+    /// CRT coefficient of the second factor (`qi`).
+    #[serde(rename = "qi", default, skip_serializing_if = "Option::is_none")]
+    pub q_crt_coefficient: Option<SecretBytes<'a>>,
+    /// Other prime factors.
+    #[serde(rename = "oth", default, skip_serializing_if = "Vec::is_empty")]
+    pub other_prime_factors: Vec<RsaPrimeFactor<'a>>,
+}
+
+/// Block for an additional prime factor in [`RsaPrivateParts`].
+///
+/// # Serialization
+///
+/// Fields of this struct are serialized using the big endian presentation
+/// with the minimum necessary number of bytes. See [`JsonWebKey` notes](JsonWebKey#serialization)
+/// on encoding.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct RsaPrimeFactor<'a> {
+    /// Prime factor (`r`).
+    #[serde(rename = "r")]
+    pub factor: SecretBytes<'a>,
+    /// Factor CRT exponent (`d`).
+    #[serde(rename = "d", default, skip_serializing_if = "Option::is_none")]
+    pub crt_exponent: Option<SecretBytes<'a>>,
+    /// Factor CRT coefficient (`t`).
+    #[serde(rename = "t", default, skip_serializing_if = "Option::is_none")]
+    pub crt_coefficient: Option<SecretBytes<'a>>,
+}
+
+#[cfg(any(
+    feature = "es256k",
+    feature = "k256",
+    feature = "exonum-crypto",
+    feature = "ed25519-dalek",
+    feature = "ed25519-compact"
+))]
+mod helpers {
+    use super::{JsonWebKey, JwkError};
+    use crate::{alg::SigningKey, alloc::ToOwned, Algorithm};
+
+    impl JsonWebKey<'_> {
+        pub(crate) fn ensure_curve(curve: &str, expected: &str) -> Result<(), JwkError> {
+            if curve == expected {
+                Ok(())
+            } else {
+                Err(JwkError::UnexpectedValue {
+                    field: "crv".to_owned(),
+                    expected: expected.to_owned(),
+                    actual: curve.to_owned(),
+                })
+            }
+        }
+
+        pub(crate) fn ensure_len(
+            field: &str,
+            bytes: &[u8],
+            expected_len: usize,
+        ) -> Result<(), JwkError> {
+            if bytes.len() == expected_len {
+                Ok(())
+            } else {
+                Err(JwkError::UnexpectedLen {
+                    field: field.to_owned(),
+                    expected: expected_len,
+                    actual: bytes.len(),
+                })
+            }
+        }
+
+        /// Ensures that the provided signing key matches the verifying key restored from the same JWK.
+        /// This is useful when implementing [`TryFrom`] conversion from `JsonWebKey` for private keys.
+        pub(crate) fn ensure_key_match<Alg, K>(&self, signing_key: K) -> Result<K, JwkError>
+        where
+            Alg: Algorithm<SigningKey = K>,
+            K: SigningKey<Alg>,
+            Alg::VerifyingKey: for<'jwk> TryFrom<&'jwk Self, Error = JwkError> + PartialEq,
+        {
+            let verifying_key = <Alg::VerifyingKey>::try_from(self)?;
+            if verifying_key == signing_key.to_verifying_key() {
+                Ok(signing_key)
+            } else {
+                Err(JwkError::MismatchedKeys)
+            }
+        }
+    }
+}
+
+mod base64url {
+    use base64ct::{Base64UrlUnpadded, Encoding};
+    use serde::{
+        de::{Error as DeError, Unexpected, Visitor},
+        Deserializer, Serializer,
+    };
+
+    use core::fmt;
+
+    use crate::alloc::{Cow, Vec};
+
+    pub fn serialize<S>(value: &[u8], serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        if serializer.is_human_readable() {
+            serializer.serialize_str(&Base64UrlUnpadded::encode_string(value))
+        } else {
+            serializer.serialize_bytes(value)
+        }
+    }
+
+    pub fn deserialize<'de, D>(deserializer: D) -> Result<Cow<'static, [u8]>, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        struct Base64Visitor;
+
+        impl Visitor<'_> for Base64Visitor {
+            type Value = Vec<u8>;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                formatter.write_str("base64url-encoded data")
+            }
+
+            fn visit_str<E: DeError>(self, value: &str) -> Result<Self::Value, E> {
+                Base64UrlUnpadded::decode_vec(value)
+                    .map_err(|_| E::invalid_value(Unexpected::Str(value), &self))
+            }
+
+            fn visit_bytes<E: DeError>(self, value: &[u8]) -> Result<Self::Value, E> {
+                Ok(value.to_vec())
+            }
+
+            fn visit_byte_buf<E: DeError>(self, value: Vec<u8>) -> Result<Self::Value, E> {
+                Ok(value)
+            }
+        }
+
+        struct BytesVisitor;
+
+        impl<'de> Visitor<'de> for BytesVisitor {
+            type Value = Vec<u8>;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                formatter.write_str("byte buffer")
+            }
+
+            fn visit_bytes<E: DeError>(self, value: &[u8]) -> Result<Self::Value, E> {
+                Ok(value.to_vec())
+            }
+
+            fn visit_byte_buf<E: DeError>(self, value: Vec<u8>) -> Result<Self::Value, E> {
+                Ok(value)
+            }
+        }
+
+        let maybe_bytes = if deserializer.is_human_readable() {
+            deserializer.deserialize_str(Base64Visitor)
+        } else {
+            deserializer.deserialize_bytes(BytesVisitor)
+        };
+        maybe_bytes.map(Cow::Owned)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::alg::Hs256Key;
+
+    use assert_matches::assert_matches;
+
+    fn create_jwk() -> JsonWebKey<'static> {
+        JsonWebKey::KeyPair {
+            curve: Cow::Borrowed("Ed25519"),
+            x: Cow::Borrowed(b"test"),
+            secret: None,
+        }
+    }
+
+    #[test]
+    fn serializing_jwk() {
+        let jwk = create_jwk();
+
+        let json = serde_json::to_value(&jwk).unwrap();
+        assert_eq!(
+            json,
+            serde_json::json!({ "crv": "Ed25519", "kty": "OKP", "x": "dGVzdA" })
+        );
+
+        let restored: JsonWebKey<'_> = serde_json::from_value(json).unwrap();
+        assert_eq!(restored, jwk);
+    }
+
+    #[test]
+    fn jwk_deserialization_errors() {
+        let missing_field_json = r#"{"crv":"Ed25519"}"#;
+        let missing_field_err = serde_json::from_str::<JsonWebKey<'_>>(missing_field_json)
+            .unwrap_err()
+            .to_string();
+        assert!(
+            missing_field_err.contains("missing field `kty`"),
+            "{missing_field_err}"
+        );
+
+        let base64_json = r#"{"crv":"Ed25519","kty":"OKP","x":"??"}"#;
+        let base64_err = serde_json::from_str::<JsonWebKey<'_>>(base64_json)
+            .unwrap_err()
+            .to_string();
+        assert!(
+            base64_err.contains("invalid value: string \"??\""),
+            "{base64_err}"
+        );
+        assert!(
+            base64_err.contains("base64url-encoded data"),
+            "{base64_err}"
+        );
+    }
+
+    #[test]
+    fn extra_jwk_fields() {
+        #[derive(Debug, Serialize, Deserialize)]
+        struct ExtendedJsonWebKey<'a, T> {
+            #[serde(flatten)]
+            base: JsonWebKey<'a>,
+            #[serde(flatten)]
+            extra: T,
+        }
+
+        #[derive(Debug, Deserialize)]
+        struct Extra {
+            #[serde(rename = "kid")]
+            key_id: String,
+            #[serde(rename = "use")]
+            key_use: KeyUse,
+        }
+
+        #[derive(Debug, Deserialize, PartialEq)]
+        enum KeyUse {
+            #[serde(rename = "sig")]
+            Signature,
+            #[serde(rename = "enc")]
+            Encryption,
+        }
+
+        let json_str = r#"
+            { "kty": "oct", "kid": "my-unique-key", "k": "dGVzdA", "use": "sig" }
+        "#;
+        let jwk: ExtendedJsonWebKey<'_, Extra> = serde_json::from_str(json_str).unwrap();
+
+        assert_matches!(&jwk.base, JsonWebKey::Symmetric { secret } if secret.as_ref() == b"test");
+        assert_eq!(jwk.extra.key_id, "my-unique-key");
+        assert_eq!(jwk.extra.key_use, KeyUse::Signature);
+
+        let key = Hs256Key::try_from(&jwk.base).unwrap();
+        let jwk_from_key = JsonWebKey::from(&key);
+
+        assert_matches!(
+            jwk_from_key,
+            JsonWebKey::Symmetric { secret } if secret.as_ref() == b"test"
+        );
+    }
+
+    #[test]
+    #[cfg(feature = "ciborium")]
+    fn jwk_with_cbor() {
+        let key = JsonWebKey::KeyPair {
+            curve: Cow::Borrowed("Ed25519"),
+            x: Cow::Borrowed(b"public"),
+            secret: Some(SecretBytes::borrowed(b"private")),
+        };
+        let mut bytes = vec![];
+        ciborium::into_writer(&key, &mut bytes).unwrap();
+        assert!(bytes.windows(6).any(|window| window == b"public"));
+        assert!(bytes.windows(7).any(|window| window == b"private"));
+
+        let restored: JsonWebKey<'_> = ciborium::from_reader(&bytes[..]).unwrap();
+        assert_eq!(restored, key);
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/lib.rs.html b/src/jwt_compact/lib.rs.html new file mode 100644 index 00000000..cf4a29af --- /dev/null +++ b/src/jwt_compact/lib.rs.html @@ -0,0 +1,555 @@ +lib.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+
//! Minimalistic [JSON web token (JWT)][JWT] implementation with focus on type safety
+//! and secure cryptographic primitives.
+//!
+//! # Design choices
+//!
+//! - JWT signature algorithms (i.e., cryptographic algorithms providing JWT integrity)
+//!   are expressed via the [`Algorithm`] trait, which uses fully typed keys and signatures.
+//! - [JWT header] is represented by the [`Header`] struct. Notably, `Header` does not
+//!   expose the [`alg` field].
+//!   Instead, `alg` is filled automatically during token creation, and is compared to the
+//!   expected value during verification. (If you do not know the JWT signature algorithm during
+//!   verification, you're doing something wrong.) This eliminates the possibility
+//!   of [algorithm switching attacks][switching].
+//!
+//! # Additional features
+//!
+//! - The crate supports more compact [CBOR] encoding of the claims. This feature is enabled
+//!   via the [`ciborium` feature](#cbor-support).
+//! - The crate supports `EdDSA` algorithm with the Ed25519 elliptic curve, and `ES256K` algorithm
+//!   with the secp256k1 elliptic curve.
+//! - Supports basic [JSON Web Key](https://tools.ietf.org/html/rfc7517.html) functionality,
+//!   e.g., for converting keys to / from JSON or computing
+//!   [a key thumbprint](https://tools.ietf.org/html/rfc7638).
+//!
+//! ## Supported algorithms
+//!
+//! | Algorithm(s) | Feature | Description |
+//! |--------------|---------|-------------|
+//! | `HS256`, `HS384`, `HS512` | - | Uses pure Rust [`sha2`] crate |
+//! | `EdDSA` (Ed25519) | [`exonum-crypto`] | [`libsodium`] binding |
+//! | `EdDSA` (Ed25519) | [`ed25519-dalek`] | Pure Rust implementation |
+//! | `EdDSA` (Ed25519) | [`ed25519-compact`] | Compact pure Rust implementation, WASM-compatible |
+//! | `ES256K` | `es256k` | [Rust binding][`secp256k1`] for [`libsecp256k1`] |
+//! | `ES256K` | [`k256`] | Pure Rust implementation |
+//! | `ES256`  | [`p256`] | Pure Rust implementation |
+//! | `RS*`, `PS*` (RSA) | `rsa` | Uses pure Rust [`rsa`] crate with blinding |
+//!
+//! Beware that the `rsa` crate (along with other RSA implementations) may be susceptible to
+//! [the "Marvin" timing side-channel attack](https://github.com/RustCrypto/RSA/security/advisories/GHSA-c38w-74pg-36hr)
+//! at the time of writing; use with caution.
+//!
+//! `EdDSA` and `ES256K` algorithms are somewhat less frequently supported by JWT implementations
+//! than others since they are recent additions to the JSON Web Algorithms (JWA) suit.
+//! They both work with elliptic curves
+//! (Curve25519 and secp256k1; both are widely used in crypto community and believed to be
+//! securely generated). These algs have 128-bit security, making them an alternative
+//! to `ES256`.
+//!
+//! RSA support requires a system-wide RNG retrieved via the [`getrandom`] crate.
+//! In case of a compilation failure in the `getrandom` crate, you may want
+//! to include it as a direct dependency and specify one of its features
+//! to assist `getrandom` with choosing an appropriate RNG implementation; consult `getrandom` docs
+//! for more details. See also WASM and bare-metal E2E tests included
+//! in the [source code repository] of this crate.
+//!
+//! ## CBOR support
+//!
+//! If the `ciborium` crate feature is enabled (and it is enabled by default), token claims can
+//! be encoded using [CBOR] with the [`AlgorithmExt::compact_token()`] method.
+//! The compactly encoded JWTs have the [`cty` field] (content type) in their header
+//! set to `"CBOR"`. Tokens with such encoding can be verified in the same way as ordinary tokens;
+//! see [examples below](#examples).
+//!
+//! If the `ciborium` feature is disabled, `AlgorithmExt::compact_token()` is not available.
+//! Verifying CBOR-encoded tokens in this case is not supported either;
+//! a [`ParseError::UnsupportedContentType`] will be returned when creating an [`UntrustedToken`]
+//! from the token string.
+//!
+//! # `no_std` support
+//!
+//! The crate supports a `no_std` compilation mode. This is controlled by two features:
+//! `clock` and `std`; both are on by default.
+//!
+//! - The `clock` feature enables getting the current time using `Utc::now()` from [`chrono`].
+//!   Without it, some [`TimeOptions`] constructors, such as the `Default` impl,
+//!   are not available. It is still possible to create `TimeOptions` with an explicitly specified
+//!   clock function, or to set / verify time-related [`Claims`] fields manually.
+//! - The `std` feature is propagated to the core dependencies and enables `std`-specific
+//!   functionality (such as error types implementing the standard `Error` trait).
+//!
+//! Some `alloc` types are still used in the `no_std` mode, such as `String`, `Vec` and `Cow`.
+//!
+//! Note that not all crypto backends are `no_std`-compatible.
+//!
+//! [JWT]: https://jwt.io/
+//! [switching]: https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
+//! [JWT header]: https://tools.ietf.org/html/rfc7519#section-5
+//! [`alg` field]: https://tools.ietf.org/html/rfc7515#section-4.1.1
+//! [`cty` field]: https://tools.ietf.org/html/rfc7515#section-4.1.10
+//! [CBOR]: https://tools.ietf.org/html/rfc7049
+//! [`sha2`]: https://docs.rs/sha2/
+//! [`libsodium`]: https://download.libsodium.org/doc/
+//! [`exonum-crypto`]: https://docs.rs/exonum-crypto/
+//! [`ed25519-dalek`]: https://doc.dalek.rs/ed25519_dalek/
+//! [`ed25519-compact`]: https://crates.io/crates/ed25519-compact
+//! [`secp256k1`]: https://docs.rs/secp256k1/
+//! [`libsecp256k1`]: https://github.com/bitcoin-core/secp256k1
+//! [`k256`]: https://docs.rs/k256/
+//! [`p256`]: https://docs.rs/p256/
+//! [`rsa`]: https://docs.rs/rsa/
+//! [`chrono`]: https://docs.rs/chrono/
+//! [`getrandom`]: https://docs.rs/getrandom/
+//! [source code repository]: https://github.com/slowli/jwt-compact
+//!
+//! # Examples
+//!
+//! Basic JWT lifecycle:
+//!
+//! ```
+//! use chrono::{Duration, Utc};
+//! use jwt_compact::{prelude::*, alg::{Hs256, Hs256Key}};
+//! use serde::{Serialize, Deserialize};
+//!
+//! /// Custom claims encoded in the token.
+//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
+//! struct CustomClaims {
+//!     /// `sub` is a standard claim which denotes claim subject:
+//!     /// https://tools.ietf.org/html/rfc7519#section-4.1.2
+//!     #[serde(rename = "sub")]
+//!     subject: String,
+//! }
+//!
+//! # fn main() -> anyhow::Result<()> {
+//! // Choose time-related options for token creation / validation.
+//! let time_options = TimeOptions::default();
+//! // Create a symmetric HMAC key, which will be used both to create and verify tokens.
+//! let key = Hs256Key::new(b"super_secret_key_donut_steel");
+//! // Create a token.
+//! let header = Header::empty().with_key_id("my-key");
+//! let claims = Claims::new(CustomClaims { subject: "alice".to_owned() })
+//!     .set_duration_and_issuance(&time_options, Duration::days(7))
+//!     .set_not_before(Utc::now() - Duration::hours(1));
+//! let token_string = Hs256.token(&header, &claims, &key)?;
+//! println!("token: {token_string}");
+//!
+//! // Parse the token.
+//! let token = UntrustedToken::new(&token_string)?;
+//! // Before verifying the token, we might find the key which has signed the token
+//! // using the `Header.key_id` field.
+//! assert_eq!(token.header().key_id, Some("my-key".to_owned()));
+//! // Validate the token integrity.
+//! let token: Token<CustomClaims> = Hs256.validator(&key).validate(&token)?;
+//! // Validate additional conditions.
+//! token.claims()
+//!     .validate_expiration(&time_options)?
+//!     .validate_maturity(&time_options)?;
+//! // Now, we can extract information from the token (e.g., its subject).
+//! let subject = &token.claims().custom.subject;
+//! assert_eq!(subject, "alice");
+//! # Ok(())
+//! # } // end main()
+//! ```
+//!
+//! ## Compact JWT
+//!
+//! ```
+//! # use chrono::Duration;
+//! # use hex_buffer_serde::{Hex as _, HexForm};
+//! # use jwt_compact::{prelude::*, alg::{Hs256, Hs256Key}};
+//! # use serde::{Serialize, Deserialize};
+//! /// Custom claims encoded in the token.
+//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
+//! struct CustomClaims {
+//!     /// `sub` is a standard claim which denotes claim subject:
+//!     ///     https://tools.ietf.org/html/rfc7519#section-4.1.2
+//!     /// The custom serializer we use allows to efficiently
+//!     /// encode the subject in CBOR.
+//!     #[serde(rename = "sub", with = "HexForm")]
+//!     subject: [u8; 32],
+//! }
+//!
+//! # fn main() -> anyhow::Result<()> {
+//! let time_options = TimeOptions::default();
+//! let key = Hs256Key::new(b"super_secret_key_donut_steel");
+//! let claims = Claims::new(CustomClaims { subject: [111; 32] })
+//!     .set_duration_and_issuance(&time_options, Duration::days(7));
+//! let token = Hs256.token(&Header::empty(), &claims, &key)?;
+//! println!("token: {token}");
+//! let compact_token = Hs256.compact_token(&Header::empty(), &claims, &key)?;
+//! println!("compact token: {compact_token}");
+//! // The compact token should be ~40 chars shorter.
+//!
+//! // Parse the compact token.
+//! let token = UntrustedToken::new(&compact_token)?;
+//! let token: Token<CustomClaims> = Hs256.validator(&key).validate(&token)?;
+//! token.claims().validate_expiration(&time_options)?;
+//! // Now, we can extract information from the token (e.g., its subject).
+//! assert_eq!(token.claims().custom.subject, [111; 32]);
+//! # Ok(())
+//! # } // end main()
+//! ```
+//!
+//! ## JWT with custom header fields
+//!
+//! ```
+//! # use chrono::Duration;
+//! # use jwt_compact::{prelude::*, alg::{Hs256, Hs256Key}};
+//! # use serde::{Deserialize, Serialize};
+//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
+//! struct CustomClaims { subject: [u8; 32] }
+//!
+//! /// Additional fields in the token header.
+//! #[derive(Debug, Clone, Serialize, Deserialize)]
+//! struct HeaderExtensions { custom: bool }
+//!
+//! # fn main() -> anyhow::Result<()> {
+//! let time_options = TimeOptions::default();
+//! let key = Hs256Key::new(b"super_secret_key_donut_steel");
+//! let claims = Claims::new(CustomClaims { subject: [111; 32] })
+//!     .set_duration_and_issuance(&time_options, Duration::days(7));
+//! let header = Header::new(HeaderExtensions { custom: true })
+//!     .with_key_id("my-key");
+//! let token = Hs256.token(&header, &claims, &key)?;
+//! print!("token: {token}");
+//!
+//! // Parse the token.
+//! let token: UntrustedToken<HeaderExtensions> =
+//!     token.as_str().try_into()?;
+//! // Token header (incl. custom fields) can be accessed right away.
+//! assert_eq!(token.header().key_id.as_deref(), Some("my-key"));
+//! assert!(token.header().other_fields.custom);
+//! // Token can then be validated as usual.
+//! let token = Hs256.validator::<CustomClaims>(&key).validate(&token)?;
+//! assert_eq!(token.claims().custom.subject, [111; 32]);
+//! # Ok(())
+//! # } // end main()
+//! ```
+
+#![cfg_attr(not(feature = "std"), no_std)]
+// Documentation settings.
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![doc(html_root_url = "https://docs.rs/jwt-compact/0.8.0")]
+// Linter settings.
+#![warn(missing_debug_implementations, missing_docs, bare_trait_objects)]
+#![warn(clippy::all, clippy::pedantic)]
+#![allow(
+    clippy::missing_errors_doc,
+    clippy::must_use_candidate,
+    clippy::module_name_repetitions
+)]
+
+pub mod alg;
+mod claims;
+mod error;
+pub mod jwk;
+mod token;
+mod traits;
+
+// Polyfill for `alloc` types.
+mod alloc {
+    #[cfg(not(feature = "std"))]
+    extern crate alloc as std;
+
+    pub use std::{
+        borrow::{Cow, ToOwned},
+        boxed::Box,
+        format,
+        string::{String, ToString},
+        vec::Vec,
+    };
+}
+
+/// Prelude to neatly import all necessary stuff from the crate.
+pub mod prelude {
+    #[doc(no_inline)]
+    pub use crate::{AlgorithmExt as _, Claims, Header, TimeOptions, Token, UntrustedToken};
+}
+
+pub use crate::{
+    claims::{Claims, Empty, TimeOptions},
+    error::{Claim, CreationError, ParseError, ValidationError},
+    token::{Header, SignedToken, Thumbprint, Token, UntrustedToken},
+    traits::{Algorithm, AlgorithmExt, AlgorithmSignature, Renamed, Validator},
+};
+
+#[cfg(doctest)]
+doc_comment::doctest!("../README.md");
+
\ No newline at end of file diff --git a/src/jwt_compact/token.rs.html b/src/jwt_compact/token.rs.html new file mode 100644 index 00000000..c7f155bd --- /dev/null +++ b/src/jwt_compact/token.rs.html @@ -0,0 +1,1801 @@ +token.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+
//! `Token` and closely related types.
+
+use base64ct::{Base64UrlUnpadded, Encoding};
+use serde::{
+    de::{DeserializeOwned, Error as DeError, Visitor},
+    Deserialize, Deserializer, Serialize, Serializer,
+};
+use smallvec::{smallvec, SmallVec};
+
+use core::{cmp, fmt};
+
+#[cfg(feature = "ciborium")]
+use crate::error::CborDeError;
+use crate::{
+    alloc::{format, Cow, String, Vec},
+    Algorithm, Claims, Empty, ParseError, ValidationError,
+};
+
+/// Maximum "reasonable" signature size in bytes.
+const SIGNATURE_SIZE: usize = 128;
+
+/// Representation of a X.509 certificate thumbprint (`x5t` and `x5t#S256` fields in
+/// the JWT [`Header`]).
+///
+/// As per the JWS spec in [RFC 7515], a certificate thumbprint (i.e., the SHA-1 / SHA-256
+/// digest of the certificate) must be base64url-encoded. Some JWS implementations however
+/// encode not the thumbprint itself, but rather its hex encoding, sometimes even
+/// with additional chars spliced within. To account for these implementations,
+/// a thumbprint is represented as an enum – either a properly encoded hash digest,
+/// or an opaque base64-encoded string.
+///
+/// [RFC 7515]: https://www.rfc-editor.org/rfc/rfc7515.html
+///
+/// # Examples
+///
+/// ```
+/// # use assert_matches::assert_matches;
+/// # use jwt_compact::{
+/// #     alg::{Hs256, Hs256Key}, AlgorithmExt, Claims, Header, Thumbprint, UntrustedToken,
+/// # };
+/// # fn main() -> anyhow::Result<()> {
+/// let key = Hs256Key::new(b"super_secret_key_donut_steel");
+///
+/// // Creates a token with a custom-encoded SHA-1 thumbprint.
+/// let thumbprint = "65:AF:69:09:B1:B0:75:8E:06:C6:E0:48:C4:60:02:B5:C6:95:E3:6B";
+/// let header = Header::empty()
+///     .with_key_id("my_key")
+///     .with_certificate_sha1_thumbprint(thumbprint);
+/// let token = Hs256.token(&header, &Claims::empty(), &key)?;
+/// println!("{token}");
+///
+/// // Deserialize the token and check that its header fields are readable.
+/// let token = UntrustedToken::new(&token)?;
+/// let deserialized_thumbprint =
+///     token.header().certificate_sha1_thumbprint.as_ref();
+/// assert_matches!(
+///     deserialized_thumbprint,
+///     Some(Thumbprint::String(s)) if s == thumbprint
+/// );
+/// # Ok(())
+/// # }
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[non_exhaustive]
+pub enum Thumbprint<const N: usize> {
+    /// Byte representation of a SHA-1 or SHA-256 digest.
+    Bytes([u8; N]),
+    /// Opaque string representation of the thumbprint. It is the responsibility
+    /// of an application to verify that this value is valid.
+    String(String),
+}
+
+impl<const N: usize> From<[u8; N]> for Thumbprint<N> {
+    fn from(value: [u8; N]) -> Self {
+        Self::Bytes(value)
+    }
+}
+
+impl<const N: usize> From<String> for Thumbprint<N> {
+    fn from(s: String) -> Self {
+        Self::String(s)
+    }
+}
+
+impl<const N: usize> From<&str> for Thumbprint<N> {
+    fn from(s: &str) -> Self {
+        Self::String(s.into())
+    }
+}
+
+impl<const N: usize> Serialize for Thumbprint<N> {
+    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+        let input = match self {
+            Self::Bytes(bytes) => bytes.as_slice(),
+            Self::String(s) => s.as_bytes(),
+        };
+        serializer.serialize_str(&Base64UrlUnpadded::encode_string(input))
+    }
+}
+
+impl<'de, const N: usize> Deserialize<'de> for Thumbprint<N> {
+    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+        struct Base64Visitor<const L: usize>;
+
+        impl<const L: usize> Visitor<'_> for Base64Visitor<L> {
+            type Value = Thumbprint<L>;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                write!(formatter, "base64url-encoded thumbprint")
+            }
+
+            fn visit_str<E: DeError>(self, mut value: &str) -> Result<Self::Value, E> {
+                // Allow for padding. RFC 7515 defines base64url encoding as one without padding:
+                //
+                // > Base64url Encoding: Base64 encoding using the URL- and filename-safe
+                // > character set defined in Section 5 of RFC 4648 [RFC4648], with all trailing '='
+                // > characters omitted [...]
+                //
+                // ...but it's easy to trim the padding, so we support it anyway.
+                //
+                // See: https://www.rfc-editor.org/rfc/rfc7515.html#section-2
+                for _ in 0..2 {
+                    if value.as_bytes().last() == Some(&b'=') {
+                        value = &value[..value.len() - 1];
+                    }
+                }
+
+                let decoded_len = value.len() * 3 / 4;
+                match decoded_len.cmp(&L) {
+                    cmp::Ordering::Less => Err(E::custom(format!(
+                        "thumbprint must contain at least {L} bytes"
+                    ))),
+                    cmp::Ordering::Equal => {
+                        let mut bytes = [0_u8; L];
+                        let len = Base64UrlUnpadded::decode(value, &mut bytes)
+                            .map_err(E::custom)?
+                            .len();
+                        debug_assert_eq!(len, L);
+                        Ok(bytes.into())
+                    }
+                    cmp::Ordering::Greater => {
+                        let decoded = Base64UrlUnpadded::decode_vec(value).map_err(E::custom)?;
+                        let decoded = String::from_utf8(decoded)
+                            .map_err(|err| E::custom(err.utf8_error()))?;
+                        Ok(decoded.into())
+                    }
+                }
+            }
+        }
+
+        deserializer.deserialize_str(Base64Visitor)
+    }
+}
+
+/// JWT header.
+///
+/// See [RFC 7515](https://tools.ietf.org/html/rfc7515#section-4.1) for the description
+/// of the fields. The purpose of all fields except `token_type` is to determine
+/// the verifying key. Since these values will be provided by the adversary in the case of
+/// an attack, they require additional verification (e.g., a provided certificate might
+/// be checked against the list of "acceptable" certificate authorities).
+///
+/// A `Header` can be created using `Default` implementation, which does not set any fields.
+/// For added fluency, you may use `with_*` methods:
+///
+/// ```
+/// # use jwt_compact::Header;
+/// use sha2::{digest::Digest, Sha256};
+///
+/// let my_key_cert = // DER-encoded key certificate
+/// #   b"Hello, world!";
+/// let thumbprint: [u8; 32] = Sha256::digest(my_key_cert).into();
+/// let header = Header::empty()
+///     .with_key_id("my-key-id")
+///     .with_certificate_thumbprint(thumbprint);
+/// ```
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[non_exhaustive]
+pub struct Header<T = Empty> {
+    /// URL of the JSON Web Key Set containing the key that has signed the token.
+    /// This field is renamed to [`jku`] for serialization.
+    ///
+    /// [`jku`]: https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.2
+    #[serde(rename = "jku", default, skip_serializing_if = "Option::is_none")]
+    pub key_set_url: Option<String>,
+
+    /// Identifier of the key that has signed the token. This field is renamed to [`kid`]
+    /// for serialization.
+    ///
+    /// [`kid`]: https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.4
+    #[serde(rename = "kid", default, skip_serializing_if = "Option::is_none")]
+    pub key_id: Option<String>,
+
+    /// URL of the X.509 certificate for the signing key. This field is renamed to [`x5u`]
+    /// for serialization.
+    ///
+    /// [`x5u`]: https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.5
+    #[serde(rename = "x5u", default, skip_serializing_if = "Option::is_none")]
+    pub certificate_url: Option<String>,
+
+    /// SHA-1 thumbprint of the X.509 certificate for the signing key.
+    /// This field is renamed to [`x5t`] for serialization.
+    ///
+    /// [`x5t`]: https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.7
+    #[serde(rename = "x5t", default, skip_serializing_if = "Option::is_none")]
+    pub certificate_sha1_thumbprint: Option<Thumbprint<20>>,
+
+    /// SHA-256 thumbprint of the X.509 certificate for the signing key.
+    /// This field is renamed to [`x5t#S256`] for serialization.
+    ///
+    /// [`x5t#S256`]: https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.8
+    #[serde(rename = "x5t#S256", default, skip_serializing_if = "Option::is_none")]
+    pub certificate_thumbprint: Option<Thumbprint<32>>,
+
+    /// Application-specific [token type]. This field is renamed to `typ` for serialization.
+    ///
+    /// [token type]: https://tools.ietf.org/html/rfc7519#section-5.1
+    #[serde(rename = "typ", default, skip_serializing_if = "Option::is_none")]
+    pub token_type: Option<String>,
+
+    /// Other fields encoded in the header. These fields may be used by agreement between
+    /// the producer and consumer of the token to pass additional information.
+    /// See Sections 4.2 and 4.3 of [RFC 7515](https://www.rfc-editor.org/rfc/rfc7515#section-4.2)
+    /// for details.
+    ///
+    /// For the token creation and validation to work properly, the fields type must [`Serialize`]
+    /// to a JSON object.
+    ///
+    /// Note that these fields do not include the signing algorithm (`alg`) and the token
+    /// content type (`cty`) since both these fields have predefined semantics and are used
+    /// internally by the crate logic.
+    #[serde(flatten)]
+    pub other_fields: T,
+}
+
+impl Header {
+    /// Creates an empty header.
+    pub const fn empty() -> Self {
+        Self {
+            key_set_url: None,
+            key_id: None,
+            certificate_url: None,
+            certificate_sha1_thumbprint: None,
+            certificate_thumbprint: None,
+            token_type: None,
+            other_fields: Empty {},
+        }
+    }
+}
+
+impl<T> Header<T> {
+    /// Creates a header with the specified custom fields.
+    pub const fn new(fields: T) -> Header<T> {
+        Header {
+            key_set_url: None,
+            key_id: None,
+            certificate_url: None,
+            certificate_sha1_thumbprint: None,
+            certificate_thumbprint: None,
+            token_type: None,
+            other_fields: fields,
+        }
+    }
+
+    /// Sets the `key_set_url` field for this header.
+    #[must_use]
+    pub fn with_key_set_url(mut self, key_set_url: impl Into<String>) -> Self {
+        self.key_set_url = Some(key_set_url.into());
+        self
+    }
+
+    /// Sets the `key_id` field for this header.
+    #[must_use]
+    pub fn with_key_id(mut self, key_id: impl Into<String>) -> Self {
+        self.key_id = Some(key_id.into());
+        self
+    }
+
+    /// Sets the `certificate_url` field for this header.
+    #[must_use]
+    pub fn with_certificate_url(mut self, certificate_url: impl Into<String>) -> Self {
+        self.certificate_url = Some(certificate_url.into());
+        self
+    }
+
+    /// Sets the `certificate_sha1_thumbprint` field for this header.
+    #[must_use]
+    pub fn with_certificate_sha1_thumbprint(
+        mut self,
+        certificate_thumbprint: impl Into<Thumbprint<20>>,
+    ) -> Self {
+        self.certificate_sha1_thumbprint = Some(certificate_thumbprint.into());
+        self
+    }
+
+    /// Sets the `certificate_thumbprint` field for this header.
+    #[must_use]
+    pub fn with_certificate_thumbprint(
+        mut self,
+        certificate_thumbprint: impl Into<Thumbprint<32>>,
+    ) -> Self {
+        self.certificate_thumbprint = Some(certificate_thumbprint.into());
+        self
+    }
+
+    /// Sets the `token_type` field for this header.
+    #[must_use]
+    pub fn with_token_type(mut self, token_type: impl Into<String>) -> Self {
+        self.token_type = Some(token_type.into());
+        self
+    }
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub(crate) struct CompleteHeader<'a, T> {
+    #[serde(rename = "alg")]
+    pub algorithm: Cow<'a, str>,
+    #[serde(rename = "cty", default, skip_serializing_if = "Option::is_none")]
+    pub content_type: Option<String>,
+    #[serde(flatten)]
+    pub inner: T,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+enum ContentType {
+    Json,
+    #[cfg(feature = "ciborium")]
+    Cbor,
+}
+
+/// Parsed, but unvalidated token.
+///
+/// The type param ([`Empty`] by default) corresponds to the [additional information] enclosed
+/// in the token [`Header`].
+///
+/// An `UntrustedToken` can be parsed from a string using the [`TryFrom`] implementation.
+/// This checks that a token is well-formed (has a header, claims and a signature),
+/// but does not validate the signature.
+/// As a shortcut, a token without additional header info can be created using [`Self::new()`].
+///
+/// [additional information]: Header#other_fields
+///
+/// # Examples
+///
+/// ```
+/// # use jwt_compact::UntrustedToken;
+/// let token_str = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJp\
+///     c3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leG\
+///     FtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJ\
+///     U1p1r_wW1gFWFOEjXk";
+/// let token: UntrustedToken = token_str.try_into()?;
+/// // The same operation using a shortcut:
+/// let same_token = UntrustedToken::new(token_str)?;
+/// // Token header can be accessed to select the verifying key etc.
+/// let key_id: Option<&str> = token.header().key_id.as_deref();
+/// # Ok::<_, anyhow::Error>(())
+/// ```
+///
+/// ## Handling tokens with custom header fields
+///
+/// ```
+/// # use serde::Deserialize;
+/// # use jwt_compact::UntrustedToken;
+/// #[derive(Debug, Clone, Deserialize)]
+/// struct HeaderExtensions {
+///     custom: String,
+/// }
+///
+/// let token_str = "eyJhbGciOiJIUzI1NiIsImtpZCI6InRlc3Rfa2V5Iiwid\
+///     HlwIjoiSldUIiwiY3VzdG9tIjoiY3VzdG9tIn0.eyJzdWIiOiIxMjM0NTY\
+///     3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9._27Fb6nF\
+///     Tg-HSt3vO4ylaLGcU_ZV2VhMJR4HL7KaQik";
+/// let token: UntrustedToken<HeaderExtensions> = token_str.try_into()?;
+/// let extensions = &token.header().other_fields;
+/// println!("{}", extensions.custom);
+/// # Ok::<_, anyhow::Error>(())
+/// ```
+#[derive(Debug, Clone)]
+pub struct UntrustedToken<'a, H = Empty> {
+    pub(crate) signed_data: Cow<'a, [u8]>,
+    header: Header<H>,
+    algorithm: String,
+    content_type: ContentType,
+    serialized_claims: Vec<u8>,
+    signature: SmallVec<[u8; SIGNATURE_SIZE]>,
+}
+
+/// Token with validated integrity.
+///
+/// Claims encoded in the token can be verified by invoking [`Claims`] methods
+/// via [`Self::claims()`].
+#[derive(Debug, Clone)]
+pub struct Token<T, H = Empty> {
+    header: Header<H>,
+    claims: Claims<T>,
+}
+
+impl<T, H> Token<T, H> {
+    pub(crate) fn new(header: Header<H>, claims: Claims<T>) -> Self {
+        Self { header, claims }
+    }
+
+    /// Gets token header.
+    pub fn header(&self) -> &Header<H> {
+        &self.header
+    }
+
+    /// Gets token claims.
+    pub fn claims(&self) -> &Claims<T> {
+        &self.claims
+    }
+
+    /// Splits the `Token` into the respective `Header` and `Claims` while consuming it.
+    pub fn into_parts(self) -> (Header<H>, Claims<T>) {
+        (self.header, self.claims)
+    }
+}
+
+/// `Token` together with the validated token signature.
+///
+/// # Examples
+///
+/// ```
+/// # use jwt_compact::{alg::{Hs256, Hs256Key, Hs256Signature}, prelude::*};
+/// # use chrono::Duration;
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// #[derive(Serialize, Deserialize)]
+/// struct MyClaims {
+///     // Custom claims in the token...
+/// }
+///
+/// # fn main() -> anyhow::Result<()> {
+/// # let key = Hs256Key::new(b"super_secret_key");
+/// # let claims = Claims::new(MyClaims {})
+/// #     .set_duration_and_issuance(&TimeOptions::default(), Duration::days(7));
+/// let token_string: String = // token from an external source
+/// #   Hs256.token(&Header::empty(), &claims, &key)?;
+/// let token = UntrustedToken::new(&token_string)?;
+/// let signed = Hs256.validator::<MyClaims>(&key)
+///     .validate_for_signed_token(&token)?;
+///
+/// // `signature` is strongly typed.
+/// let signature: Hs256Signature = signed.signature;
+/// // Token itself is available via `token` field.
+/// let claims = signed.token.claims();
+/// claims.validate_expiration(&TimeOptions::default())?;
+/// // Process the claims...
+/// # Ok(())
+/// # } // end main()
+/// ```
+#[non_exhaustive]
+pub struct SignedToken<A: Algorithm + ?Sized, T, H = Empty> {
+    /// Token signature.
+    pub signature: A::Signature,
+    /// Verified token.
+    pub token: Token<T, H>,
+}
+
+impl<A, T, H> fmt::Debug for SignedToken<A, T, H>
+where
+    A: Algorithm,
+    A::Signature: fmt::Debug,
+    T: fmt::Debug,
+    H: fmt::Debug,
+{
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        formatter
+            .debug_struct("SignedToken")
+            .field("token", &self.token)
+            .field("signature", &self.signature)
+            .finish()
+    }
+}
+
+impl<A, T, H> Clone for SignedToken<A, T, H>
+where
+    A: Algorithm,
+    A::Signature: Clone,
+    T: Clone,
+    H: Clone,
+{
+    fn clone(&self) -> Self {
+        Self {
+            signature: self.signature.clone(),
+            token: self.token.clone(),
+        }
+    }
+}
+
+impl<'a, H: DeserializeOwned> TryFrom<&'a str> for UntrustedToken<'a, H> {
+    type Error = ParseError;
+
+    fn try_from(s: &'a str) -> Result<Self, Self::Error> {
+        let token_parts: Vec<_> = s.splitn(4, '.').collect();
+        match &token_parts[..] {
+            [header, claims, signature] => {
+                let header = Base64UrlUnpadded::decode_vec(header)
+                    .map_err(|_| ParseError::InvalidBase64Encoding)?;
+                let serialized_claims = Base64UrlUnpadded::decode_vec(claims)
+                    .map_err(|_| ParseError::InvalidBase64Encoding)?;
+
+                let mut decoded_signature = smallvec![0; 3 * (signature.len() + 3) / 4];
+                let signature_len =
+                    Base64UrlUnpadded::decode(signature, &mut decoded_signature[..])
+                        .map_err(|_| ParseError::InvalidBase64Encoding)?
+                        .len();
+                decoded_signature.truncate(signature_len);
+
+                let header: CompleteHeader<_> =
+                    serde_json::from_slice(&header).map_err(ParseError::MalformedHeader)?;
+                let content_type = match header.content_type {
+                    None => ContentType::Json,
+                    Some(s) if s.eq_ignore_ascii_case("json") => ContentType::Json,
+                    #[cfg(feature = "ciborium")]
+                    Some(s) if s.eq_ignore_ascii_case("cbor") => ContentType::Cbor,
+                    Some(s) => return Err(ParseError::UnsupportedContentType(s)),
+                };
+                let signed_data = s.rsplit_once('.').unwrap().0.as_bytes();
+                Ok(Self {
+                    signed_data: Cow::Borrowed(signed_data),
+                    header: header.inner,
+                    algorithm: header.algorithm.into_owned(),
+                    content_type,
+                    serialized_claims,
+                    signature: decoded_signature,
+                })
+            }
+            _ => Err(ParseError::InvalidTokenStructure),
+        }
+    }
+}
+
+impl<'a> UntrustedToken<'a> {
+    /// Creates an untrusted token from a string. This is a shortcut for calling the [`TryFrom`]
+    /// conversion.
+    pub fn new<S: AsRef<str> + ?Sized>(s: &'a S) -> Result<Self, ParseError> {
+        Self::try_from(s.as_ref())
+    }
+}
+
+impl<H> UntrustedToken<'_, H> {
+    /// Converts this token to an owned form.
+    pub fn into_owned(self) -> UntrustedToken<'static, H> {
+        UntrustedToken {
+            signed_data: Cow::Owned(self.signed_data.into_owned()),
+            header: self.header,
+            algorithm: self.algorithm,
+            content_type: self.content_type,
+            serialized_claims: self.serialized_claims,
+            signature: self.signature,
+        }
+    }
+
+    /// Gets the token header.
+    pub fn header(&self) -> &Header<H> {
+        &self.header
+    }
+
+    /// Gets the integrity algorithm used to secure the token.
+    pub fn algorithm(&self) -> &str {
+        &self.algorithm
+    }
+
+    /// Returns signature bytes from the token. These bytes are **not** guaranteed to form a valid
+    /// signature.
+    pub fn signature_bytes(&self) -> &[u8] {
+        &self.signature
+    }
+
+    /// Deserializes claims from this token without checking token integrity. The resulting
+    /// claims are thus **not** guaranteed to be valid.
+    pub fn deserialize_claims_unchecked<T>(&self) -> Result<Claims<T>, ValidationError>
+    where
+        T: DeserializeOwned,
+    {
+        match self.content_type {
+            ContentType::Json => serde_json::from_slice(&self.serialized_claims)
+                .map_err(ValidationError::MalformedClaims),
+
+            #[cfg(feature = "ciborium")]
+            ContentType::Cbor => {
+                ciborium::from_reader(&self.serialized_claims[..]).map_err(|err| {
+                    ValidationError::MalformedCborClaims(match err {
+                        CborDeError::Io(err) => CborDeError::Io(anyhow::anyhow!(err)),
+                        // ^ In order to be able to use `anyhow!` in both std and no-std envs,
+                        // we inline the error transform directly here.
+                        CborDeError::Syntax(offset) => CborDeError::Syntax(offset),
+                        CborDeError::Semantic(offset, description) => {
+                            CborDeError::Semantic(offset, description)
+                        }
+                        CborDeError::RecursionLimitExceeded => CborDeError::RecursionLimitExceeded,
+                    })
+                })
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use assert_matches::assert_matches;
+    use base64ct::{Base64UrlUnpadded, Encoding};
+
+    use super::*;
+    use crate::{
+        alg::{Hs256, Hs256Key},
+        alloc::{ToOwned, ToString},
+        AlgorithmExt, Empty,
+    };
+
+    type Obj = serde_json::Map<String, serde_json::Value>;
+
+    const HS256_TOKEN: &str = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.\
+                               eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt\
+                               cGxlLmNvbS9pc19yb290Ijp0cnVlfQ.\
+                               dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk";
+    const HS256_KEY: &str = "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75\
+                             aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow";
+
+    #[test]
+    fn invalid_token_structure() {
+        let mangled_str = HS256_TOKEN.replace('.', "");
+        assert_matches!(
+            UntrustedToken::new(&mangled_str).unwrap_err(),
+            ParseError::InvalidTokenStructure
+        );
+
+        let mut mangled_str = HS256_TOKEN.to_owned();
+        let signature_start = mangled_str.rfind('.').unwrap();
+        mangled_str.truncate(signature_start);
+        assert_matches!(
+            UntrustedToken::new(&mangled_str).unwrap_err(),
+            ParseError::InvalidTokenStructure
+        );
+
+        let mut mangled_str = HS256_TOKEN.to_owned();
+        mangled_str.push('.');
+        assert_matches!(
+            UntrustedToken::new(&mangled_str).unwrap_err(),
+            ParseError::InvalidTokenStructure
+        );
+    }
+
+    #[test]
+    fn base64_error_during_parsing() {
+        let mangled_str = HS256_TOKEN.replace('0', "+");
+        assert_matches!(
+            UntrustedToken::new(&mangled_str).unwrap_err(),
+            ParseError::InvalidBase64Encoding
+        );
+    }
+
+    #[test]
+    fn base64_padding_error_during_parsing() {
+        let mut mangled_str = HS256_TOKEN.to_owned();
+        mangled_str.pop();
+        mangled_str.push('_'); // leads to non-zero padding for the last encoded byte
+        assert_matches!(
+            UntrustedToken::new(&mangled_str).unwrap_err(),
+            ParseError::InvalidBase64Encoding
+        );
+    }
+
+    #[test]
+    fn header_fields_are_not_serialized_if_not_present() {
+        let header = Header::empty();
+        let json = serde_json::to_string(&header).unwrap();
+        assert_eq!(json, "{}");
+    }
+
+    #[test]
+    fn header_with_x5t_field() {
+        let header = r#"{"alg":"HS256","x5t":"lDpwLQbzRZmu4fjajvn3KWAx1pk"}"#;
+        let header: CompleteHeader<Header<Empty>> = serde_json::from_str(header).unwrap();
+        let thumbprint = header.inner.certificate_sha1_thumbprint.as_ref().unwrap();
+        let Thumbprint::Bytes(thumbprint) = thumbprint else {
+            unreachable!();
+        };
+
+        assert_eq!(thumbprint[0], 0x94);
+        assert_eq!(thumbprint[19], 0x99);
+
+        let json = serde_json::to_value(header).unwrap();
+        assert_eq!(
+            json,
+            serde_json::json!({
+                "alg": "HS256",
+                "x5t": "lDpwLQbzRZmu4fjajvn3KWAx1pk",
+            })
+        );
+    }
+
+    #[test]
+    fn header_with_padded_x5t_field() {
+        let header = r#"{"alg":"HS256","x5t":"lDpwLQbzRZmu4fjajvn3KWAx1pk=="}"#;
+        let header: CompleteHeader<Header<Empty>> = serde_json::from_str(header).unwrap();
+        let thumbprint = header.inner.certificate_sha1_thumbprint.as_ref().unwrap();
+        let Thumbprint::Bytes(thumbprint) = thumbprint else {
+            unreachable!()
+        };
+
+        assert_eq!(thumbprint[0], 0x94);
+        assert_eq!(thumbprint[19], 0x99);
+    }
+
+    #[test]
+    fn header_with_hex_x5t_field() {
+        let header =
+            r#"{"alg":"HS256","x5t":"NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg"}"#;
+        let header: CompleteHeader<Header<Empty>> = serde_json::from_str(header).unwrap();
+        let thumbprint = header.inner.certificate_sha1_thumbprint.as_ref().unwrap();
+        let Thumbprint::String(thumbprint) = thumbprint else {
+            unreachable!()
+        };
+
+        assert_eq!(thumbprint, "65AF6909B1B0758E06C6E048C46002B5C695E36B");
+
+        let json = serde_json::to_value(header).unwrap();
+        assert_eq!(
+            json,
+            serde_json::json!({
+                "alg": "HS256",
+                "x5t": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg",
+            })
+        );
+    }
+
+    #[test]
+    fn header_with_padded_hex_x5t_field() {
+        let header =
+            r#"{"alg":"HS256","x5t":"NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg=="}"#;
+        let header: CompleteHeader<Header<Empty>> = serde_json::from_str(header).unwrap();
+        let thumbprint = header.inner.certificate_sha1_thumbprint.as_ref().unwrap();
+        let Thumbprint::String(thumbprint) = thumbprint else {
+            unreachable!()
+        };
+
+        assert_eq!(thumbprint, "65AF6909B1B0758E06C6E048C46002B5C695E36B");
+    }
+
+    #[test]
+    fn header_with_overly_short_x5t_field() {
+        let header = r#"{"alg":"HS256","x5t":"aGk="}"#;
+        let err = serde_json::from_str::<CompleteHeader<Header<Empty>>>(header).unwrap_err();
+        let err = err.to_string();
+        assert!(
+            err.contains("thumbprint must contain at least 20 bytes"),
+            "{err}"
+        );
+    }
+
+    #[test]
+    fn header_with_non_base64_x5t_field() {
+        let headers = [
+            r#"{"alg":"HS256","x5t":"lDpwLQbzRZmu4fjajvn3KWAx1p?"}"#,
+            r#"{"alg":"HS256","x5t":"NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk!RTM2Qg"}"#,
+        ];
+        for header in headers {
+            let err = serde_json::from_str::<CompleteHeader<Header<Empty>>>(header).unwrap_err();
+            let err = err.to_string();
+            assert!(err.contains("Base64"), "{err}");
+        }
+    }
+
+    #[test]
+    fn header_with_x5t_sha256_field() {
+        let header = r#"{"alg":"HS256","x5t#S256":"MV9b23bQeMQ7isAGTkoBZGErH853yGk0W_yUx1iU7dM"}"#;
+        let header: CompleteHeader<Header<Empty>> = serde_json::from_str(header).unwrap();
+        let thumbprint = header.inner.certificate_thumbprint.as_ref().unwrap();
+        let Thumbprint::Bytes(thumbprint) = thumbprint else {
+            unreachable!()
+        };
+
+        assert_eq!(thumbprint[0], 0x31);
+        assert_eq!(thumbprint[31], 0xd3);
+
+        let json = serde_json::to_value(header).unwrap();
+        assert_eq!(
+            json,
+            serde_json::json!({
+                "alg": "HS256",
+                "x5t#S256": "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W_yUx1iU7dM",
+            })
+        );
+    }
+
+    #[test]
+    fn malformed_header() {
+        let mangled_headers = [
+            // Missing closing brace
+            r#"{"alg":"HS256""#,
+            // Missing necessary `alg` field
+            "{}",
+            // `alg` field is not a string
+            r#"{"alg":5}"#,
+            r#"{"alg":[1,"foo"]}"#,
+            r#"{"alg":false}"#,
+            // Duplicate `alg` field
+            r#"{"alg":"HS256","alg":"none"}"#,
+            // Invalid thumbprint fields
+            r#"{"alg":"HS256","x5t":"lDpwLQbzRZmu4fjajvn3KWAx1p"}"#,
+            r#"{"alg":"HS256","x5t":["lDpwLQbzRZmu4fjajvn3KWAx1pk"]}"#,
+            r#"{"alg":"HS256","x5t":"lDpwLQbzRZmu4fjajvn3KWAx1 k"}"#,
+            r#"{"alg":"HS256","x5t":"lDpwLQbzRZmu4fjajvn3KWAx1pk==="}"#,
+            r#"{"alg":"HS256","x5t":"lDpwLQbzRZmu4fjajvn3KWAx1pkk"}"#,
+            r#"{"alg":"HS256","x5t":"MV9b23bQeMQ7isAGTkoBZGErH853yGk0W_yUx1iU7dM"}"#,
+            r#"{"alg":"HS256","x5t#S256":"lDpwLQbzRZmu4fjajvn3KWAx1pk"}"#,
+        ];
+
+        for mangled_header in &mangled_headers {
+            let mangled_header = Base64UrlUnpadded::encode_string(mangled_header.as_bytes());
+            let mut mangled_str = HS256_TOKEN.to_owned();
+            mangled_str.replace_range(..mangled_str.find('.').unwrap(), &mangled_header);
+            assert_matches!(
+                UntrustedToken::new(&mangled_str).unwrap_err(),
+                ParseError::MalformedHeader(_)
+            );
+        }
+    }
+
+    #[test]
+    fn unsupported_content_type() {
+        let mangled_header = br#"{"alg":"HS256","cty":"txt"}"#;
+        let mangled_header = Base64UrlUnpadded::encode_string(mangled_header);
+        let mut mangled_str = HS256_TOKEN.to_owned();
+        mangled_str.replace_range(..mangled_str.find('.').unwrap(), &mangled_header);
+        assert_matches!(
+            UntrustedToken::new(&mangled_str).unwrap_err(),
+            ParseError::UnsupportedContentType(s) if s == "txt"
+        );
+    }
+
+    #[test]
+    fn extracting_custom_header_fields() {
+        let header = r#"{"alg":"HS256","custom":[1,"field"],"x5t":"lDpwLQbzRZmu4fjajvn3KWAx1pk"}"#;
+        let header: CompleteHeader<Header<Obj>> = serde_json::from_str(header).unwrap();
+        assert_eq!(header.algorithm, "HS256");
+        assert!(header.inner.certificate_sha1_thumbprint.is_some());
+        assert_eq!(header.inner.other_fields.len(), 1);
+        assert!(header.inner.other_fields["custom"].is_array());
+    }
+
+    #[test]
+    fn malformed_json_claims() {
+        let malformed_claims = [
+            // Missing closing brace
+            r#"{"exp":1500000000"#,
+            // `exp` claim is not a number
+            r#"{"exp":"1500000000"}"#,
+            r#"{"exp":false}"#,
+            // Duplicate `exp` claim
+            r#"{"exp":1500000000,"nbf":1400000000,"exp":1510000000}"#,
+            // Too large `exp` value
+            r#"{"exp":1500000000000000000000000000000000}"#,
+        ];
+
+        let claims_start = HS256_TOKEN.find('.').unwrap() + 1;
+        let claims_end = HS256_TOKEN.rfind('.').unwrap();
+        let key = Base64UrlUnpadded::decode_vec(HS256_KEY).unwrap();
+        let key = Hs256Key::new(key);
+
+        for claims in &malformed_claims {
+            let encoded_claims = Base64UrlUnpadded::encode_string(claims.as_bytes());
+            let mut mangled_str = HS256_TOKEN.to_owned();
+            mangled_str.replace_range(claims_start..claims_end, &encoded_claims);
+            let token = UntrustedToken::new(&mangled_str).unwrap();
+            assert_matches!(
+                Hs256.validator::<Obj>(&key).validate(&token).unwrap_err(),
+                ValidationError::MalformedClaims(_),
+                "Failing claims: {claims}"
+            );
+        }
+    }
+
+    fn test_invalid_signature_len(mangled_str: &str, actual_len: usize) {
+        let token = UntrustedToken::new(&mangled_str).unwrap();
+        let key = Base64UrlUnpadded::decode_vec(HS256_KEY).unwrap();
+        let key = Hs256Key::new(key);
+
+        let err = Hs256.validator::<Empty>(&key).validate(&token).unwrap_err();
+        assert_matches!(
+            err,
+            ValidationError::InvalidSignatureLen { actual, expected: 32 }
+                if actual == actual_len
+        );
+    }
+
+    #[test]
+    fn short_signature_error() {
+        test_invalid_signature_len(&HS256_TOKEN[..HS256_TOKEN.len() - 3], 30);
+    }
+
+    #[test]
+    fn long_signature_error() {
+        let mut mangled_string = HS256_TOKEN.to_owned();
+        mangled_string.push('a');
+        test_invalid_signature_len(&mangled_string, 33);
+    }
+}
+
\ No newline at end of file diff --git a/src/jwt_compact/traits.rs.html b/src/jwt_compact/traits.rs.html new file mode 100644 index 00000000..ced4932a --- /dev/null +++ b/src/jwt_compact/traits.rs.html @@ -0,0 +1,719 @@ +traits.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+
//! Key traits defined by the crate.
+
+use base64ct::{Base64UrlUnpadded, Encoding};
+use serde::{de::DeserializeOwned, Serialize};
+
+use core::{marker::PhantomData, num::NonZeroUsize};
+
+#[cfg(feature = "ciborium")]
+use crate::error::CborSerError;
+use crate::{
+    alloc::{Cow, String, ToOwned, Vec},
+    token::CompleteHeader,
+    Claims, CreationError, Header, SignedToken, Token, UntrustedToken, ValidationError,
+};
+
+/// Signature for a certain JWT signing [`Algorithm`].
+///
+/// We require that signature can be restored from a byte slice,
+/// and can be represented as a byte slice.
+pub trait AlgorithmSignature: Sized {
+    /// Constant byte length of signatures supported by the [`Algorithm`], or `None` if
+    /// the signature length is variable.
+    ///
+    /// - If this value is `Some(_)`, the signature will be first checked for its length
+    ///   during token verification. An [`InvalidSignatureLen`] error will be raised if the length
+    ///   is invalid. [`Self::try_from_slice()`] will thus always receive a slice with
+    ///   the expected length.
+    /// - If this value is `None`, no length check is performed before calling
+    ///   [`Self::try_from_slice()`].
+    ///
+    /// [`InvalidSignatureLen`]: crate::ValidationError::InvalidSignatureLen
+    const LENGTH: Option<NonZeroUsize> = None;
+
+    /// Attempts to restore a signature from a byte slice. This method may fail
+    /// if the slice is malformed.
+    fn try_from_slice(slice: &[u8]) -> anyhow::Result<Self>;
+
+    /// Represents this signature as bytes.
+    fn as_bytes(&self) -> Cow<'_, [u8]>;
+}
+
+/// JWT signing algorithm.
+pub trait Algorithm {
+    /// Key used when issuing new tokens.
+    type SigningKey;
+    /// Key used when verifying tokens. May coincide with [`Self::SigningKey`] for symmetric
+    /// algorithms (e.g., `HS*`).
+    type VerifyingKey;
+    /// Signature produced by the algorithm.
+    type Signature: AlgorithmSignature;
+
+    /// Returns the name of this algorithm, as mentioned in the `alg` field of the JWT header.
+    fn name(&self) -> Cow<'static, str>;
+
+    /// Signs a `message` with the `signing_key`.
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature;
+
+    /// Verifies the `message` against the `signature` and `verifying_key`.
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool;
+}
+
+/// Algorithm that uses a custom name when creating and validating tokens.
+///
+/// # Examples
+///
+/// ```
+/// use jwt_compact::{alg::{Hs256, Hs256Key}, prelude::*, Empty, Renamed};
+///
+/// # fn main() -> anyhow::Result<()> {
+/// let alg = Renamed::new(Hs256, "HS2");
+/// let key = Hs256Key::new(b"super_secret_key_donut_steel");
+/// let token_string = alg.token(&Header::empty(), &Claims::empty(), &key)?;
+///
+/// let token = UntrustedToken::new(&token_string)?;
+/// assert_eq!(token.algorithm(), "HS2");
+/// // Note that the created token cannot be verified against the original algorithm
+/// // since the algorithm name recorded in the token header doesn't match.
+/// assert!(Hs256.validator::<Empty>(&key).validate(&token).is_err());
+///
+/// // ...but the modified alg is working as expected.
+/// assert!(alg.validator::<Empty>(&key).validate(&token).is_ok());
+/// # Ok(())
+/// # }
+/// ```
+#[derive(Debug, Clone, Copy)]
+pub struct Renamed<A> {
+    inner: A,
+    name: &'static str,
+}
+
+impl<A: Algorithm> Renamed<A> {
+    /// Creates a renamed algorithm.
+    pub fn new(algorithm: A, new_name: &'static str) -> Self {
+        Self {
+            inner: algorithm,
+            name: new_name,
+        }
+    }
+}
+
+impl<A: Algorithm> Algorithm for Renamed<A> {
+    type SigningKey = A::SigningKey;
+    type VerifyingKey = A::VerifyingKey;
+    type Signature = A::Signature;
+
+    fn name(&self) -> Cow<'static, str> {
+        Cow::Borrowed(self.name)
+    }
+
+    fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
+        self.inner.sign(signing_key, message)
+    }
+
+    fn verify_signature(
+        &self,
+        signature: &Self::Signature,
+        verifying_key: &Self::VerifyingKey,
+        message: &[u8],
+    ) -> bool {
+        self.inner
+            .verify_signature(signature, verifying_key, message)
+    }
+}
+
+/// Automatically implemented extensions of the `Algorithm` trait.
+pub trait AlgorithmExt: Algorithm {
+    /// Creates a new token and serializes it to string.
+    fn token<T>(
+        &self,
+        header: &Header<impl Serialize>,
+        claims: &Claims<T>,
+        signing_key: &Self::SigningKey,
+    ) -> Result<String, CreationError>
+    where
+        T: Serialize;
+
+    /// Creates a new token with CBOR-encoded claims and serializes it to string.
+    #[cfg(feature = "ciborium")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "ciborium")))]
+    fn compact_token<T>(
+        &self,
+        header: &Header<impl Serialize>,
+        claims: &Claims<T>,
+        signing_key: &Self::SigningKey,
+    ) -> Result<String, CreationError>
+    where
+        T: Serialize;
+
+    /// Creates a JWT validator for the specified verifying key and the claims type.
+    /// The validator can then be used to validate integrity of one or more tokens.
+    fn validator<'a, T>(&'a self, verifying_key: &'a Self::VerifyingKey) -> Validator<'a, Self, T>;
+
+    /// Validates the token integrity against the provided `verifying_key`.
+    #[deprecated = "Use `.validator().validate()` for added flexibility"]
+    fn validate_integrity<T>(
+        &self,
+        token: &UntrustedToken<'_>,
+        verifying_key: &Self::VerifyingKey,
+    ) -> Result<Token<T>, ValidationError>
+    where
+        T: DeserializeOwned;
+
+    /// Validates the token integrity against the provided `verifying_key`.
+    ///
+    /// Unlike [`validate_integrity`](#tymethod.validate_integrity), this method retains more
+    /// information about the original token, in particular, its signature.
+    #[deprecated = "Use `.validator().validate_for_signed_token()` for added flexibility"]
+    fn validate_for_signed_token<T>(
+        &self,
+        token: &UntrustedToken<'_>,
+        verifying_key: &Self::VerifyingKey,
+    ) -> Result<SignedToken<Self, T>, ValidationError>
+    where
+        T: DeserializeOwned;
+}
+
+impl<A: Algorithm> AlgorithmExt for A {
+    fn token<T>(
+        &self,
+        header: &Header<impl Serialize>,
+        claims: &Claims<T>,
+        signing_key: &Self::SigningKey,
+    ) -> Result<String, CreationError>
+    where
+        T: Serialize,
+    {
+        let complete_header = CompleteHeader {
+            algorithm: self.name(),
+            content_type: None,
+            inner: header,
+        };
+        let header = serde_json::to_string(&complete_header).map_err(CreationError::Header)?;
+        let mut buffer = Vec::new();
+        encode_base64_buf(&header, &mut buffer);
+
+        let claims = serde_json::to_string(claims).map_err(CreationError::Claims)?;
+        buffer.push(b'.');
+        encode_base64_buf(&claims, &mut buffer);
+
+        let signature = self.sign(signing_key, &buffer);
+        buffer.push(b'.');
+        encode_base64_buf(signature.as_bytes(), &mut buffer);
+
+        // SAFETY: safe by construction: base64 alphabet and `.` char are valid UTF-8.
+        Ok(unsafe { String::from_utf8_unchecked(buffer) })
+    }
+
+    #[cfg(feature = "ciborium")]
+    fn compact_token<T>(
+        &self,
+        header: &Header<impl Serialize>,
+        claims: &Claims<T>,
+        signing_key: &Self::SigningKey,
+    ) -> Result<String, CreationError>
+    where
+        T: Serialize,
+    {
+        let complete_header = CompleteHeader {
+            algorithm: self.name(),
+            content_type: Some("CBOR".to_owned()),
+            inner: header,
+        };
+        let header = serde_json::to_string(&complete_header).map_err(CreationError::Header)?;
+        let mut buffer = Vec::new();
+        encode_base64_buf(&header, &mut buffer);
+
+        let mut serialized_claims = vec![];
+        ciborium::into_writer(claims, &mut serialized_claims).map_err(|err| {
+            CreationError::CborClaims(match err {
+                CborSerError::Value(message) => CborSerError::Value(message),
+                CborSerError::Io(_) => unreachable!(), // writing to a `Vec` always succeeds
+            })
+        })?;
+        buffer.push(b'.');
+        encode_base64_buf(&serialized_claims, &mut buffer);
+
+        let signature = self.sign(signing_key, &buffer);
+        buffer.push(b'.');
+        encode_base64_buf(signature.as_bytes(), &mut buffer);
+
+        // SAFETY: safe by construction: base64 alphabet and `.` char are valid UTF-8.
+        Ok(unsafe { String::from_utf8_unchecked(buffer) })
+    }
+
+    fn validator<'a, T>(&'a self, verifying_key: &'a Self::VerifyingKey) -> Validator<'a, Self, T> {
+        Validator {
+            algorithm: self,
+            verifying_key,
+            _claims: PhantomData,
+        }
+    }
+
+    fn validate_integrity<T>(
+        &self,
+        token: &UntrustedToken<'_>,
+        verifying_key: &Self::VerifyingKey,
+    ) -> Result<Token<T>, ValidationError>
+    where
+        T: DeserializeOwned,
+    {
+        self.validator::<T>(verifying_key).validate(token)
+    }
+
+    fn validate_for_signed_token<T>(
+        &self,
+        token: &UntrustedToken<'_>,
+        verifying_key: &Self::VerifyingKey,
+    ) -> Result<SignedToken<Self, T>, ValidationError>
+    where
+        T: DeserializeOwned,
+    {
+        self.validator::<T>(verifying_key)
+            .validate_for_signed_token(token)
+    }
+}
+
+/// Validator for a certain signing [`Algorithm`] associated with a specific verifying key
+/// and a claims type. Produced by the [`AlgorithmExt::validator()`] method.
+#[derive(Debug)]
+pub struct Validator<'a, A: Algorithm + ?Sized, T> {
+    algorithm: &'a A,
+    verifying_key: &'a A::VerifyingKey,
+    _claims: PhantomData<fn() -> T>,
+}
+
+impl<A: Algorithm + ?Sized, T> Clone for Validator<'_, A, T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<A: Algorithm + ?Sized, T> Copy for Validator<'_, A, T> {}
+
+impl<A: Algorithm + ?Sized, T: DeserializeOwned> Validator<'_, A, T> {
+    /// Validates the token integrity against a verifying key enclosed in this validator.
+    pub fn validate<H: Clone>(
+        self,
+        token: &UntrustedToken<'_, H>,
+    ) -> Result<Token<T, H>, ValidationError> {
+        self.validate_for_signed_token(token)
+            .map(|signed| signed.token)
+    }
+
+    /// Validates the token integrity against a verifying key enclosed in this validator,
+    /// and returns the validated [`Token`] together with its signature.
+    pub fn validate_for_signed_token<H: Clone>(
+        self,
+        token: &UntrustedToken<'_, H>,
+    ) -> Result<SignedToken<A, T, H>, ValidationError> {
+        let expected_alg = self.algorithm.name();
+        if expected_alg != token.algorithm() {
+            return Err(ValidationError::AlgorithmMismatch {
+                expected: expected_alg.into_owned(),
+                actual: token.algorithm().to_owned(),
+            });
+        }
+
+        let signature = token.signature_bytes();
+        if let Some(expected_len) = A::Signature::LENGTH {
+            if signature.len() != expected_len.get() {
+                return Err(ValidationError::InvalidSignatureLen {
+                    expected: expected_len.get(),
+                    actual: signature.len(),
+                });
+            }
+        }
+
+        let signature =
+            A::Signature::try_from_slice(signature).map_err(ValidationError::MalformedSignature)?;
+        // We assume that parsing claims is less computationally demanding than
+        // validating a signature.
+        let claims = token.deserialize_claims_unchecked::<T>()?;
+        if !self
+            .algorithm
+            .verify_signature(&signature, self.verifying_key, &token.signed_data)
+        {
+            return Err(ValidationError::InvalidSignature);
+        }
+
+        Ok(SignedToken {
+            signature,
+            token: Token::new(token.header().clone(), claims),
+        })
+    }
+}
+
+fn encode_base64_buf(source: impl AsRef<[u8]>, buffer: &mut Vec<u8>) {
+    let source = source.as_ref();
+    let previous_len = buffer.len();
+    let claims_len = Base64UrlUnpadded::encoded_len(source);
+    buffer.resize(previous_len + claims_len, 0);
+    Base64UrlUnpadded::encode(source, &mut buffer[previous_len..])
+        .expect("miscalculated base64-encoded length; this should never happen");
+}
+
\ No newline at end of file diff --git a/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 00000000..1447df79 --- /dev/null +++ b/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 00000000..d7e9c149 --- /dev/null +++ b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 00000000..7a1e5fc5 Binary files /dev/null and b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 00000000..e766e06c Binary files /dev/null and b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 00000000..1866ad4b Binary files /dev/null and b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 00000000..4b3edc29 --- /dev/null +++ b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 00000000..462c34ef Binary files /dev/null and b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 00000000..0d2941e1 --- /dev/null +++ b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 00000000..10b558e0 Binary files /dev/null and b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 00000000..5ec64eef Binary files /dev/null and b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 00000000..181a07f6 Binary files /dev/null and b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ diff --git a/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 00000000..2ae08a7b Binary files /dev/null and b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ diff --git a/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md new file mode 100644 index 00000000..175fa4f4 --- /dev/null +++ b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md @@ -0,0 +1,98 @@ + + +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + diff --git a/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 00000000..0263fc30 Binary files /dev/null and b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ diff --git a/static.files/ayu-49e58d069f567085.css b/static.files/ayu-49e58d069f567085.css new file mode 100644 index 00000000..7a84c0b7 --- /dev/null +++ b/static.files/ayu-49e58d069f567085.css @@ -0,0 +1 @@ + :root{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);}h1,h2,h3,h4,h1 a,.sidebar h2 a,.sidebar h3 a,#src-sidebar>.title{color:#fff;}h4{border:none;}.docblock code{color:#ffb454;}.docblock a>code{color:#39AFD7 !important;}.code-header,.docblock pre>code,pre,pre>code,.item-info code,.rustdoc.src .example-wrap{color:#e6e1cf;}.sidebar .current,.sidebar a:hover,#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus,#src-sidebar div.files>a.selected{color:#ffb44c;}.sidebar-elems .location{color:#ff7733;}.src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}.search-results a:hover,.search-results a:focus{color:#fff !important;background-color:#3c3c3c;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}#search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}#search-tabs>button:not(.selected){border:none;background-color:transparent !important;}#search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#settings-menu>a img{filter:invert(100);} \ No newline at end of file diff --git a/static.files/clipboard-7571035ce49a181d.svg b/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 00000000..8adbd996 --- /dev/null +++ b/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/static.files/dark-1dd4d1ce031e15de.css b/static.files/dark-1dd4d1ce031e15de.css new file mode 100644 index 00000000..a6623d9b --- /dev/null +++ b/static.files/dark-1dd4d1ce031e15de.css @@ -0,0 +1 @@ +:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);} \ No newline at end of file diff --git a/static.files/favicon-16x16-8b506e7a72182f1c.png b/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 00000000..ea4b45ca Binary files /dev/null and b/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/static.files/favicon-2c020d218678b618.svg b/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 00000000..8b34b511 --- /dev/null +++ b/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/static.files/favicon-32x32-422f7d1d52889060.png b/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 00000000..69b8613c Binary files /dev/null and b/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/static.files/light-f194925aa375ae96.css b/static.files/light-f194925aa375ae96.css new file mode 100644 index 00000000..61311db0 --- /dev/null +++ b/static.files/light-f194925aa375ae96.css @@ -0,0 +1 @@ +:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);} \ No newline at end of file diff --git a/static.files/main-ef3a2de404864b0b.js b/static.files/main-ef3a2de404864b0b.js new file mode 100644 index 00000000..ac22f671 --- /dev/null +++ b/static.files/main-ef3a2de404864b0b.js @@ -0,0 +1,12 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function elemIsInParent(elem,parent){while(elem&&elem!==document.body){if(elem===parent){return true}elem=elem.parentElement}return false}function blurHandler(event,parentElem,hideCallback){if(!elemIsInParent(document.activeElement,parentElem)&&!elemIsInParent(event.relatedTarget,parentElem)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileLocationTitle=document.querySelector(".mobile-topbar h2");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileLocationTitle&&locationTitle){mobileLocationTitle.innerHTML=locationTitle.innerHTML}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function loadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="stylesheet";document.getElementsByTagName("head")[0].appendChild(link)}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadCss(getVar("static-root-path")+getVar("settings-css"));loadScript(getVar("static-root-path")+getVar("settings-js"));preLoadCss(getVar("static-root-path")+getVar("theme-light-css"));preLoadCss(getVar("static-root-path")+getVar("theme-dark-css"));preLoadCss(getVar("static-root-path")+getVar("theme-ayu-css"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=name+"/index.html"}else{path=shortty+"."+name+".html"}const current_page=document.location.href.split("/").pop();const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("union","unions","Unions");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";if(window.rootPath!=="./"&&crate===window.currentCrate){link.className="current"}link.textContent=crate;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=function(ev){if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,e)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=function(){this.TOOLTIP_FORCE_VISIBLE=this.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!this.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(this);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=function(ev){if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(this,true)};e.onpointermove=function(ev){if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(this,true)};e.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!this.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=function(switchFocus){hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=function(){onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/static.files/normalize-76eba96aa4d2e634.css b/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 00000000..469959f1 --- /dev/null +++ b/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/static.files/noscript-cffde32267a19fd6.css b/static.files/noscript-cffde32267a19fd6.css new file mode 100644 index 00000000..12d3f6dd --- /dev/null +++ b/static.files/noscript-cffde32267a19fd6.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;} \ No newline at end of file diff --git a/static.files/rust-logo-151179464ae7ed46.svg b/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 00000000..62424d8f --- /dev/null +++ b/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/static.files/rustdoc-47e7ab555ef2818a.css b/static.files/rustdoc-47e7ab555ef2818a.css new file mode 100644 index 00000000..b6a585f1 --- /dev/null +++ b/static.files/rustdoc-47e7ab555ef2818a.css @@ -0,0 +1,8 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.small-section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.sub-logo-container,.logo-container{line-height:0;display:block;}.sub-logo-container{margin-right:32px;}.sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 200px;overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;}.rustdoc.src .sidebar{flex-basis:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;z-index:1;}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}#src-sidebar-toggle>button:hover,#src-sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.src .sidebar>*:not(#src-sidebar-toggle){visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:300px;}.src-sidebar-expanded .src .sidebar>*:not(#src-sidebar-toggle){visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.sidebar .logo-container{margin-top:10px;margin-bottom:10px;text-align:center;}.version{overflow-wrap:break-word;}.logo-container>img{height:100px;width:100px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}.method .where,.fn .where,.where.fmt-newline{display:block;white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.small-section-header{display:block;position:relative;}.small-section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block a.current{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:2;margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{min-height:36px;display:flex;padding:3px;margin-bottom:5px;align-items:center;vertical-align:text-bottom;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji{font-size:1.25rem;margin-right:0.3rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar-toggle{position:sticky;top:0;left:0;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:stretch;align-items:stretch;z-index:10;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}#src-sidebar-toggle>button{font-size:inherit;font-weight:bold;background:none;color:inherit;text-align:center;border:none;outline:none;flex:1 1;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;display:flex;}#settings-menu>a,#help-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus{border-color:var(--settings-button-border-focus);}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;color:var(--main-color);}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#search-tabs .count{display:block;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#src-sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;border:1px solid;border-left:0;}.src-sidebar-expanded #src-sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#copy-path,#help-button{display:none;}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{max-width:100vw;width:100vw;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}.sub-logo-container>img{height:35px;width:35px;margin-bottom:var(--nav-sub-mobile-padding);}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;} \ No newline at end of file diff --git a/static.files/scrape-examples-ef1e698c1d417c0c.js b/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 00000000..ba830e37 --- /dev/null +++ b/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/static.files/search-5d3eaacf19ebf04f.js b/static.files/search-5d3eaacf19ebf04f.js new file mode 100644 index 00000000..db532c01 --- /dev/null +++ b/static.files/search-5d3eaacf19ebf04f.js @@ -0,0 +1,5 @@ +"use strict";(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias",];const longItemTypes=["module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","primitive type","assoc type","constant","assoc const","union","foreign type","keyword","existential type","attribute macro","derive macro","trait alias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;function buildTypeMapIndex(name){if(name===""||name===null){return-1}if(typeNameIdMap.has(name)){return typeNameIdMap.get(name)}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,id);return id}}function isWhitespace(c){return" \t\n\r".indexOf(c)!==-1}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return",>-]".indexOf(c)!==-1}function isStopCharacter(c){return isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","}function isPathSeparator(c){return c===":"||isWhitespace(c)}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(!isWhitespace(c)){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}return{name:"never",id:-1,fullPath:["never"],pathWithoutLast:[],pathLast:"never",generics:[],typeFilter:"primitive",}}if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(path.includes("::::")){throw["Unexpected ","::::"]}else if(path.includes(" ::")){throw["Unexpected "," ::"]}else if(path.includes(":: ")){throw["Unexpected ",":: "]}const pathSegments=path.split(/::|\s+/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}return{name:name.trim(),id:-1,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast:pathSegments[pathSegments.length-1],generics:generics,typeFilter,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",","," or ",endChar,...extra,", found ",c,]}throw["Expected ",",",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(isWhitespace(c)){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,literalSearch:false,error:null,correction:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}}userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id>-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of result_list){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(result_list)}function checkGenerics(fnType,queryElem){return unifyFunctionTypes(fnType.generics,queryElem.generics)}function unifyFunctionTypes(fnTypes,queryElems){if(queryElems.length===0){return true}if(!fnTypes||fnTypes.length===0){return false}const queryElemSet=new Map();const addQueryElemToQueryElemSet=queryElem=>{let currentQueryElemList;if(queryElemSet.has(queryElem.id)){currentQueryElemList=queryElemSet.get(queryElem.id)}else{currentQueryElemList=[];queryElemSet.set(queryElem.id,currentQueryElemList)}currentQueryElemList.push(queryElem)};for(const queryElem of queryElems){addQueryElemToQueryElemSet(queryElem)}const fnTypeSet=new Map();const addFnTypeToFnTypeSet=fnType=>{const queryContainsArrayOrSliceElem=queryElemSet.has(typeNameIdOfArrayOrSlice);if(fnType.id===-1||!(queryElemSet.has(fnType.id)||(fnType.id===typeNameIdOfSlice&&queryContainsArrayOrSliceElem)||(fnType.id===typeNameIdOfArray&&queryContainsArrayOrSliceElem))){for(const innerFnType of fnType.generics){addFnTypeToFnTypeSet(innerFnType)}return}let currentQueryElemList=queryElemSet.get(fnType.id)||[];let matchIdx=currentQueryElemList.findIndex(queryElem=>{return typePassesFilter(queryElem.typeFilter,fnType.ty)&&checkGenerics(fnType,queryElem)});if(matchIdx===-1&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)&&queryContainsArrayOrSliceElem){currentQueryElemList=queryElemSet.get(typeNameIdOfArrayOrSlice)||[];matchIdx=currentQueryElemList.findIndex(queryElem=>{return typePassesFilter(queryElem.typeFilter,fnType.ty)&&checkGenerics(fnType,queryElem)})}if(matchIdx===-1){for(const innerFnType of fnType.generics){addFnTypeToFnTypeSet(innerFnType)}return}let currentFnTypeList;if(fnTypeSet.has(fnType.id)){currentFnTypeList=fnTypeSet.get(fnType.id)}else{currentFnTypeList=[];fnTypeSet.set(fnType.id,currentFnTypeList)}currentFnTypeList.push(fnType)};for(const fnType of fnTypes){addFnTypeToFnTypeSet(fnType)}const doHandleQueryElemList=(currentFnTypeList,queryElemList)=>{if(queryElemList.length===0){return true}const queryElem=queryElemList.pop();const l=currentFnTypeList.length;for(let i=0;i0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){continue}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i{if(!fnTypeSet.has(id)){if(id===typeNameIdOfArrayOrSlice){return handleQueryElemList(typeNameIdOfSlice,queryElemList)||handleQueryElemList(typeNameIdOfArray,queryElemList)}return false}const currentFnTypeList=fnTypeSet.get(id);if(currentFnTypeList.length0?checkIfInList(row.generics,elem):false}const matchesExact=row.id===elem.id;const matchesArrayOrSlice=elem.id===typeNameIdOfArrayOrSlice&&(row.id===typeNameIdOfSlice||row.id===typeNameIdOfArray);if((matchesExact||matchesArrayOrSlice)&&typePassesFilter(elem.typeFilter,row.ty)){if(elem.generics.length>0){return checkGenerics(row,elem)}return true}return checkIfInList(row.generics,elem)}function checkPath(contains,ty,maxEditDistance){if(contains.length===0){return 0}let ret_dist=maxEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return maxEditDistance+1}for(let i=0;ilength){break}let dist_total=0;let aborted=false;for(let x=0;xmaxEditDistance){aborted=true;break}dist_total+=dist}if(!aborted){ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}}return ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){const inBounds=dist<=maxEditDistance||index!==-1;if(dist===0||(!parsedQuery.literalSearch&&inBounds)){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let index=-1,path_dist=0;const fullId=row.id;const searchWord=searchWords[pos];const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem);if(in_args){addIntoResults(results_in_args,fullId,pos,-1,0,0,maxEditDistance)}const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem);if(returned){addIntoResults(results_returned,fullId,pos,-1,0,0,maxEditDistance)}if(!typePassesFilter(elem.typeFilter,row.ty)){return}const row_index=row.normalizedName.indexOf(elem.pathLast);const word_index=searchWord.indexOf(elem.pathLast);if(row_index===-1){index=word_index}else if(word_index===-1){index=row_index}else if(word_index1){path_dist=checkPath(elem.pathWithoutLast,row,maxEditDistance);if(path_dist>maxEditDistance){return}}if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(searchWord,elem.pathLast,maxEditDistance);if(index===-1&&dist+path_dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems)){return}if(!unifyFunctionTypes(row.type.output,parsedQuery.returned)){return}addIntoResults(results,row.id,pos,0,0,0,Number.MAX_VALUE)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;let queryLen=0;for(const elem of parsedQuery.elems){queryLen+=elem.name.length}for(const elem of parsedQuery.returned){queryLen+=elem.name.length}const maxEditDistance=Math.floor(queryLen/3);function convertNameToId(elem){if(typeNameIdMap.has(elem.pathLast)){elem.id=typeNameIdMap.get(elem.pathLast)}else if(!parsedQuery.literalSearch){let match=-1;let matchDist=maxEditDistance+1;let matchName="";for(const[name,id]of typeNameIdMap){const dist=editDistance(name,elem.pathLast,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==-1){parsedQuery.correction=matchName}elem.id=match}for(const elem2 of elem.generics){convertNameToId(elem2)}}for(const elem of parsedQuery.elems){convertNameToId(elem)}for(const elem of parsedQuery.returned){convertNameToId(elem)}if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||editDistance(name,key,maxEditDistance)<=maxEditDistance)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor="#"+type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";length+=1;const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(e,forced){if(e){e.preventDefault()}const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;return types.map(type=>{let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}if(pathIndex===0){return{id:-1,ty:null,path:null,generics:generics,}}const item=lowercasePaths[pathIndex-1];return{id:buildTypeMapIndex(item.name),ty:item.ty,path:item.path,generics:generics,}})}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){const pathIndex=functionSearchType[INPUTS_DATA];if(pathIndex===0){inputs=[{id:-1,ty:null,path:null,generics:[],}]}else{const item=lowercasePaths[pathIndex-1];inputs=[{id:buildTypeMapIndex(item.name),ty:item.ty,path:item.path,generics:[],}]}}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){const pathIndex=functionSearchType[OUTPUT_DATA];if(pathIndex===0){output=[{id:-1,ty:null,path:null,generics:[],}]}else{const item=lowercasePaths[pathIndex-1];output=[{id:buildTypeMapIndex(item.name),ty:item.ty,path:item.path,generics:[],}]}}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}return{inputs,output,}}function buildIndex(rawSearchIndex){searchIndex=[];const searchWords=[];typeNameIdMap=new Map();const charA="A".charCodeAt(0);let currentIndex=0;let id=0;typeNameIdOfArray=buildTypeMapIndex("array");typeNameIdOfSlice=buildTypeMapIndex("slice");typeNameIdOfArrayOrSlice=buildTypeMapIndex("[]");for(const crate in rawSearchIndex){if(!hasOwnPropertyRustdoc(rawSearchIndex,crate)){continue}let crateSize=0;const crateCorpus=rawSearchIndex[crate];searchWords.push(crate);const crateRow={crate:crate,ty:1,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),deprecated:null,};id+=1;searchIndex.push(crateRow);currentIndex+=1;const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=new Map(crateCorpus.q);const itemDescs=crateCorpus.d;const itemParentIdxs=crateCorpus.i;const itemFunctionSearchTypes=crateCorpus.f;const deprecatedItems=new Set(crateCorpus.c);const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];let len=paths.length;let lastPath=itemPaths.get(0);for(let i=0;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}lowercasePaths.push({ty:ty,name:name.toLowerCase(),path:path});paths[i]={ty:ty,name:name,path:path}}lastPath="";len=itemTypes.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})() \ No newline at end of file diff --git a/static.files/settings-8c76f75bfb6bd192.css b/static.files/settings-8c76f75bfb6bd192.css new file mode 100644 index 00000000..5241bb86 --- /dev/null +++ b/static.files/settings-8c76f75bfb6bd192.css @@ -0,0 +1,3 @@ +.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;} \ No newline at end of file diff --git a/static.files/settings-de11bff964e9d4e5.js b/static.files/settings-de11bff964e9d4e5.js new file mode 100644 index 00000000..cc508a86 --- /dev/null +++ b/static.files/settings-de11bff964e9d4e5.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=function(){changeSetting(this.id,this.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=function(event){event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=function(event){if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/static.files/src-script-3280b574d94e47b4.js b/static.files/src-script-3280b574d94e47b4.js new file mode 100644 index 00000000..9ea88921 --- /dev/null +++ b/static.files/src-script-3280b574d94e47b4.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth"){addClass(document.documentElement,"src-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{removeClass(document.documentElement,"src-sidebar-expanded");child.innerText=">";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="src-sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(srcIndex).forEach(key=>{srcIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(srcIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSrcLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSrcLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/static.files/storage-db41da1a38ea3cb8.js b/static.files/storage-db41da1a38ea3cb8.js new file mode 100644 index 00000000..b8728135 --- /dev/null +++ b/static.files/storage-db41da1a38ea3cb8.js @@ -0,0 +1 @@ +"use strict";const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func,reversed){if(arr&&arr.length>0){if(reversed){for(let i=arr.length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){if(saveTheme){updateLocalStorage("theme",newThemeName)}let newHref;if(newThemeName==="light"||newThemeName==="dark"||newThemeName==="ayu"){newHref=getVar("static-root-path")+getVar("theme-"+newThemeName+"-css")}else{newHref=getVar("root-path")+newThemeName+getVar("resource-suffix")+".css"}if(!window.currentTheme){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0)}}) \ No newline at end of file diff --git a/static.files/wheel-7b819b6101059cd0.svg b/static.files/wheel-7b819b6101059cd0.svg new file mode 100644 index 00000000..83c07f63 --- /dev/null +++ b/static.files/wheel-7b819b6101059cd0.svg @@ -0,0 +1 @@ + \ No newline at end of file