From aa976f744a5eec267b6557461c1c93d56b12493c Mon Sep 17 00:00:00 2001 From: robjtede Date: Mon, 22 Mar 2021 11:49:07 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20=20@=20c7df6?= =?UTF-8?q?2d0b67d43e271512ed9bc857fce987b3629=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FiraSans-Medium.woff2 | Bin 0 -> 132780 bytes FiraSans-Regular.woff2 | Bin 0 -> 129188 bytes actix_cors/all.html | 5 + actix_cors/builder/struct.Cors.html | 10 + actix_cors/enum.CorsError.html | 52 + actix_cors/error/enum.CorsError.html | 10 + actix_cors/index.html | 45 + actix_cors/sidebar-items.js | 1 + actix_cors/struct.Cors.html | 133 + actix_identity/all.html | 7 + actix_identity/index.html | 55 + actix_identity/sidebar-items.js | 1 + .../struct.CookieIdentityPolicy.html | 57 + actix_identity/struct.Identity.html | 73 + actix_identity/struct.IdentityService.html | 38 + actix_identity/trait.IdentityPolicy.html | 15 + actix_identity/trait.RequestIdentity.html | 10 + actix_protobuf/all.html | 7 + actix_protobuf/enum.ProtoBufPayloadError.html | 39 + actix_protobuf/index.html | 8 + actix_protobuf/sidebar-items.js | 1 + actix_protobuf/struct.ProtoBuf.html | 34 + actix_protobuf/struct.ProtoBufConfig.html | 21 + actix_protobuf/struct.ProtoBufMessage.html | 87 + .../trait.ProtoBufResponseBuilder.html | 7 + actix_redis/all.html | 9 +- actix_redis/enum.Error.html | 41 +- actix_redis/enum.RespError.html | 43 +- actix_redis/enum.RespValue.html | 49 +- actix_redis/enum.SameSite.html | 73 +- actix_redis/index.html | 9 +- actix_redis/struct.Command.html | 31 +- actix_redis/struct.RedisActor.html | 33 +- actix_redis/struct.RedisSession.html | 31 +- actix_session/all.html | 7 + .../cookie/struct.CookieSession.html | 10 + actix_session/enum.SessionStatus.html | 37 + actix_session/index.html | 47 + actix_session/sidebar-items.js | 1 + actix_session/struct.CookieSession.html | 75 + actix_session/struct.Session.html | 75 + actix_session/trait.UserSession.html | 8 + actix_web_httpauth/all.html | 7 + .../extractors/basic/index.html | 10 + .../extractors/basic/sidebar-items.js | 1 + .../extractors/basic/struct.BasicAuth.html | 63 + .../extractors/basic/struct.Config.html | 35 + .../extractors/bearer/enum.Error.html | 61 + .../extractors/bearer/index.html | 11 + .../extractors/bearer/sidebar-items.js | 1 + .../extractors/bearer/struct.BearerAuth.html | 65 + .../extractors/bearer/struct.Config.html | 38 + .../config/trait.AuthExtractorConfig.html | 10 + .../errors/struct.AuthenticationError.html | 10 + actix_web_httpauth/extractors/index.html | 16 + .../extractors/sidebar-items.js | 1 + .../struct.AuthenticationError.html | 45 + .../extractors/trait.AuthExtractor.html | 19 + .../extractors/trait.AuthExtractorConfig.html | 12 + .../authorization/enum.ParseError.html | 47 + .../authorization/errors/enum.ParseError.html | 10 + .../header/struct.Authorization.html | 10 + .../headers/authorization/index.html | 15 + .../scheme/basic/struct.Basic.html | 10 + .../scheme/bearer/struct.Bearer.html | 10 + .../authorization/scheme/trait.Scheme.html | 10 + .../headers/authorization/sidebar-items.js | 1 + .../authorization/struct.Authorization.html | 71 + .../headers/authorization/struct.Basic.html | 54 + .../headers/authorization/struct.Bearer.html | 54 + .../headers/authorization/trait.Scheme.html | 10 + actix_web_httpauth/headers/index.html | 9 + actix_web_httpauth/headers/sidebar-items.js | 1 + .../headers/www_authenticate/basic/index.html | 9 + .../www_authenticate/basic/sidebar-items.js | 1 + .../www_authenticate/basic/struct.Basic.html | 75 + .../www_authenticate/bearer/enum.Error.html | 61 + .../www_authenticate/bearer/index.html | 12 + .../www_authenticate/bearer/sidebar-items.js | 1 + .../bearer/struct.Bearer.html | 78 + .../bearer/struct.BearerBuilder.html | 31 + .../challenge/basic/index.html | 10 + .../challenge/basic/struct.Basic.html | 10 + .../bearer/builder/struct.BearerBuilder.html | 10 + .../bearer/challenge/struct.Bearer.html | 10 + .../challenge/bearer/errors/enum.Error.html | 10 + .../challenge/bearer/index.html | 10 + .../challenge/trait.Challenge.html | 10 + .../header/struct.WwwAuthenticate.html | 10 + .../headers/www_authenticate/index.html | 13 + .../headers/www_authenticate/sidebar-items.js | 1 + .../struct.WwwAuthenticate.html | 52 + .../www_authenticate/trait.Challenge.html | 9 + actix_web_httpauth/index.html | 21 + actix_web_httpauth/middleware/index.html | 8 + .../middleware/sidebar-items.js | 1 + .../middleware/struct.HttpAuthentication.html | 71 + actix_web_httpauth/sidebar-items.js | 1 + ayu.css | 2 +- crates.js | 1 + dark.css | 2 +- implementors/actix/actor/trait.Actor.js | 2 +- implementors/actix/actor/trait.Supervised.js | 2 +- implementors/actix/handler/trait.Handler.js | 2 +- implementors/actix/handler/trait.Message.js | 2 +- implementors/actix/io/trait.WriteHandler.js | 2 +- .../actix/stream/trait.StreamHandler.js | 2 +- .../actix_http/error/trait.ResponseError.js | 5 +- .../into_value/trait.IntoHeaderValue.js | 3 + .../actix_http/header/trait.Header.js | 3 + .../actix_identity/trait.IdentityPolicy.js | 3 + .../actix_identity/trait.RequestIdentity.js | 3 + .../trait.ProtoBufResponseBuilder.js | 3 + .../transform/trait.Transform.js | 6 +- .../actix_session/trait.UserSession.js | 3 + .../actix_web/extract/trait.FromRequest.js | 6 + .../actix_web/responder/trait.Responder.js | 3 + .../extractors/trait.AuthExtractor.js | 3 + .../extractors/trait.AuthExtractorConfig.js | 3 + .../headers/authorization/trait.Scheme.js | 3 + implementors/core/clone/trait.Clone.js | 7 + implementors/core/cmp/trait.Eq.js | 3 + implementors/core/cmp/trait.Ord.js | 3 + implementors/core/cmp/trait.PartialEq.js | 5 + implementors/core/cmp/trait.PartialOrd.js | 3 + implementors/core/convert/trait.AsMut.js | 3 + implementors/core/convert/trait.AsRef.js | 3 + implementors/core/convert/trait.From.js | 4 +- implementors/core/default/trait.Default.js | 7 + implementors/core/fmt/trait.Debug.js | 7 +- implementors/core/fmt/trait.Display.js | 5 +- .../core/future/future/trait.Future.js | 3 + implementors/core/hash/trait.Hash.js | 3 + implementors/core/marker/trait.Copy.js | 3 + implementors/core/marker/trait.Freeze.js | 8 +- implementors/core/marker/trait.Send.js | 8 +- .../core/marker/trait.StructuralEq.js | 3 + .../core/marker/trait.StructuralPartialEq.js | 5 + implementors/core/marker/trait.Sync.js | 8 +- implementors/core/marker/trait.Unpin.js | 8 +- implementors/core/ops/deref/trait.Deref.js | 3 + implementors/core/ops/deref/trait.DerefMut.js | 3 + implementors/prost/message/trait.Message.js | 3 + implementors/std/error/trait.Error.js | 4 +- implementors/std/panic/trait.RefUnwindSafe.js | 8 +- implementors/std/panic/trait.UnwindSafe.js | 8 +- index.html | 2 +- light.css | 2 +- main.js | 6 +- noscript.css | 2 +- prost_example/all.html | 7 + prost_example/fn.index.html | 5 + prost_example/fn.main.html | 5 + prost_example/index.html | 7 + prost_example/sidebar-items.js | 1 + prost_example/struct.MyObj.html | 43 + rustdoc.css | 2 +- search-index.js | 10 +- settings.html | 9 +- source-files.js | 6 + source-script.js | 2 +- src/actix_cors/all_or_some.rs.html | 115 + src/actix_cors/builder.rs.html | 1257 +++++++++ src/actix_cors/error.rs.html | 117 + src/actix_cors/inner.rs.html | 681 +++++ src/actix_cors/lib.rs.html | 125 + src/actix_cors/middleware.rs.html | 439 ++++ src/actix_identity/lib.rs.html | 2291 +++++++++++++++++ src/actix_protobuf/lib.rs.html | 655 +++++ src/actix_redis/lib.rs.html | 9 +- src/actix_redis/redis.rs.html | 9 +- src/actix_redis/session.rs.html | 9 +- src/actix_session/cookie.rs.html | 1107 ++++++++ src/actix_session/lib.rs.html | 671 +++++ .../extractors/basic.rs.html | 311 +++ .../extractors/bearer.rs.html | 367 +++ .../extractors/config.rs.html | 53 + .../extractors/errors.rs.html | 171 ++ src/actix_web_httpauth/extractors/mod.rs.html | 73 + .../headers/authorization/errors.rs.html | 145 ++ .../headers/authorization/header.rs.html | 213 ++ .../headers/authorization/mod.rs.html | 29 + .../authorization/scheme/basic.rs.html | 401 +++ .../authorization/scheme/bearer.rs.html | 283 ++ .../headers/authorization/scheme/mod.rs.html | 37 + src/actix_web_httpauth/headers/mod.rs.html | 15 + .../www_authenticate/challenge/basic.rs.html | 287 +++ .../challenge/bearer/builder.rs.html | 133 + .../challenge/bearer/challenge.rs.html | 285 ++ .../challenge/bearer/errors.rs.html | 109 + .../challenge/bearer/mod.rs.html | 31 + .../www_authenticate/challenge/mod.rs.html | 33 + .../headers/www_authenticate/header.rs.html | 73 + .../headers/www_authenticate/mod.rs.html | 25 + src/actix_web_httpauth/lib.rs.html | 55 + src/actix_web_httpauth/middleware.rs.html | 611 +++++ src/actix_web_httpauth/utils.rs.html | 229 ++ src/prost_example/main.rs.html | 73 + storage.js | 2 +- 199 files changed, 14165 insertions(+), 202 deletions(-) create mode 100644 FiraSans-Medium.woff2 create mode 100644 FiraSans-Regular.woff2 create mode 100644 actix_cors/all.html create mode 100644 actix_cors/builder/struct.Cors.html create mode 100644 actix_cors/enum.CorsError.html create mode 100644 actix_cors/error/enum.CorsError.html create mode 100644 actix_cors/index.html create mode 100644 actix_cors/sidebar-items.js create mode 100644 actix_cors/struct.Cors.html create mode 100644 actix_identity/all.html create mode 100644 actix_identity/index.html create mode 100644 actix_identity/sidebar-items.js create mode 100644 actix_identity/struct.CookieIdentityPolicy.html create mode 100644 actix_identity/struct.Identity.html create mode 100644 actix_identity/struct.IdentityService.html create mode 100644 actix_identity/trait.IdentityPolicy.html create mode 100644 actix_identity/trait.RequestIdentity.html create mode 100644 actix_protobuf/all.html create mode 100644 actix_protobuf/enum.ProtoBufPayloadError.html create mode 100644 actix_protobuf/index.html create mode 100644 actix_protobuf/sidebar-items.js create mode 100644 actix_protobuf/struct.ProtoBuf.html create mode 100644 actix_protobuf/struct.ProtoBufConfig.html create mode 100644 actix_protobuf/struct.ProtoBufMessage.html create mode 100644 actix_protobuf/trait.ProtoBufResponseBuilder.html create mode 100644 actix_session/all.html create mode 100644 actix_session/cookie/struct.CookieSession.html create mode 100644 actix_session/enum.SessionStatus.html create mode 100644 actix_session/index.html create mode 100644 actix_session/sidebar-items.js create mode 100644 actix_session/struct.CookieSession.html create mode 100644 actix_session/struct.Session.html create mode 100644 actix_session/trait.UserSession.html create mode 100644 actix_web_httpauth/all.html create mode 100644 actix_web_httpauth/extractors/basic/index.html create mode 100644 actix_web_httpauth/extractors/basic/sidebar-items.js create mode 100644 actix_web_httpauth/extractors/basic/struct.BasicAuth.html create mode 100644 actix_web_httpauth/extractors/basic/struct.Config.html create mode 100644 actix_web_httpauth/extractors/bearer/enum.Error.html create mode 100644 actix_web_httpauth/extractors/bearer/index.html create mode 100644 actix_web_httpauth/extractors/bearer/sidebar-items.js create mode 100644 actix_web_httpauth/extractors/bearer/struct.BearerAuth.html create mode 100644 actix_web_httpauth/extractors/bearer/struct.Config.html create mode 100644 actix_web_httpauth/extractors/config/trait.AuthExtractorConfig.html create mode 100644 actix_web_httpauth/extractors/errors/struct.AuthenticationError.html create mode 100644 actix_web_httpauth/extractors/index.html create mode 100644 actix_web_httpauth/extractors/sidebar-items.js create mode 100644 actix_web_httpauth/extractors/struct.AuthenticationError.html create mode 100644 actix_web_httpauth/extractors/trait.AuthExtractor.html create mode 100644 actix_web_httpauth/extractors/trait.AuthExtractorConfig.html create mode 100644 actix_web_httpauth/headers/authorization/enum.ParseError.html create mode 100644 actix_web_httpauth/headers/authorization/errors/enum.ParseError.html create mode 100644 actix_web_httpauth/headers/authorization/header/struct.Authorization.html create mode 100644 actix_web_httpauth/headers/authorization/index.html create mode 100644 actix_web_httpauth/headers/authorization/scheme/basic/struct.Basic.html create mode 100644 actix_web_httpauth/headers/authorization/scheme/bearer/struct.Bearer.html create mode 100644 actix_web_httpauth/headers/authorization/scheme/trait.Scheme.html create mode 100644 actix_web_httpauth/headers/authorization/sidebar-items.js create mode 100644 actix_web_httpauth/headers/authorization/struct.Authorization.html create mode 100644 actix_web_httpauth/headers/authorization/struct.Basic.html create mode 100644 actix_web_httpauth/headers/authorization/struct.Bearer.html create mode 100644 actix_web_httpauth/headers/authorization/trait.Scheme.html create mode 100644 actix_web_httpauth/headers/index.html create mode 100644 actix_web_httpauth/headers/sidebar-items.js create mode 100644 actix_web_httpauth/headers/www_authenticate/basic/index.html create mode 100644 actix_web_httpauth/headers/www_authenticate/basic/sidebar-items.js create mode 100644 actix_web_httpauth/headers/www_authenticate/basic/struct.Basic.html create mode 100644 actix_web_httpauth/headers/www_authenticate/bearer/enum.Error.html create mode 100644 actix_web_httpauth/headers/www_authenticate/bearer/index.html create mode 100644 actix_web_httpauth/headers/www_authenticate/bearer/sidebar-items.js create mode 100644 actix_web_httpauth/headers/www_authenticate/bearer/struct.Bearer.html create mode 100644 actix_web_httpauth/headers/www_authenticate/bearer/struct.BearerBuilder.html create mode 100644 actix_web_httpauth/headers/www_authenticate/challenge/basic/index.html create mode 100644 actix_web_httpauth/headers/www_authenticate/challenge/basic/struct.Basic.html create mode 100644 actix_web_httpauth/headers/www_authenticate/challenge/bearer/builder/struct.BearerBuilder.html create mode 100644 actix_web_httpauth/headers/www_authenticate/challenge/bearer/challenge/struct.Bearer.html create mode 100644 actix_web_httpauth/headers/www_authenticate/challenge/bearer/errors/enum.Error.html create mode 100644 actix_web_httpauth/headers/www_authenticate/challenge/bearer/index.html create mode 100644 actix_web_httpauth/headers/www_authenticate/challenge/trait.Challenge.html create mode 100644 actix_web_httpauth/headers/www_authenticate/header/struct.WwwAuthenticate.html create mode 100644 actix_web_httpauth/headers/www_authenticate/index.html create mode 100644 actix_web_httpauth/headers/www_authenticate/sidebar-items.js create mode 100644 actix_web_httpauth/headers/www_authenticate/struct.WwwAuthenticate.html create mode 100644 actix_web_httpauth/headers/www_authenticate/trait.Challenge.html create mode 100644 actix_web_httpauth/index.html create mode 100644 actix_web_httpauth/middleware/index.html create mode 100644 actix_web_httpauth/middleware/sidebar-items.js create mode 100644 actix_web_httpauth/middleware/struct.HttpAuthentication.html create mode 100644 actix_web_httpauth/sidebar-items.js create mode 100644 crates.js create mode 100644 implementors/actix_http/header/into_value/trait.IntoHeaderValue.js create mode 100644 implementors/actix_http/header/trait.Header.js create mode 100644 implementors/actix_identity/trait.IdentityPolicy.js create mode 100644 implementors/actix_identity/trait.RequestIdentity.js create mode 100644 implementors/actix_protobuf/trait.ProtoBufResponseBuilder.js create mode 100644 implementors/actix_session/trait.UserSession.js create mode 100644 implementors/actix_web/extract/trait.FromRequest.js create mode 100644 implementors/actix_web/responder/trait.Responder.js create mode 100644 implementors/actix_web_httpauth/extractors/trait.AuthExtractor.js create mode 100644 implementors/actix_web_httpauth/extractors/trait.AuthExtractorConfig.js create mode 100644 implementors/actix_web_httpauth/headers/authorization/trait.Scheme.js create mode 100644 implementors/core/clone/trait.Clone.js create mode 100644 implementors/core/cmp/trait.Eq.js create mode 100644 implementors/core/cmp/trait.Ord.js create mode 100644 implementors/core/cmp/trait.PartialEq.js create mode 100644 implementors/core/cmp/trait.PartialOrd.js create mode 100644 implementors/core/convert/trait.AsMut.js create mode 100644 implementors/core/convert/trait.AsRef.js create mode 100644 implementors/core/default/trait.Default.js create mode 100644 implementors/core/future/future/trait.Future.js create mode 100644 implementors/core/hash/trait.Hash.js create mode 100644 implementors/core/marker/trait.Copy.js create mode 100644 implementors/core/marker/trait.StructuralEq.js create mode 100644 implementors/core/marker/trait.StructuralPartialEq.js create mode 100644 implementors/core/ops/deref/trait.Deref.js create mode 100644 implementors/core/ops/deref/trait.DerefMut.js create mode 100644 implementors/prost/message/trait.Message.js create mode 100644 prost_example/all.html create mode 100644 prost_example/fn.index.html create mode 100644 prost_example/fn.main.html create mode 100644 prost_example/index.html create mode 100644 prost_example/sidebar-items.js create mode 100644 prost_example/struct.MyObj.html create mode 100644 src/actix_cors/all_or_some.rs.html create mode 100644 src/actix_cors/builder.rs.html create mode 100644 src/actix_cors/error.rs.html create mode 100644 src/actix_cors/inner.rs.html create mode 100644 src/actix_cors/lib.rs.html create mode 100644 src/actix_cors/middleware.rs.html create mode 100644 src/actix_identity/lib.rs.html create mode 100644 src/actix_protobuf/lib.rs.html create mode 100644 src/actix_session/cookie.rs.html create mode 100644 src/actix_session/lib.rs.html create mode 100644 src/actix_web_httpauth/extractors/basic.rs.html create mode 100644 src/actix_web_httpauth/extractors/bearer.rs.html create mode 100644 src/actix_web_httpauth/extractors/config.rs.html create mode 100644 src/actix_web_httpauth/extractors/errors.rs.html create mode 100644 src/actix_web_httpauth/extractors/mod.rs.html create mode 100644 src/actix_web_httpauth/headers/authorization/errors.rs.html create mode 100644 src/actix_web_httpauth/headers/authorization/header.rs.html create mode 100644 src/actix_web_httpauth/headers/authorization/mod.rs.html create mode 100644 src/actix_web_httpauth/headers/authorization/scheme/basic.rs.html create mode 100644 src/actix_web_httpauth/headers/authorization/scheme/bearer.rs.html create mode 100644 src/actix_web_httpauth/headers/authorization/scheme/mod.rs.html create mode 100644 src/actix_web_httpauth/headers/mod.rs.html create mode 100644 src/actix_web_httpauth/headers/www_authenticate/challenge/basic.rs.html create mode 100644 src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/builder.rs.html create mode 100644 src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/challenge.rs.html create mode 100644 src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/errors.rs.html create mode 100644 src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/mod.rs.html create mode 100644 src/actix_web_httpauth/headers/www_authenticate/challenge/mod.rs.html create mode 100644 src/actix_web_httpauth/headers/www_authenticate/header.rs.html create mode 100644 src/actix_web_httpauth/headers/www_authenticate/mod.rs.html create mode 100644 src/actix_web_httpauth/lib.rs.html create mode 100644 src/actix_web_httpauth/middleware.rs.html create mode 100644 src/actix_web_httpauth/utils.rs.html create mode 100644 src/prost_example/main.rs.html diff --git a/FiraSans-Medium.woff2 b/FiraSans-Medium.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..7a1e5fc548ef28137a32150b6aa50a568cd53d02 GIT binary patch literal 132780 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�|o|A<_G9#bJ&K$mXTSM@kZfZ^-ZYS)6EG~kHJ{! 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

TIWHPC<_9>em(Cvlhuf-BD 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 literal 0 HcmV?d00001 diff --git a/FiraSans-Regular.woff2 b/FiraSans-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e766e06ccb0d457fcdc8d4428efb796c7772a497 GIT binary patch literal 129188 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

)Thpg9J)x+@B(n?maf9&#`PQNHtKX<@|CQ`> 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 N#!G)s;List of all items in this crate

List of all items[] + +

Structs

Enums

+ \ No newline at end of file diff --git a/actix_cors/builder/struct.Cors.html b/actix_cors/builder/struct.Cors.html new file mode 100644 index 000000000..68e229708 --- /dev/null +++ b/actix_cors/builder/struct.Cors.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../actix_cors/struct.Cors.html...

+ + + \ No newline at end of file diff --git a/actix_cors/enum.CorsError.html b/actix_cors/enum.CorsError.html new file mode 100644 index 000000000..8c0cc968c --- /dev/null +++ b/actix_cors/enum.CorsError.html @@ -0,0 +1,52 @@ +actix_cors::CorsError - Rust

Enum actix_cors::CorsError[][src]

#[non_exhaustive]pub enum CorsError {
+    WildcardOrigin,
+    MissingOrigin,
+    MissingRequestMethod,
+    BadRequestMethod,
+    BadRequestHeaders,
+    OriginNotAllowed,
+    MethodNotAllowed,
+    HeadersNotAllowed,
+}

Errors that can occur when processing CORS guarded requests.

+

+ Variants (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.
WildcardOrigin

Allowed origin argument must not be wildcard (*).

+
MissingOrigin

Request header Origin is required but was not provided.

+
MissingRequestMethod

Request header Access-Control-Request-Method is required but is missing.

+
BadRequestMethod

Request header Access-Control-Request-Method has an invalid value.

+
BadRequestHeaders

Request header Access-Control-Request-Headers has an invalid value.

+
OriginNotAllowed

Origin is not allowed to make this request.

+
MethodNotAllowed

Request method is not allowed.

+
HeadersNotAllowed

One or more request headers are not allowed.

+

Trait Implementations

impl Clone for CorsError[src]

impl Debug for CorsError[src]

impl Display for CorsError[src]

impl Error for CorsError[src]

impl ResponseError for CorsError[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_cors/error/enum.CorsError.html b/actix_cors/error/enum.CorsError.html new file mode 100644 index 000000000..17229c03c --- /dev/null +++ b/actix_cors/error/enum.CorsError.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../actix_cors/enum.CorsError.html...

+ + + \ No newline at end of file diff --git a/actix_cors/index.html b/actix_cors/index.html new file mode 100644 index 000000000..48aa31475 --- /dev/null +++ b/actix_cors/index.html @@ -0,0 +1,45 @@ +actix_cors - Rust

Crate actix_cors[][src]

Cross-Origin Resource Sharing (CORS) controls for Actix Web.

+

This middleware can be applied to both applications and resources. Once built, a +Cors builder can be used as an argument for Actix Web’s App::wrap(), +Scope::wrap(), or Resource::wrap() methods.

+

This CORS middleware automatically handles OPTIONS preflight requests.

+

Example

+
+use actix_cors::Cors;
+use actix_web::{get, http, web, App, HttpRequest, HttpResponse, HttpServer};
+
+#[get("/index.html")]
+async fn index(req: HttpRequest) -> &'static str {
+    "<p>Hello World!</p>"
+}
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(|| {
+        let cors = Cors::default()
+              .allowed_origin("https://www.rust-lang.org/")
+              .allowed_origin_fn(|origin, _req_head| {
+                  origin.as_bytes().ends_with(b".rust-lang.org")
+              })
+              .allowed_methods(vec!["GET", "POST"])
+              .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
+              .allowed_header(http::header::CONTENT_TYPE)
+              .max_age(3600);
+
+        App::new()
+            .wrap(cors)
+            .service(index)
+    })
+    .bind(("127.0.0.1", 8080))?
+    .run()
+    .await;
+
+    Ok(())
+}
+

Structs

+
Cors

Builder for CORS middleware.

+

Enums

+
CorsError

Errors that can occur when processing CORS guarded requests.

+
+ \ No newline at end of file diff --git a/actix_cors/sidebar-items.js b/actix_cors/sidebar-items.js new file mode 100644 index 000000000..f4876e792 --- /dev/null +++ b/actix_cors/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["CorsError","Errors that can occur when processing CORS guarded requests."]],"struct":[["Cors","Builder for CORS middleware."]]}); \ No newline at end of file diff --git a/actix_cors/struct.Cors.html b/actix_cors/struct.Cors.html new file mode 100644 index 000000000..d46cb27c9 --- /dev/null +++ b/actix_cors/struct.Cors.html @@ -0,0 +1,133 @@ +actix_cors::Cors - Rust

Struct actix_cors::Cors[][src]

pub struct Cors { /* fields omitted */ }

Builder for CORS middleware.

+

To construct a CORS middleware, call Cors::default() to create a blank, restrictive builder. +Then use any of the builder methods to customize CORS behavior.

+

The alternative Cors::permissive() constructor is available for local development, allowing +all origins and headers, etc. The permissive constructor should not be used in production.

+

Errors

+

Errors surface in the middleware initialization phase. This means that, if you have logs enabled +in Actix Web (using env_logger or other crate that exposes logs from the log crate), error +messages will outline what is wrong with the CORS configuration in the server logs and the +server will fail to start up or serve requests.

+

Example

+
+use actix_cors::Cors;
+use actix_web::http::header;
+
+let cors = Cors::default()
+    .allowed_origin("https://www.rust-lang.org")
+    .allowed_methods(vec!["GET", "POST"])
+    .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
+    .allowed_header(header::CONTENT_TYPE)
+    .max_age(3600);
+
+// `cors` can now be used in `App::wrap`.
+

Implementations

impl Cors[src]

pub fn permissive() -> Self[src]

A very permissive set of default for quick development. Not recommended for production use.

+

All origins, methods, request headers and exposed headers allowed. Credentials supported. +Max age 1 hour. Does not send wildcard.

+

pub fn allow_any_origin(self) -> Cors[src]

Resets allowed origin list to a state where any origin is accepted.

+

See Cors::allowed_origin for more info on allowed origins.

+

pub fn allowed_origin(self, origin: &str) -> Cors[src]

Add an origin that is allowed to make requests.

+

By default, requests from all origins are accepted by CORS logic. This method allows to +specify a finite set of origins to verify the value of the Origin request header.

+

These are origin-or-null types in the Fetch Standard.

+

When this list is set, the client’s Origin request header will be checked in a +case-sensitive manner.

+

When all origins are allowed and send_wildcard is set, * will be sent in the +Access-Control-Allow-Origin response header. If send_wildcard is not set, the client’s +Origin request header will be echoed back in the Access-Control-Allow-Origin +response header.

+

If the origin of the request doesn’t match any allowed origins and at least one +allowed_origin_fn function is set, these functions will be used to determinate +allowed origins.

+

Initialization Errors

+
    +
  • If supplied origin is not valid uri
  • +
  • If supplied origin is a wildcard (*). Cors::send_wildcard should be used instead.
  • +
+

pub fn allowed_origin_fn<F>(self, f: F) -> Cors where
    F: Fn(&HeaderValue, &RequestHead) -> bool + 'static, 
[src]

Determinate allowed origins by processing requests which didn’t match any origins specified +in the allowed_origin.

+

The function will receive two parameters, the Origin header value, and the RequestHead of +each request, which can be used to determine whether to allow the request or not.

+

If the function returns true, the client’s Origin request header will be echoed back +into the Access-Control-Allow-Origin response header.

+

pub fn allow_any_method(self) -> Cors[src]

Resets allowed methods list to all methods.

+

See Cors::allowed_methods for more info on allowed methods.

+

pub fn allowed_methods<U, M>(self, methods: U) -> Cors where
    U: IntoIterator<Item = M>,
    M: TryInto<Method>,
    <M as TryInto<Method>>::Error: Into<HttpError>, 
[src]

Set a list of methods which allowed origins can perform.

+

These will be sent in the Access-Control-Allow-Methods response header as specified in +the Fetch Standard CORS protocol.

+

Defaults to [GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE]

+

pub fn allow_any_header(self) -> Cors[src]

Resets allowed request header list to a state where any header is accepted.

+

See Cors::allowed_headers for more info on allowed request headers.

+

pub fn allowed_header<H>(self, header: H) -> Cors where
    H: TryInto<HeaderName>,
    <H as TryInto<HeaderName>>::Error: Into<HttpError>, 
[src]

Add an allowed request header.

+

See Cors::allowed_headers for more info on allowed request headers.

+

pub fn allowed_headers<U, H>(self, headers: U) -> Cors where
    U: IntoIterator<Item = H>,
    H: TryInto<HeaderName>,
    <H as TryInto<HeaderName>>::Error: Into<HttpError>, 
[src]

Set a list of request header field names which can be used when this resource is accessed by +allowed origins.

+

If All is set, whatever is requested by the client in Access-Control-Request-Headers +will be echoed back in the Access-Control-Allow-Headers header as specified in +the Fetch Standard CORS protocol.

+

Defaults to All.

+

pub fn expose_any_header(self) -> Cors[src]

Resets exposed response header list to a state where any header is accepted.

+

See Cors::expose_headers for more info on exposed response headers.

+

pub fn expose_headers<U, H>(self, headers: U) -> Cors where
    U: IntoIterator<Item = H>,
    H: TryInto<HeaderName>,
    <H as TryInto<HeaderName>>::Error: Into<HttpError>, 
[src]

Set a list of headers which are safe to expose to the API of a CORS API specification. +This corresponds to the Access-Control-Expose-Headers response header as specified in +the Fetch Standard CORS protocol.

+

This defaults to an empty set.

+

pub fn max_age(self, max_age: impl Into<Option<usize>>) -> Cors[src]

Set a maximum time (in seconds) for which this CORS request maybe cached. +This value is set as the Access-Control-Max-Age header as specified in +the Fetch Standard CORS protocol.

+

Pass a number (of seconds) or use None to disable sending max age header.

+

pub fn send_wildcard(self) -> Cors[src]

Set to use wildcard origins.

+

If send wildcard is set and the allowed_origins parameter is All, a wildcard +Access-Control-Allow-Origin response header is sent, rather than the request’s +Origin header.

+

This CANNOT be used in conjunction with allowed_origins set to All and +allow_credentials set to true. Depending on the mode of usage, this will either result +in an CorsError::CredentialsWithWildcardOrigin error during actix launch or runtime.

+

Defaults to false.

+

pub fn supports_credentials(self) -> Cors[src]

Allows users to make authenticated requests

+

If true, injects the Access-Control-Allow-Credentials header in responses. This allows +cookies and credentials to be submitted across domains as specified in +the Fetch Standard CORS protocol.

+

This option cannot be used in conjunction with an allowed_origin set to All and +send_wildcards set to true.

+

Defaults to false.

+

A server initialization error will occur if credentials are allowed, but the Origin is set +to send wildcards (*); this is not allowed by the CORS protocol.

+

pub fn disable_vary_header(self) -> Cors[src]

Disable Vary header support.

+

When enabled the header Vary: Origin will be returned as per the Fetch Standard +implementation guidelines.

+

Setting this header when the Access-Control-Allow-Origin is dynamically generated +(eg. when there is more than one allowed origin, and an Origin other than ‘*’ is returned) +informs CDNs and other caches that the CORS headers are dynamic, and cannot be cached.

+

By default, Vary header support is enabled.

+

pub fn disable_preflight(self) -> Cors[src]

Disable support for preflight requests.

+

When enabled CORS middleware automatically handles OPTIONS requests. +This is useful for application level middleware.

+

By default preflight support is enabled.

+

Trait Implementations

impl Debug for Cors[src]

impl Default for Cors[src]

fn default() -> Cors[src]

A restrictive (security paranoid) set of defaults.

+

No allowed origins, methods, request headers or exposed headers. Credentials +not supported. No max age (will use browser’s default).

+

impl<S, B> Transform<S, ServiceRequest> for Cors where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static, 
[src]

type Response = ServiceResponse<B>

Responses produced by the service.

+

type Error = Error

Errors produced by the service.

+

type InitError = ()

Errors produced while building a transform service.

+

type Transform = CorsMiddleware<S>

The TransformService value created by this factory

+

type Future = Ready<Result<Self::Transform, Self::InitError>>

The future response value.

+

Auto Trait Implementations

impl !RefUnwindSafe for Cors

impl !Send for Cors

impl !Sync for Cors

impl Unpin for Cors

impl !UnwindSafe for Cors

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_identity/all.html b/actix_identity/all.html new file mode 100644 index 000000000..bc1a84395 --- /dev/null +++ b/actix_identity/all.html @@ -0,0 +1,7 @@ +List of all items in this crate + +

List of all items[] + +

Structs

Traits

+ \ No newline at end of file diff --git a/actix_identity/index.html b/actix_identity/index.html new file mode 100644 index 000000000..2a462ce7c --- /dev/null +++ b/actix_identity/index.html @@ -0,0 +1,55 @@ +actix_identity - Rust + +

Crate actix_identity[][src]

Request identity service for Actix applications.

+

IdentityService middleware can be +used with different policies types to store identity information.

+

By default, only cookie identity policy is implemented. Other backend +implementations can be added separately.

+

CookieIdentityPolicy +uses cookies as identity storage.

+

To access current request identity +Identity extractor should be used.

+ +
+use actix_web::*;
+use actix_identity::{Identity, CookieIdentityPolicy, IdentityService};
+
+async fn index(id: Identity) -> String {
+    // access request identity
+    if let Some(id) = id.identity() {
+        format!("Welcome! {}", id)
+    } else {
+        "Welcome Anonymous!".to_owned()
+    }
+}
+
+async fn login(id: Identity) -> HttpResponse {
+    id.remember("User1".to_owned()); // <- remember identity
+    HttpResponse::Ok().finish()
+}
+
+async fn logout(id: Identity) -> HttpResponse {
+    id.forget();                      // <- remove identity
+    HttpResponse::Ok().finish()
+}
+
+fn main() {
+    let app = App::new().wrap(IdentityService::new(
+        // <- create identity middleware
+        CookieIdentityPolicy::new(&[0; 32])    // <- create cookie identity policy
+              .name("auth-cookie")
+              .secure(false)))
+        .service(web::resource("/index.html").to(index))
+        .service(web::resource("/login.html").to(login))
+        .service(web::resource("/logout.html").to(logout));
+}
+

Structs

+
CookieIdentityPolicy

Use cookies for request identity storage.

+
Identity

The extractor type to obtain your identity from a request.

+
IdentityService

Request identity middleware

+

Traits

+
IdentityPolicy

Identity policy definition.

+
RequestIdentity

Helper trait that allows to get Identity.

+
+ \ No newline at end of file diff --git a/actix_identity/sidebar-items.js b/actix_identity/sidebar-items.js new file mode 100644 index 000000000..422cb1564 --- /dev/null +++ b/actix_identity/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["CookieIdentityPolicy","Use cookies for request identity storage."],["Identity","The extractor type to obtain your identity from a request."],["IdentityService","Request identity middleware"]],"trait":[["IdentityPolicy","Identity policy definition."],["RequestIdentity","Helper trait that allows to get Identity."]]}); \ No newline at end of file diff --git a/actix_identity/struct.CookieIdentityPolicy.html b/actix_identity/struct.CookieIdentityPolicy.html new file mode 100644 index 000000000..1717e0983 --- /dev/null +++ b/actix_identity/struct.CookieIdentityPolicy.html @@ -0,0 +1,57 @@ +actix_identity::CookieIdentityPolicy - Rust + +

Struct actix_identity::CookieIdentityPolicy[][src]

pub struct CookieIdentityPolicy(_);

Use cookies for request identity storage.

+

The constructors take a key as an argument. +This is the private key for cookie - when this value is changed, +all identities are lost. The constructors will panic if the key is less +than 32 bytes in length.

+

Example

+
+use actix_web::App;
+use actix_identity::{CookieIdentityPolicy, IdentityService};
+
+let app = App::new().wrap(IdentityService::new(
+    // <- create identity middleware
+    CookieIdentityPolicy::new(&[0; 32])  // <- construct cookie policy
+           .domain("www.rust-lang.org")
+           .name("actix_auth")
+           .path("/")
+           .secure(true),
+));
+

Implementations

impl CookieIdentityPolicy[src]

pub fn new(key: &[u8]) -> CookieIdentityPolicy[src]

Construct new CookieIdentityPolicy instance.

+

Panics if key length is less than 32 bytes.

+

pub fn path<S: Into<String>>(self, value: S) -> CookieIdentityPolicy[src]

Sets the path field in the session cookie being built.

+

pub fn name<S: Into<String>>(self, value: S) -> CookieIdentityPolicy[src]

Sets the name field in the session cookie being built.

+

pub fn domain<S: Into<String>>(self, value: S) -> CookieIdentityPolicy[src]

Sets the domain field in the session cookie being built.

+

pub fn secure(self, value: bool) -> CookieIdentityPolicy[src]

Sets the secure field in the session cookie being built.

+

If the secure field is set, a cookie will only be transmitted when the +connection is secure - i.e. https

+

pub fn max_age(self, seconds: i64) -> CookieIdentityPolicy[src]

Sets the max-age field in the session cookie being built with given number of seconds.

+

pub fn max_age_time(self, value: Duration) -> CookieIdentityPolicy[src]

Sets the max-age field in the session cookie being built with time::Duration.

+

pub fn http_only(self, http_only: bool) -> Self[src]

Sets the http_only field in the session cookie being built.

+

pub fn same_site(self, same_site: SameSite) -> Self[src]

Sets the same_site field in the session cookie being built.

+

pub fn visit_deadline(self, value: Duration) -> CookieIdentityPolicy[src]

Accepts only users whose cookie has been seen before the given deadline

+

By default visit deadline is disabled.

+

pub fn login_deadline(self, value: Duration) -> CookieIdentityPolicy[src]

Accepts only users which has been authenticated before the given deadline

+

By default login deadline is disabled.

+

Trait Implementations

impl IdentityPolicy for CookieIdentityPolicy[src]

type Future = Ready<Result<Option<String>, Error>>

The return type of the middleware

+

type ResponseFuture = Ready<Result<(), Error>>

The return type of the middleware

+

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_identity/struct.Identity.html b/actix_identity/struct.Identity.html new file mode 100644 index 000000000..6e710549c --- /dev/null +++ b/actix_identity/struct.Identity.html @@ -0,0 +1,73 @@ +actix_identity::Identity - Rust + +

Struct actix_identity::Identity[][src]

pub struct Identity(_);

The extractor type to obtain your identity from a request.

+ +
+use actix_web::*;
+use actix_identity::Identity;
+
+fn index(id: Identity) -> Result<String> {
+    // access request identity
+    if let Some(id) = id.identity() {
+        Ok(format!("Welcome! {}", id))
+    } else {
+        Ok("Welcome Anonymous!".to_owned())
+    }
+}
+
+fn login(id: Identity) -> HttpResponse {
+    id.remember("User1".to_owned()); // <- remember identity
+    HttpResponse::Ok().finish()
+}
+
+fn logout(id: Identity) -> HttpResponse {
+    id.forget(); // <- remove identity
+    HttpResponse::Ok().finish()
+}
+

Implementations

impl Identity[src]

pub fn identity(&self) -> Option<String>[src]

Return the claimed identity of the user associated request or +None if no identity can be found associated with the request.

+

pub fn remember(&self, identity: String)[src]

Remember identity.

+

pub fn forget(&self)[src]

This method is used to ‘forget’ the current identity on subsequent +requests.

+

Trait Implementations

impl Clone for Identity[src]

impl FromRequest for Identity[src]

Extractor implementation for Identity type.

+ +
+use actix_identity::Identity;
+
+fn index(id: Identity) -> String {
+    // access request identity
+    if let Some(id) = id.identity() {
+        format!("Welcome! {}", id)
+    } else {
+        "Welcome Anonymous!".to_owned()
+    }
+}
+

type Config = ()

Configuration for this extractor.

+

type Error = Error

The associated error which can be returned.

+

type Future = Ready<Result<Identity, Error>>

Future that resolves to a Self.

+

Auto Trait Implementations

impl !RefUnwindSafe for Identity

impl !Send for Identity

impl !Sync for Identity

impl Unpin for Identity

impl !UnwindSafe for Identity

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_identity/struct.IdentityService.html b/actix_identity/struct.IdentityService.html new file mode 100644 index 000000000..99975c676 --- /dev/null +++ b/actix_identity/struct.IdentityService.html @@ -0,0 +1,38 @@ +actix_identity::IdentityService - Rust + +

Struct actix_identity::IdentityService[][src]

pub struct IdentityService<T> { /* fields omitted */ }

Request identity middleware

+ +
+use actix_web::App;
+use actix_identity::{CookieIdentityPolicy, IdentityService};
+
+let app = App::new().wrap(IdentityService::new(
+    // <- create identity middleware
+    CookieIdentityPolicy::new(&[0; 32])    // <- create cookie session backend
+          .name("auth-cookie")
+          .secure(false),
+));
+

Implementations

impl<T> IdentityService<T>[src]

pub fn new(backend: T) -> Self[src]

Create new identity service with specified backend.

+

Trait Implementations

impl<S, T, B> Transform<S, ServiceRequest> for IdentityService<T> where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    T: IdentityPolicy,
    B: 'static, 
[src]

type Response = ServiceResponse<B>

Responses produced by the service.

+

type Error = Error

Errors produced by the service.

+

type InitError = ()

Errors produced while building a transform service.

+

type Transform = IdentityServiceMiddleware<S, T>

The TransformService value created by this factory

+

type Future = Ready<Result<Self::Transform, Self::InitError>>

The future response value.

+

Auto Trait Implementations

impl<T> !RefUnwindSafe for IdentityService<T>

impl<T> !Send for IdentityService<T>

impl<T> !Sync for IdentityService<T>

impl<T> Unpin for IdentityService<T>

impl<T> UnwindSafe for IdentityService<T> where
    T: RefUnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_identity/trait.IdentityPolicy.html b/actix_identity/trait.IdentityPolicy.html new file mode 100644 index 000000000..df98b1b4a --- /dev/null +++ b/actix_identity/trait.IdentityPolicy.html @@ -0,0 +1,15 @@ +actix_identity::IdentityPolicy - Rust + +

Trait actix_identity::IdentityPolicy[][src]

pub trait IdentityPolicy: Sized + 'static {
+    type Future: Future<Output = Result<Option<String>, Error>>;
+    type ResponseFuture: Future<Output = Result<(), Error>>;
+    fn from_request(&self, request: &mut ServiceRequest) -> Self::Future;
+
fn to_response<B>(
        &self,
        identity: Option<String>,
        changed: bool,
        response: &mut ServiceResponse<B>
    ) -> Self::ResponseFuture; +}

Identity policy definition.

+

Associated Types

type Future: Future<Output = Result<Option<String>, Error>>[src]

The return type of the middleware

+

type ResponseFuture: Future<Output = Result<(), Error>>[src]

The return type of the middleware

+
Loading content...

Required methods

fn from_request(&self, request: &mut ServiceRequest) -> Self::Future[src]

Parse the session from request and load data from a service identity.

+

fn to_response<B>(
    &self,
    identity: Option<String>,
    changed: bool,
    response: &mut ServiceResponse<B>
) -> Self::ResponseFuture
[src]

Write changes to response

+
Loading content...

Implementors

impl IdentityPolicy for CookieIdentityPolicy[src]

type Future = Ready<Result<Option<String>, Error>>

type ResponseFuture = Ready<Result<(), Error>>

Loading content...
+ \ No newline at end of file diff --git a/actix_identity/trait.RequestIdentity.html b/actix_identity/trait.RequestIdentity.html new file mode 100644 index 000000000..061b1cb99 --- /dev/null +++ b/actix_identity/trait.RequestIdentity.html @@ -0,0 +1,10 @@ +actix_identity::RequestIdentity - Rust + +

Trait actix_identity::RequestIdentity[][src]

pub trait RequestIdentity {
+    fn get_identity(&self) -> Option<String>;
+}

Helper trait that allows to get Identity.

+

It could be used in middleware but identity policy must be set before any other middleware that needs identity +RequestIdentity is implemented both for ServiceRequest and HttpRequest.

+

Required methods

Loading content...

Implementors

impl<T> RequestIdentity for T where
    T: HttpMessage, 
[src]

Loading content...
+ \ No newline at end of file diff --git a/actix_protobuf/all.html b/actix_protobuf/all.html new file mode 100644 index 000000000..19d2634df --- /dev/null +++ b/actix_protobuf/all.html @@ -0,0 +1,7 @@ +List of all items in this crate + +

List of all items[] + +

Structs

Enums

Traits

+ \ No newline at end of file diff --git a/actix_protobuf/enum.ProtoBufPayloadError.html b/actix_protobuf/enum.ProtoBufPayloadError.html new file mode 100644 index 000000000..100f5138c --- /dev/null +++ b/actix_protobuf/enum.ProtoBufPayloadError.html @@ -0,0 +1,39 @@ +actix_protobuf::ProtoBufPayloadError - Rust + +

Enum actix_protobuf::ProtoBufPayloadError[][src]

pub enum ProtoBufPayloadError {
+    Overflow,
+    ContentType,
+    Serialize(ProtoBufEncodeError),
+    Deserialize(ProtoBufDecodeError),
+    Payload(PayloadError),
+}

+ Variants

+
Overflow

Payload size is bigger than 256k

+
ContentType

Content type error

+

Serialize error

+
Deserialize(ProtoBufDecodeError)

Deserialize error

+
Payload(PayloadError)

Payload error

+

Trait Implementations

impl Debug for ProtoBufPayloadError[src]

impl Display for ProtoBufPayloadError[src]

impl From<DecodeError> for ProtoBufPayloadError[src]

impl From<PayloadError> for ProtoBufPayloadError[src]

impl ResponseError for ProtoBufPayloadError[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_protobuf/index.html b/actix_protobuf/index.html new file mode 100644 index 000000000..d24731527 --- /dev/null +++ b/actix_protobuf/index.html @@ -0,0 +1,8 @@ +actix_protobuf - Rust + +

Crate actix_protobuf[][src]

Structs

+
ProtoBuf
ProtoBufConfig
ProtoBufMessage

Enums

+
ProtoBufPayloadError

Traits

+
ProtoBufResponseBuilder
+ \ No newline at end of file diff --git a/actix_protobuf/sidebar-items.js b/actix_protobuf/sidebar-items.js new file mode 100644 index 000000000..fdd21e743 --- /dev/null +++ b/actix_protobuf/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["ProtoBufPayloadError",""]],"struct":[["ProtoBuf",""],["ProtoBufConfig",""],["ProtoBufMessage",""]],"trait":[["ProtoBufResponseBuilder",""]]}); \ No newline at end of file diff --git a/actix_protobuf/struct.ProtoBuf.html b/actix_protobuf/struct.ProtoBuf.html new file mode 100644 index 000000000..b792913c2 --- /dev/null +++ b/actix_protobuf/struct.ProtoBuf.html @@ -0,0 +1,34 @@ +actix_protobuf::ProtoBuf - Rust + +

Struct actix_protobuf::ProtoBuf[][src]

pub struct ProtoBuf<T: Message>(pub T);

Trait Implementations

impl<T: Message> Debug for ProtoBuf<T> where
    T: Debug
[src]

impl<T: Message> Deref for ProtoBuf<T>[src]

type Target = T

The resulting type after dereferencing.

+

impl<T: Message> DerefMut for ProtoBuf<T>[src]

impl<T: Message> Display for ProtoBuf<T> where
    T: Display
[src]

impl<T> FromRequest for ProtoBuf<T> where
    T: Message + Default + 'static, 
[src]

type Config = ProtoBufConfig

Configuration for this extractor.

+

type Error = Error

The associated error which can be returned.

+

type Future = LocalBoxFuture<'static, Result<Self, Error>>

Future that resolves to a Self.

+

impl<T: Message + Default> Responder for ProtoBuf<T>[src]

Auto Trait Implementations

impl<T> RefUnwindSafe for ProtoBuf<T> where
    T: RefUnwindSafe

impl<T> Send for ProtoBuf<T>

impl<T> Sync for ProtoBuf<T>

impl<T> Unpin for ProtoBuf<T> where
    T: Unpin

impl<T> UnwindSafe for ProtoBuf<T> where
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_protobuf/struct.ProtoBufConfig.html b/actix_protobuf/struct.ProtoBufConfig.html new file mode 100644 index 000000000..3195537b4 --- /dev/null +++ b/actix_protobuf/struct.ProtoBufConfig.html @@ -0,0 +1,21 @@ +actix_protobuf::ProtoBufConfig - Rust + +

Struct actix_protobuf::ProtoBufConfig[][src]

pub struct ProtoBufConfig { /* fields omitted */ }

Implementations

impl ProtoBufConfig[src]

pub fn limit(&mut self, limit: usize) -> &mut Self[src]

Change max size of payload. By default max size is 256Kb

+

Trait Implementations

impl Default for ProtoBufConfig[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_protobuf/struct.ProtoBufMessage.html b/actix_protobuf/struct.ProtoBufMessage.html new file mode 100644 index 000000000..bfafcf000 --- /dev/null +++ b/actix_protobuf/struct.ProtoBufMessage.html @@ -0,0 +1,87 @@ +actix_protobuf::ProtoBufMessage - Rust + +

Struct actix_protobuf::ProtoBufMessage[][src]

pub struct ProtoBufMessage<T: Message + Default> { /* fields omitted */ }

Implementations

impl<T: Message + Default> ProtoBufMessage<T>[src]

pub fn new(req: &HttpRequest, payload: &mut Payload) -> Self[src]

Create ProtoBufMessage for request.

+

pub fn limit(self, limit: usize) -> Self[src]

Change max size of payload. By default max size is 256Kb

+

Trait Implementations

impl<T: Message + Default + 'static> Future for ProtoBufMessage<T>[src]

type Output = Result<T, ProtoBufPayloadError>

The type of value produced on completion.

+

Auto Trait Implementations

impl<T> !RefUnwindSafe for ProtoBufMessage<T>

impl<T> !Send for ProtoBufMessage<T>

impl<T> !Sync for ProtoBufMessage<T>

impl<T> Unpin for ProtoBufMessage<T>

impl<T> !UnwindSafe for ProtoBufMessage<T>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> FutureExt for T where
    T: Future + ?Sized

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<F> IntoFuture for F where
    F: Future
[src]

type Output = <F as Future>::Output

🔬 This is a nightly-only experimental API. (into_future)

The output that the future will produce on completion.

+

type Future = F

🔬 This is a nightly-only experimental API. (into_future)

Which kind of future are we turning this into?

+

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<F, T, E> TryFuture for F where
    F: Future<Output = Result<T, E>> + ?Sized

type Ok = T

The type of successful values yielded by this future

+

type Error = E

The type of failures yielded by this future

+

impl<Fut> TryFutureExt for Fut where
    Fut: TryFuture + ?Sized

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_protobuf/trait.ProtoBufResponseBuilder.html b/actix_protobuf/trait.ProtoBufResponseBuilder.html new file mode 100644 index 000000000..97b66fdd6 --- /dev/null +++ b/actix_protobuf/trait.ProtoBufResponseBuilder.html @@ -0,0 +1,7 @@ +actix_protobuf::ProtoBufResponseBuilder - Rust + +

Trait actix_protobuf::ProtoBufResponseBuilder[][src]

pub trait ProtoBufResponseBuilder {
+    fn protobuf<T: Message>(&mut self, value: T) -> Result<HttpResponse, Error>;
+}

Required methods

fn protobuf<T: Message>(&mut self, value: T) -> Result<HttpResponse, Error>[src]

Loading content...

Implementations on Foreign Types

impl ProtoBufResponseBuilder for HttpResponseBuilder[src]

Loading content...

Implementors

Loading content...
+ \ No newline at end of file diff --git a/actix_redis/all.html b/actix_redis/all.html index a3ceab97e..b3d6777eb 100644 --- a/actix_redis/all.html +++ b/actix_redis/all.html @@ -1,6 +1,7 @@ -List of all items in this crate +List of all items in this crate -

[] +

List of all items[] - List of all items

Structs

Enums

\ No newline at end of file +

Structs

Enums

+ \ No newline at end of file diff --git a/actix_redis/enum.Error.html b/actix_redis/enum.Error.html index 05175f210..4619ecea2 100644 --- a/actix_redis/enum.Error.html +++ b/actix_redis/enum.Error.html @@ -1,7 +1,7 @@ -actix_redis::Error - Rust +actix_redis::Error - Rust -

[][src]Enum actix_redis::Error

pub enum Error {
+

Enum actix_redis::Error[][src]

pub enum Error {
     Redis(Error),
     NotConnected,
     Disconnected,
@@ -13,25 +13,26 @@
 

Trait Implementations

impl Debug for Error[src]

impl Display for Error[src]

impl Error for Error[src]

impl From<Error> for Error[src]

impl ResponseError for Error[src]

impl ResponseError for Error[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

Auto Trait Implementations

impl !RefUnwindSafe for Error

impl Send for Error

impl Sync for Error

impl Unpin for Error

impl !UnwindSafe for Error

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

-

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

-

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

-

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

\ No newline at end of file +

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_redis/enum.RespError.html b/actix_redis/enum.RespError.html index 6495fe1ee..d436bcb62 100644 --- a/actix_redis/enum.RespError.html +++ b/actix_redis/enum.RespError.html @@ -1,7 +1,7 @@ -actix_redis::RespError - Rust +actix_redis::RespError - Rust -

[]Enum actix_redis::RespError

pub enum RespError {
+

Enum actix_redis::RespError[]

pub enum RespError {
     Internal(String),
     IO(Error),
     RESP(StringOption<RespValue>),
@@ -15,8 +15,8 @@
 

A RESP parsing/serialising error occurred

Remote(String)

A remote error

Connection(ConnectionReason)

Error creating a connection, or an error with a connection being closed unexpectedly

-
Unexpected(String)

An unexpected error. In this context "unexpected" means -"unexpected because we check ahead of time", it used to maintain the type signature of +

Unexpected(String)

An unexpected error. In this context “unexpected” means +“unexpected because we check ahead of time”, it used to maintain the type signature of chains of futures; but it occurring at runtime should be considered a catastrophic failure.

If any error is propagated this way that needs to be handled, then it should be made into @@ -24,25 +24,26 @@ a proper option.

Trait Implementations

impl Debug for Error

impl Display for Error

impl Error for Error

impl From<Error> for Error

impl From<Error> for Error[src]

impl<T> From<TrySendError<T>> for Error where
    T: 'static + Send

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

Auto Trait Implementations

impl !RefUnwindSafe for Error

impl Send for Error

impl Sync for Error

impl Unpin for Error

impl !UnwindSafe for Error

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

-

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

-

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

-

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

\ No newline at end of file +

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_redis/enum.RespValue.html b/actix_redis/enum.RespValue.html index 31965e88c..b1f3e9167 100644 --- a/actix_redis/enum.RespValue.html +++ b/actix_redis/enum.RespValue.html @@ -1,7 +1,7 @@ -actix_redis::RespValue - Rust +actix_redis::RespValue - Rust -

[]Enum actix_redis::RespValue

Trait Implementations

impl Clone for RespValue

impl Debug for RespValue

impl Eq for RespValue

impl<'a> From<&'a [u8]> for RespValue

impl Eq for RespValue

impl<'a> From<&'a [u8]> for RespValue

impl<'a> From<&'a String> for RespValue

impl<'a> From<&'a str> for RespValue

impl<'a> From<Arc<str>> for RespValue

impl<'a> From<String> for RespValue

impl<'a> From<Vec<u8, Global>> for RespValue

impl<'a> From<Arc<str>> for RespValue

impl<'a> From<String> for RespValue

impl<'a> From<Vec<u8, Global>> for RespValue

impl<'a> From<usize> for RespValue

impl FromResp for RespValue

impl PartialEq<RespValue> for RespValue

impl StructuralEq for RespValue

impl StructuralPartialEq for RespValue

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl StructuralEq for RespValue

impl StructuralPartialEq for RespValue

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

-

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

-

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

-

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

-

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

\ No newline at end of file +

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_redis/enum.SameSite.html b/actix_redis/enum.SameSite.html index f8fd325d5..4ba10446f 100644 --- a/actix_redis/enum.SameSite.html +++ b/actix_redis/enum.SameSite.html @@ -1,19 +1,19 @@ -actix_redis::SameSite - Rust +actix_redis::SameSite - Rust -

[][src]Enum actix_redis::SameSite

pub enum SameSite {
+

Enum actix_redis::SameSite[][src]

pub enum SameSite {
     Strict,
     Lax,
     None,
 }

The SameSite cookie attribute.

A cookie with a SameSite attribute is imposed restrictions on when it is sent to the origin server in a cross-site request. If the SameSite -attribute is "Strict", then the cookie is never sent in cross-site requests. -If the SameSite attribute is "Lax", the cookie is only sent in cross-site -requests with "safe" HTTP methods, i.e, GET, HEAD, OPTIONS, TRACE. -If the SameSite attribute is "None", the cookie is sent in all cross-site -requests if the "Secure" flag is also set, otherwise the cookie is ignored. -This library automatically sets the "Secure" flag on cookies when +attribute is “Strict”, then the cookie is never sent in cross-site requests. +If the SameSite attribute is “Lax”, the cookie is only sent in cross-site +requests with “safe” HTTP methods, i.e, GET, HEAD, OPTIONS, TRACE. +If the SameSite attribute is “None”, the cookie is sent in all cross-site +requests if the “Secure” flag is also set, otherwise the cookie is ignored. +This library automatically sets the “Secure” flag on cookies when same_site is set to SameSite::None as long as secure is not explicitly set to false.

If the SameSite attribute is not present (by not setting SameSite @@ -23,10 +23,10 @@ will be sent as normal.

definition are subject to change.

Variants

-
Strict

The "Strict" SameSite attribute.

-
Lax

The "Lax" SameSite attribute.

-
None

The "None" SameSite attribute.

-

Implementations

impl SameSite[src]

pub fn is_strict(&self) -> bool[src]

Returns true if self is SameSite::Strict and false otherwise.

+
Strict

The “Strict” SameSite attribute.

+
Lax

The “Lax” SameSite attribute.

+
None

The “None” SameSite attribute.

+

Implementations

impl SameSite[src]

pub fn is_strict(&self) -> bool[src]

Returns true if self is SameSite::Strict and false otherwise.

Example

 use cookie::SameSite;
@@ -35,7 +35,7 @@ definition are subject to change.

assert!(strict.is_strict()); assert!(!strict.is_lax()); assert!(!strict.is_none());
-

pub fn is_lax(&self) -> bool[src]

Returns true if self is SameSite::Lax and false otherwise.

+

pub fn is_lax(&self) -> bool[src]

Returns true if self is SameSite::Lax and false otherwise.

Example

 use cookie::SameSite;
@@ -44,7 +44,7 @@ definition are subject to change.

assert!(lax.is_lax()); assert!(!lax.is_strict()); assert!(!lax.is_none());
-

pub fn is_none(&self) -> bool[src]

Returns true if self is SameSite::None and false otherwise.

+

pub fn is_none(&self) -> bool[src]

Returns true if self is SameSite::None and false otherwise.

Example

 use cookie::SameSite;
@@ -54,32 +54,33 @@ definition are subject to change.

assert!(!none.is_lax()); assert!(!none.is_strict());

Trait Implementations

impl Clone for SameSite[src]

impl Copy for SameSite[src]

impl Debug for SameSite[src]

impl Display for SameSite[src]

impl Display for SameSite[src]

impl Eq for SameSite[src]

impl Hash for SameSite[src]

impl PartialEq<SameSite> for SameSite[src]

impl StructuralEq for SameSite[src]

impl StructuralPartialEq for SameSite[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CallHasher for T where
    T: Hash + ?Sized

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl StructuralEq for SameSite[src]

impl StructuralPartialEq for SameSite[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CallHasher for T where
    T: Hash + ?Sized

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

-

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

-

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

-

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

-

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

\ No newline at end of file +

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_redis/index.html b/actix_redis/index.html index 1a4da6c21..79806608b 100644 --- a/actix_redis/index.html +++ b/actix_redis/index.html @@ -1,7 +1,7 @@ -actix_redis - Rust +actix_redis - Rust -

[][src]Crate actix_redis

Redis integration for Actix and session store for Actix Web.

+

Crate actix_redis[][src]

Redis integration for Actix and session store for Actix Web.

Structs

Command

Command for send data to Redis

RedisActor

Redis communication actor

@@ -10,4 +10,5 @@
Error

General purpose actix redis error

RespError
RespValue

A single RESP value, this owns the data that is read/to-be written to Redis.

SameSite

The SameSite cookie attribute.

-
\ No newline at end of file +
+ \ No newline at end of file diff --git a/actix_redis/struct.Command.html b/actix_redis/struct.Command.html index 503856760..d46f2d2ea 100644 --- a/actix_redis/struct.Command.html +++ b/actix_redis/struct.Command.html @@ -1,24 +1,25 @@ -actix_redis::Command - Rust +actix_redis::Command - Rust -

[][src]Struct actix_redis::Command

pub struct Command(pub RespValue);

Command for send data to Redis

+

Struct actix_redis::Command[][src]

pub struct Command(pub RespValue);

Command for send data to Redis

Trait Implementations

impl Debug for Command[src]

impl Handler<Command> for RedisActor[src]

type Result = ResponseFuture<Result<RespValue, Error>>

The type of value that this handler will return. Read more

impl Message for Command[src]

type Result = Result<RespValue, Error>

The type of value that this message will resolved with if it is successful. Read more

-

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

Auto Trait Implementations

impl RefUnwindSafe for Command

impl Send for Command

impl Sync for Command

impl Unpin for Command

impl UnwindSafe for Command

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

-

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

-

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

-

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

\ No newline at end of file +

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_redis/struct.RedisActor.html b/actix_redis/struct.RedisActor.html index 59dcfd001..7977f2863 100644 --- a/actix_redis/struct.RedisActor.html +++ b/actix_redis/struct.RedisActor.html @@ -1,7 +1,7 @@ -actix_redis::RedisActor - Rust +actix_redis::RedisActor - Rust -

[][src]Struct actix_redis::RedisActor

pub struct RedisActor { /* fields omitted */ }

Redis communication actor

+

Struct actix_redis::RedisActor[][src]

pub struct RedisActor { /* fields omitted */ }

Redis communication actor

Implementations

impl RedisActor[src]

pub fn start<S: Into<String>>(addr: S) -> Addr<RedisActor>[src]

Start new Supervisor with RedisActor.

Trait Implementations

impl Actor for RedisActor[src]

type Context = Context<Self>

Actor execution context type

impl Handler<Command> for RedisActor[src]

type Result = ResponseFuture<Result<RespValue, Error>>

The type of value that this handler will return. Read more

impl Supervised for RedisActor[src]

impl WriteHandler<Error> for RedisActor[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

-

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

-

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

-

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

\ No newline at end of file +

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_redis/struct.RedisSession.html b/actix_redis/struct.RedisSession.html index d941cfdda..162c3f52c 100644 --- a/actix_redis/struct.RedisSession.html +++ b/actix_redis/struct.RedisSession.html @@ -1,7 +1,7 @@ -actix_redis::RedisSession - Rust +actix_redis::RedisSession - Rust -

[][src]Struct actix_redis::RedisSession

pub struct RedisSession(_);

Use redis as session storage.

+

Struct actix_redis::RedisSession[][src]

pub struct RedisSession(_);

Use redis as session storage.

You need to pass an address of the redis server and random value to the constructor of RedisSession. This is private key for cookie session, When this value is changed, all session data is lost.

@@ -31,18 +31,19 @@ connection is secure - i.e. https.

type InitError = ()

Errors produced while building a transform service.

type Future = LocalBoxFuture<'static, Result<Self::Transform, Self::InitError>>

The future response value.

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

-

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

-

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

-

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

\ No newline at end of file +

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_session/all.html b/actix_session/all.html new file mode 100644 index 000000000..279522272 --- /dev/null +++ b/actix_session/all.html @@ -0,0 +1,7 @@ +List of all items in this crate + +

List of all items[] + +

Structs

Enums

Traits

+ \ No newline at end of file diff --git a/actix_session/cookie/struct.CookieSession.html b/actix_session/cookie/struct.CookieSession.html new file mode 100644 index 000000000..988b04316 --- /dev/null +++ b/actix_session/cookie/struct.CookieSession.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../actix_session/struct.CookieSession.html...

+ + + \ No newline at end of file diff --git a/actix_session/enum.SessionStatus.html b/actix_session/enum.SessionStatus.html new file mode 100644 index 000000000..9a03e784e --- /dev/null +++ b/actix_session/enum.SessionStatus.html @@ -0,0 +1,37 @@ +actix_session::SessionStatus - Rust + +

Enum actix_session::SessionStatus[][src]

pub enum SessionStatus {
+    Changed,
+    Purged,
+    Renewed,
+    Unchanged,
+}

+ Variants

+
Changed
Purged
Renewed
Unchanged

Trait Implementations

impl Clone for SessionStatus[src]

impl Debug for SessionStatus[src]

impl Default for SessionStatus[src]

impl PartialEq<SessionStatus> for SessionStatus[src]

impl StructuralPartialEq for SessionStatus[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_session/index.html b/actix_session/index.html new file mode 100644 index 000000000..54a637aa5 --- /dev/null +++ b/actix_session/index.html @@ -0,0 +1,47 @@ +actix_session - Rust + +

Crate actix_session[][src]

Sessions for Actix Web.

+

Provides a general solution for session management. Session middleware could provide different +implementations which could be accessed via general session API.

+

This crate provides a general solution for session management and includes a cookie backend. +Other backend implementations can be built to use persistent or key-value stores, for example.

+

In general, some session middleware, such as a CookieSession is initialized and applied. +To access session data, the Session extractor must be used. This extractor allows reading +modifying session data.

+ +
+use actix_web::{web, App, HttpServer, HttpResponse, Error};
+use actix_session::{Session, CookieSession};
+
+fn index(session: Session) -> Result<&'static str, Error> {
+    // access session data
+    if let Some(count) = session.get::<i32>("counter")? {
+        println!("SESSION value: {}", count);
+        session.set("counter", count + 1)?;
+    } else {
+        session.set("counter", 1)?;
+    }
+
+    Ok("Welcome!")
+}
+
+#[actix_rt::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(
+        || App::new()
+            // create cookie based session middleware
+            .wrap(CookieSession::signed(&[0; 32]).secure(false))
+            .default_service(web::to(|| HttpResponse::Ok())))
+        .bind(("127.0.0.1", 8080))?
+        .run()
+        .await
+}
+

Structs

+
CookieSession

Use cookies for session storage.

+
Session

The high-level interface you use to modify session data.

+

Enums

+
SessionStatus

Traits

+
UserSession

Extraction of a Session object.

+
+ \ No newline at end of file diff --git a/actix_session/sidebar-items.js b/actix_session/sidebar-items.js new file mode 100644 index 000000000..cf5fcad6e --- /dev/null +++ b/actix_session/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["SessionStatus",""]],"struct":[["CookieSession","Use cookies for session storage."],["Session","The high-level interface you use to modify session data."]],"trait":[["UserSession","Extraction of a [`Session`] object."]]}); \ No newline at end of file diff --git a/actix_session/struct.CookieSession.html b/actix_session/struct.CookieSession.html new file mode 100644 index 000000000..9052e3f22 --- /dev/null +++ b/actix_session/struct.CookieSession.html @@ -0,0 +1,75 @@ +actix_session::CookieSession - Rust + +

Struct actix_session::CookieSession[][src]

pub struct CookieSession(_);

Use cookies for session storage.

+

CookieSession creates sessions which are limited to storing +fewer than 4000 bytes of data (as the payload must fit into a single +cookie). An Internal Server Error is generated if the session contains more +than 4000 bytes.

+

A cookie may have a security policy of signed or private. Each has a +respective CookieSession constructor.

+

A signed cookie is stored on the client as plaintext alongside +a signature such that the cookie may be viewed but not modified by the +client.

+

A private cookie is stored on the client as encrypted text +such that it may neither be viewed nor modified by the client.

+

The constructors take a key as an argument. +This is the private key for cookie session - when this value is changed, +all session data is lost. The constructors will panic if the key is less +than 32 bytes in length.

+

The backend relies on cookie crate to create and read cookies. +By default all cookies are percent encoded, but certain symbols may +cause troubles when reading cookie, if they are not properly percent encoded.

+

Examples

+
+use actix_session::CookieSession;
+use actix_web::{web, App, HttpResponse, HttpServer};
+
+let app = App::new().wrap(
+    CookieSession::signed(&[0; 32])
+        .domain("www.rust-lang.org")
+        .name("actix_session")
+        .path("/")
+        .secure(true))
+    .service(web::resource("/").to(|| HttpResponse::Ok()));
+

Implementations

impl CookieSession[src]

pub fn signed(key: &[u8]) -> CookieSession[src]

Construct new signed CookieSession instance.

+

Panics if key length is less than 32 bytes.

+

pub fn private(key: &[u8]) -> CookieSession[src]

Construct new private CookieSession instance.

+

Panics if key length is less than 32 bytes.

+

pub fn path<S: Into<String>>(self, value: S) -> CookieSession[src]

Sets the path field in the session cookie being built.

+

pub fn name<S: Into<String>>(self, value: S) -> CookieSession[src]

Sets the name field in the session cookie being built.

+

pub fn domain<S: Into<String>>(self, value: S) -> CookieSession[src]

Sets the domain field in the session cookie being built.

+

pub fn lazy(self, value: bool) -> CookieSession[src]

When true, prevents adding session cookies to responses until +the session contains data. Default is false.

+

Useful when trying to comply with laws that require consent for setting cookies.

+

pub fn secure(self, value: bool) -> CookieSession[src]

Sets the secure field in the session cookie being built.

+

If the secure field is set, a cookie will only be transmitted when the +connection is secure - i.e. https

+

pub fn http_only(self, value: bool) -> CookieSession[src]

Sets the http_only field in the session cookie being built.

+

pub fn same_site(self, value: SameSite) -> CookieSession[src]

Sets the same_site field in the session cookie being built.

+

pub fn max_age(self, seconds: i64) -> CookieSession[src]

Sets the max-age field in the session cookie being built.

+

pub fn max_age_time(self, value: Duration) -> CookieSession[src]

Sets the max-age field in the session cookie being built.

+

pub fn expires_in(self, seconds: i64) -> CookieSession[src]

Sets the expires field in the session cookie being built.

+

pub fn expires_in_time(self, value: Duration) -> CookieSession[src]

Sets the expires field in the session cookie being built.

+

Trait Implementations

impl<S, B: 'static> Transform<S, ServiceRequest> for CookieSession where
    S: Service<ServiceRequest, Response = ServiceResponse<B>>,
    S::Future: 'static,
    S::Error: 'static, 
[src]

type Response = ServiceResponse<B>

Responses produced by the service.

+

type Error = S::Error

Errors produced by the service.

+

type InitError = ()

Errors produced while building a transform service.

+

type Transform = CookieSessionMiddleware<S>

The TransformService value created by this factory

+

type Future = Ready<Result<Self::Transform, Self::InitError>>

The future response value.

+

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_session/struct.Session.html b/actix_session/struct.Session.html new file mode 100644 index 000000000..9154b9718 --- /dev/null +++ b/actix_session/struct.Session.html @@ -0,0 +1,75 @@ +actix_session::Session - Rust + +

Struct actix_session::Session[][src]

pub struct Session(_);

The high-level interface you use to modify session data.

+

Session object is obtained with UserSession::get_session. The UserSession trait is +implemented for HttpRequest, ServiceRequest, and RequestHead.

+ +
+use actix_session::Session;
+use actix_web::Result;
+
+async fn index(session: Session) -> Result<&'static str> {
+    // access session data
+    if let Some(count) = session.get::<i32>("counter")? {
+        session.set("counter", count + 1)?;
+    } else {
+        session.set("counter", 1)?;
+    }
+
+    Ok("Welcome!")
+}
+

Implementations

impl Session[src]

pub fn get<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>, Error>[src]

Get a value from the session.

+

pub fn set<T: Serialize>(&self, key: &str, value: T) -> Result<(), Error>[src]

Set a value from the session.

+

pub fn remove(&self, key: &str)[src]

Remove value from the session.

+

pub fn clear(&self)[src]

Clear the session.

+

pub fn purge(&self)[src]

Removes session, both client and server side.

+

pub fn renew(&self)[src]

Renews the session key, assigning existing session state to new key.

+

pub fn set_session(
    data: impl IntoIterator<Item = (String, String)>,
    req: &mut ServiceRequest
)
[src]

Adds the given key-value pairs to the session on the request.

+

Values that match keys already existing on the session will be overwritten. Values should +already be JSON serialized.

+

Examples

+
+let mut req = test::TestRequest::default().to_srv_request();
+
+Session::set_session(
+    vec![("counter".to_string(), serde_json::to_string(&0).unwrap())],
+    &mut req,
+);
+

pub fn get_changes<B>(
    res: &mut ServiceResponse<B>
) -> (SessionStatus, Option<impl Iterator<Item = (String, String)>>)
[src]

Trait Implementations

impl FromRequest for Session[src]

Extractor implementation for Session type.

+ +
+use actix_session::Session;
+
+fn index(session: Session) -> Result<&'static str> {
+    // access session data
+    if let Some(count) = session.get::<i32>("counter")? {
+        session.set("counter", count + 1)?;
+    } else {
+        session.set("counter", 1)?;
+    }
+
+    Ok("Welcome!")
+}
+

type Error = Error

The associated error which can be returned.

+

type Future = Ready<Result<Session, Error>>

Future that resolves to a Self.

+

type Config = ()

Configuration for this extractor.

+

Auto Trait Implementations

impl !RefUnwindSafe for Session

impl !Send for Session

impl !Sync for Session

impl Unpin for Session

impl !UnwindSafe for Session

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_session/trait.UserSession.html b/actix_session/trait.UserSession.html new file mode 100644 index 000000000..1083ce406 --- /dev/null +++ b/actix_session/trait.UserSession.html @@ -0,0 +1,8 @@ +actix_session::UserSession - Rust + +

Trait actix_session::UserSession[][src]

pub trait UserSession {
+    fn get_session(&self) -> Session;
+}

Extraction of a Session object.

+

Required methods

Loading content...

Implementations on Foreign Types

impl UserSession for HttpRequest[src]

impl UserSession for ServiceRequest[src]

impl UserSession for RequestHead[src]

Loading content...

Implementors

Loading content...
+ \ No newline at end of file diff --git a/actix_web_httpauth/all.html b/actix_web_httpauth/all.html new file mode 100644 index 000000000..1bbd40bc9 --- /dev/null +++ b/actix_web_httpauth/all.html @@ -0,0 +1,7 @@ +List of all items in this crate + +

List of all items[] + +

Structs

Enums

Traits

+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/basic/index.html b/actix_web_httpauth/extractors/basic/index.html new file mode 100644 index 000000000..b92c7056f --- /dev/null +++ b/actix_web_httpauth/extractors/basic/index.html @@ -0,0 +1,10 @@ +actix_web_httpauth::extractors::basic - Rust + +

Module actix_web_httpauth::extractors::basic[][src]

Extractor for the “Basic” HTTP Authentication Scheme

+

Structs

+
BasicAuth

Extractor for HTTP Basic auth.

+
Config

BasicAuth extractor configuration, +used for WWW-Authenticate header later.

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/basic/sidebar-items.js b/actix_web_httpauth/extractors/basic/sidebar-items.js new file mode 100644 index 000000000..ea22dda4c --- /dev/null +++ b/actix_web_httpauth/extractors/basic/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["BasicAuth","Extractor for HTTP Basic auth."],["Config","`BasicAuth` extractor configuration, used for `WWW-Authenticate` header later."]]}); \ No newline at end of file diff --git a/actix_web_httpauth/extractors/basic/struct.BasicAuth.html b/actix_web_httpauth/extractors/basic/struct.BasicAuth.html new file mode 100644 index 000000000..36788216d --- /dev/null +++ b/actix_web_httpauth/extractors/basic/struct.BasicAuth.html @@ -0,0 +1,63 @@ +actix_web_httpauth::extractors::basic::BasicAuth - Rust + +

Struct actix_web_httpauth::extractors::basic::BasicAuth[][src]

pub struct BasicAuth(_);

Extractor for HTTP Basic auth.

+

Example

+
+use actix_web::Result;
+use actix_web_httpauth::extractors::basic::BasicAuth;
+
+async fn index(auth: BasicAuth) -> String {
+    format!("Hello, {}!", auth.user_id())
+}
+

If authentication fails, this extractor fetches the Config instance +from the app data in order to properly form the WWW-Authenticate +response header.

+

Example

+
+use actix_web::{web, App};
+use actix_web_httpauth::extractors::basic::{BasicAuth, Config};
+
+async fn index(auth: BasicAuth) -> String {
+    format!("Hello, {}!", auth.user_id())
+}
+
+fn main() {
+    let app = App::new()
+        .data(Config::default().realm("Restricted area"))
+        .service(web::resource("/index.html").route(web::get().to(index)));
+}
+

Implementations

impl BasicAuth[src]

pub fn user_id(&self) -> &Cow<'static, str>[src]

Returns client’s user-ID.

+

pub fn password(&self) -> Option<&Cow<'static, str>>[src]

Returns client’s password.

+

Trait Implementations

impl AuthExtractor for BasicAuth[src]

type Error = AuthenticationError<Challenge>

The associated error which can be returned.

+

type Future = Ready<Result<Self, Self::Error>>

Future that resolves into extracted credentials type.

+

impl Clone for BasicAuth[src]

impl Debug for BasicAuth[src]

impl FromRequest for BasicAuth[src]

type Future = Ready<Result<Self, Self::Error>>

Future that resolves to a Self.

+

type Config = Config

Configuration for this extractor.

+

type Error = AuthenticationError<Challenge>

The associated error which can be returned.

+

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/basic/struct.Config.html b/actix_web_httpauth/extractors/basic/struct.Config.html new file mode 100644 index 000000000..188701bf4 --- /dev/null +++ b/actix_web_httpauth/extractors/basic/struct.Config.html @@ -0,0 +1,35 @@ +actix_web_httpauth::extractors::basic::Config - Rust + +

Struct actix_web_httpauth::extractors::basic::Config[][src]

pub struct Config(_);

BasicAuth extractor configuration, +used for WWW-Authenticate header later.

+

Implementations

impl Config[src]

pub fn realm<T>(self, value: T) -> Config where
    T: Into<Cow<'static, str>>, 
[src]

Set challenge realm attribute.

+

The “realm” attribute indicates the scope of protection in the manner +described in HTTP/1.1 RFC2617.

+

Trait Implementations

impl AsRef<Basic> for Config[src]

impl AuthExtractorConfig for Config[src]

type Inner = Challenge

Associated challenge type.

+

impl Clone for Config[src]

impl Debug for Config[src]

impl Default for Config[src]

Auto Trait Implementations

impl RefUnwindSafe for Config

impl Send for Config

impl Sync for Config

impl Unpin for Config

impl UnwindSafe for Config

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/bearer/enum.Error.html b/actix_web_httpauth/extractors/bearer/enum.Error.html new file mode 100644 index 000000000..06282b0b9 --- /dev/null +++ b/actix_web_httpauth/extractors/bearer/enum.Error.html @@ -0,0 +1,61 @@ +actix_web_httpauth::extractors::bearer::Error - Rust + +

Enum actix_web_httpauth::extractors::bearer::Error[][src]

pub enum Error {
+    InvalidRequest,
+    InvalidToken,
+    InsufficientScope,
+}

Bearer authorization error types, described in RFC 6750

+

+ Variants

+
InvalidRequest

The request is missing a required parameter, includes an unsupported +parameter or parameter value, repeats the same parameter, uses more +than one method for including an access token, or is otherwise +malformed.

+
InvalidToken

The access token provided is expired, revoked, malformed, or invalid +for other reasons.

+
InsufficientScope

The request requires higher privileges than provided by the access +token.

+

Implementations

impl Error[src]

pub fn status_code(&self) -> StatusCode[src]

Returns HTTP status code suitable for current error type.

+

Trait Implementations

impl Clone for Error[src]

impl Copy for Error[src]

impl Debug for Error[src]

impl Display for Error[src]

impl Eq for Error[src]

impl Hash for Error[src]

impl Ord for Error[src]

impl PartialEq<Error> for Error[src]

impl PartialOrd<Error> for Error[src]

impl StructuralEq for Error[src]

impl StructuralPartialEq for Error[src]

Auto Trait Implementations

impl RefUnwindSafe for Error

impl Send for Error

impl Sync for Error

impl Unpin for Error

impl UnwindSafe for Error

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CallHasher for T where
    T: Hash + ?Sized

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/bearer/index.html b/actix_web_httpauth/extractors/bearer/index.html new file mode 100644 index 000000000..f9da017fb --- /dev/null +++ b/actix_web_httpauth/extractors/bearer/index.html @@ -0,0 +1,11 @@ +actix_web_httpauth::extractors::bearer - Rust + +

Module actix_web_httpauth::extractors::bearer[][src]

Extractor for the “Bearer” HTTP Authentication Scheme

+

Structs

+
BearerAuth

Extractor for HTTP Bearer auth

+
Config

BearerAuth extractor configuration.

+

Enums

+
Error

Bearer authorization error types, described in RFC 6750

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/bearer/sidebar-items.js b/actix_web_httpauth/extractors/bearer/sidebar-items.js new file mode 100644 index 000000000..8c3294a69 --- /dev/null +++ b/actix_web_httpauth/extractors/bearer/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["Error","Bearer authorization error types, described in RFC 6750"]],"struct":[["BearerAuth","Extractor for HTTP Bearer auth"],["Config","BearerAuth extractor configuration."]]}); \ No newline at end of file diff --git a/actix_web_httpauth/extractors/bearer/struct.BearerAuth.html b/actix_web_httpauth/extractors/bearer/struct.BearerAuth.html new file mode 100644 index 000000000..9ef9cc93e --- /dev/null +++ b/actix_web_httpauth/extractors/bearer/struct.BearerAuth.html @@ -0,0 +1,65 @@ +actix_web_httpauth::extractors::bearer::BearerAuth - Rust + +

Struct actix_web_httpauth::extractors::bearer::BearerAuth[][src]

pub struct BearerAuth(_);

Extractor for HTTP Bearer auth

+

Example

+
+use actix_web_httpauth::extractors::bearer::BearerAuth;
+
+async fn index(auth: BearerAuth) -> String {
+    format!("Hello, user with token {}!", auth.token())
+}
+

If authentication fails, this extractor fetches the Config instance +from the [app data] in order to properly form the WWW-Authenticate +response header.

+

Example

+
+use actix_web::{web, App};
+use actix_web_httpauth::extractors::bearer::{BearerAuth, Config};
+
+async fn index(auth: BearerAuth) -> String {
+    format!("Hello, {}!", auth.token())
+}
+
+fn main() {
+    let app = App::new()
+        .data(
+            Config::default()
+                .realm("Restricted area")
+                .scope("email photo"),
+        )
+        .service(web::resource("/index.html").route(web::get().to(index)));
+}
+

Implementations

impl BearerAuth[src]

pub fn token(&self) -> &str[src]

Returns bearer token provided by client.

+

Trait Implementations

impl AuthExtractor for BearerAuth[src]

type Future = Ready<Result<Self, Self::Error>>

Future that resolves into extracted credentials type.

+

type Error = AuthenticationError<Bearer>

The associated error which can be returned.

+

impl Clone for BearerAuth[src]

impl Debug for BearerAuth[src]

impl FromRequest for BearerAuth[src]

type Config = Config

Configuration for this extractor.

+

type Future = Ready<Result<Self, Self::Error>>

Future that resolves to a Self.

+

type Error = AuthenticationError<Bearer>

The associated error which can be returned.

+

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/bearer/struct.Config.html b/actix_web_httpauth/extractors/bearer/struct.Config.html new file mode 100644 index 000000000..c14f969fd --- /dev/null +++ b/actix_web_httpauth/extractors/bearer/struct.Config.html @@ -0,0 +1,38 @@ +actix_web_httpauth::extractors::bearer::Config - Rust + +

Struct actix_web_httpauth::extractors::bearer::Config[][src]

pub struct Config(_);

BearerAuth extractor configuration.

+

Implementations

impl Config[src]

pub fn scope<T: Into<Cow<'static, str>>>(self, value: T) -> Config[src]

Set challenge scope attribute.

+

The "scope" attribute is a space-delimited list of case-sensitive +scope values indicating the required scope of the access token for +accessing the requested resource.

+

pub fn realm<T: Into<Cow<'static, str>>>(self, value: T) -> Config[src]

Set challenge realm attribute.

+

The “realm” attribute indicates the scope of protection in the manner +described in HTTP/1.1 RFC2617.

+

Trait Implementations

impl AsRef<Bearer> for Config[src]

impl AuthExtractorConfig for Config[src]

type Inner = Bearer

Associated challenge type.

+

impl Clone for Config[src]

impl Debug for Config[src]

impl Default for Config[src]

Auto Trait Implementations

impl RefUnwindSafe for Config

impl Send for Config

impl Sync for Config

impl Unpin for Config

impl UnwindSafe for Config

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/config/trait.AuthExtractorConfig.html b/actix_web_httpauth/extractors/config/trait.AuthExtractorConfig.html new file mode 100644 index 000000000..8466abc1a --- /dev/null +++ b/actix_web_httpauth/extractors/config/trait.AuthExtractorConfig.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../actix_web_httpauth/extractors/trait.AuthExtractorConfig.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/extractors/errors/struct.AuthenticationError.html b/actix_web_httpauth/extractors/errors/struct.AuthenticationError.html new file mode 100644 index 000000000..ab93b3583 --- /dev/null +++ b/actix_web_httpauth/extractors/errors/struct.AuthenticationError.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../actix_web_httpauth/extractors/struct.AuthenticationError.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/extractors/index.html b/actix_web_httpauth/extractors/index.html new file mode 100644 index 000000000..29a39b0b9 --- /dev/null +++ b/actix_web_httpauth/extractors/index.html @@ -0,0 +1,16 @@ +actix_web_httpauth::extractors - Rust + +

Module actix_web_httpauth::extractors[][src]

Type-safe authentication information extractors

+

Modules

+
basic

Extractor for the “Basic” HTTP Authentication Scheme

+
bearer

Extractor for the “Bearer” HTTP Authentication Scheme

+

Structs

+
AuthenticationError

Authentication error returned by authentication extractors.

+

Traits

+
AuthExtractor

Trait implemented by types that can extract +HTTP authentication scheme credentials from the request.

+
AuthExtractorConfig

Trait implemented for types that provides configuration +for the authentication extractors.

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/sidebar-items.js b/actix_web_httpauth/extractors/sidebar-items.js new file mode 100644 index 000000000..dd156d297 --- /dev/null +++ b/actix_web_httpauth/extractors/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["basic","Extractor for the “Basic” HTTP Authentication Scheme"],["bearer","Extractor for the “Bearer” HTTP Authentication Scheme"]],"struct":[["AuthenticationError","Authentication error returned by authentication extractors."]],"trait":[["AuthExtractor","Trait implemented by types that can extract HTTP authentication scheme credentials from the request."],["AuthExtractorConfig","Trait implemented for types that provides configuration for the authentication extractors."]]}); \ No newline at end of file diff --git a/actix_web_httpauth/extractors/struct.AuthenticationError.html b/actix_web_httpauth/extractors/struct.AuthenticationError.html new file mode 100644 index 000000000..56864793a --- /dev/null +++ b/actix_web_httpauth/extractors/struct.AuthenticationError.html @@ -0,0 +1,45 @@ +actix_web_httpauth::extractors::AuthenticationError - Rust + +

Struct actix_web_httpauth::extractors::AuthenticationError[][src]

pub struct AuthenticationError<C: Challenge> { /* fields omitted */ }

Authentication error returned by authentication extractors.

+

Different extractors may extend AuthenticationError implementation +in order to provide access to inner challenge fields.

+

Implementations

impl AuthenticationError<Bearer>[src]

Extended error customization for HTTP Bearer auth.

+

pub fn with_error(self, kind: Error) -> Self[src]

Attach Error to the current Authentication error.

+

Error status code will be changed to the one provided by the kind +Error.

+

pub fn with_error_description<T>(self, desc: T) -> Self where
    T: Into<Cow<'static, str>>, 
[src]

Attach error description to the current Authentication error.

+

pub fn with_error_uri<T>(self, uri: T) -> Self where
    T: Into<Cow<'static, str>>, 
[src]

Attach error URI to the current Authentication error.

+

It is up to implementor to provide properly formed absolute URI.

+

impl<C: Challenge> AuthenticationError<C>[src]

pub fn new(challenge: C) -> AuthenticationError<C>[src]

Creates new authentication error from the provided challenge.

+

By default returned error will resolve into the HTTP 401 status code.

+

pub fn challenge_mut(&mut self) -> &mut C[src]

Returns mutable reference to the inner challenge instance.

+

pub fn status_code_mut(&mut self) -> &mut StatusCode[src]

Returns mutable reference to the inner status code.

+

Can be used to override returned status code, but by default +this lib tries to stick to the RFC, so it might be unreasonable.

+

Trait Implementations

impl<C: Debug + Challenge> Debug for AuthenticationError<C>[src]

impl<C: Challenge> Display for AuthenticationError<C>[src]

impl<C: 'static + Challenge> Error for AuthenticationError<C>[src]

impl<T> From<T> for AuthenticationError<<T as AuthExtractorConfig>::Inner> where
    T: AuthExtractorConfig
[src]

impl<C: 'static + Challenge> ResponseError for AuthenticationError<C>[src]

Auto Trait Implementations

impl<C> RefUnwindSafe for AuthenticationError<C> where
    C: RefUnwindSafe

impl<C> Send for AuthenticationError<C>

impl<C> Sync for AuthenticationError<C>

impl<C> Unpin for AuthenticationError<C> where
    C: Unpin

impl<C> UnwindSafe for AuthenticationError<C> where
    C: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/trait.AuthExtractor.html b/actix_web_httpauth/extractors/trait.AuthExtractor.html new file mode 100644 index 000000000..fcb4a5987 --- /dev/null +++ b/actix_web_httpauth/extractors/trait.AuthExtractor.html @@ -0,0 +1,19 @@ +actix_web_httpauth::extractors::AuthExtractor - Rust + +

Trait actix_web_httpauth::extractors::AuthExtractor[][src]

pub trait AuthExtractor: Sized {
+    type Error: Into<Error>;
+    type Future: Future<Output = Result<Self, Self::Error>>;
+    fn from_service_request(req: &ServiceRequest) -> Self::Future;
+}

Trait implemented by types that can extract +HTTP authentication scheme credentials from the request.

+

It is very similar to actix’ FromRequest trait, +except it operates with a ServiceRequest struct instead, +therefore it can be used in the middlewares.

+

You will not need it unless you want to implement your own +authentication scheme.

+

Associated Types

type Error: Into<Error>[src]

The associated error which can be returned.

+

type Future: Future<Output = Result<Self, Self::Error>>[src]

Future that resolves into extracted credentials type.

+
Loading content...

Required methods

fn from_service_request(req: &ServiceRequest) -> Self::Future[src]

Parse the authentication credentials from the actix’ ServiceRequest.

+
Loading content...

Implementors

impl AuthExtractor for BasicAuth[src]

type Error = AuthenticationError<Challenge>

type Future = Ready<Result<Self, Self::Error>>

impl AuthExtractor for BearerAuth[src]

type Future = Ready<Result<Self, Self::Error>>

type Error = AuthenticationError<Bearer>

Loading content...
+ \ No newline at end of file diff --git a/actix_web_httpauth/extractors/trait.AuthExtractorConfig.html b/actix_web_httpauth/extractors/trait.AuthExtractorConfig.html new file mode 100644 index 000000000..71802aacc --- /dev/null +++ b/actix_web_httpauth/extractors/trait.AuthExtractorConfig.html @@ -0,0 +1,12 @@ +actix_web_httpauth::extractors::AuthExtractorConfig - Rust + +

Trait actix_web_httpauth::extractors::AuthExtractorConfig[][src]

pub trait AuthExtractorConfig {
+    type Inner: Challenge;
+    fn into_inner(self) -> Self::Inner;
+}

Trait implemented for types that provides configuration +for the authentication extractors.

+

Associated Types

type Inner: Challenge[src]

Associated challenge type.

+
Loading content...

Required methods

fn into_inner(self) -> Self::Inner[src]

Convert the config instance into a HTTP challenge.

+
Loading content...

Implementors

impl AuthExtractorConfig for actix_web_httpauth::extractors::basic::Config[src]

type Inner = Challenge

impl AuthExtractorConfig for actix_web_httpauth::extractors::bearer::Config[src]

type Inner = Bearer

Loading content...
+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/enum.ParseError.html b/actix_web_httpauth/headers/authorization/enum.ParseError.html new file mode 100644 index 000000000..97e1b72c0 --- /dev/null +++ b/actix_web_httpauth/headers/authorization/enum.ParseError.html @@ -0,0 +1,47 @@ +actix_web_httpauth::headers::authorization::ParseError - Rust + +

Enum actix_web_httpauth::headers::authorization::ParseError[][src]

pub enum ParseError {
+    Invalid,
+    MissingScheme,
+    MissingField(&'static str),
+    ToStrError(ToStrError),
+    Base64DecodeError(DecodeError),
+    Utf8Error(Utf8Error),
+}

Possible errors while parsing Authorization header.

+

Should not be used directly unless you are implementing +your own authentication scheme.

+

+ Variants

+
Invalid

Header value is malformed

+
MissingScheme

Authentication scheme is missing

+
MissingField(&'static str)

Required authentication field is missing

+
ToStrError(ToStrError)

Unable to convert header into the str

+
Base64DecodeError(DecodeError)

Malformed base64 string

+
Utf8Error(Utf8Error)

Malformed UTF-8 string

+

Trait Implementations

impl Debug for ParseError[src]

impl Display for ParseError[src]

impl Error for ParseError[src]

impl From<DecodeError> for ParseError[src]

impl From<ToStrError> for ParseError[src]

impl From<Utf8Error> for ParseError[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/errors/enum.ParseError.html b/actix_web_httpauth/headers/authorization/errors/enum.ParseError.html new file mode 100644 index 000000000..df5de1c81 --- /dev/null +++ b/actix_web_httpauth/headers/authorization/errors/enum.ParseError.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../actix_web_httpauth/headers/authorization/enum.ParseError.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/header/struct.Authorization.html b/actix_web_httpauth/headers/authorization/header/struct.Authorization.html new file mode 100644 index 000000000..7e2c31cdb --- /dev/null +++ b/actix_web_httpauth/headers/authorization/header/struct.Authorization.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../actix_web_httpauth/headers/authorization/struct.Authorization.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/index.html b/actix_web_httpauth/headers/authorization/index.html new file mode 100644 index 000000000..ca110545c --- /dev/null +++ b/actix_web_httpauth/headers/authorization/index.html @@ -0,0 +1,15 @@ +actix_web_httpauth::headers::authorization - Rust + +

Module actix_web_httpauth::headers::authorization[][src]

Authorization header and various auth schemes

+

Structs

+
Authorization

Authorization header, defined in RFC 7235

+
Basic

Credentials for Basic authentication scheme, defined in RFC 7617

+
Bearer

Credentials for Bearer authentication scheme, defined in RFC6750

+

Enums

+
ParseError

Possible errors while parsing Authorization header.

+

Traits

+
Scheme

Authentication scheme for Authorization +header.

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/scheme/basic/struct.Basic.html b/actix_web_httpauth/headers/authorization/scheme/basic/struct.Basic.html new file mode 100644 index 000000000..09763c9b0 --- /dev/null +++ b/actix_web_httpauth/headers/authorization/scheme/basic/struct.Basic.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../../actix_web_httpauth/headers/authorization/struct.Basic.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/scheme/bearer/struct.Bearer.html b/actix_web_httpauth/headers/authorization/scheme/bearer/struct.Bearer.html new file mode 100644 index 000000000..2e9dead17 --- /dev/null +++ b/actix_web_httpauth/headers/authorization/scheme/bearer/struct.Bearer.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../../actix_web_httpauth/headers/authorization/struct.Bearer.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/scheme/trait.Scheme.html b/actix_web_httpauth/headers/authorization/scheme/trait.Scheme.html new file mode 100644 index 000000000..11a90ef8d --- /dev/null +++ b/actix_web_httpauth/headers/authorization/scheme/trait.Scheme.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../actix_web_httpauth/headers/authorization/trait.Scheme.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/sidebar-items.js b/actix_web_httpauth/headers/authorization/sidebar-items.js new file mode 100644 index 000000000..69e4942b4 --- /dev/null +++ b/actix_web_httpauth/headers/authorization/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["ParseError","Possible errors while parsing `Authorization` header."]],"struct":[["Authorization","`Authorization` header, defined in RFC 7235"],["Basic","Credentials for `Basic` authentication scheme, defined in RFC 7617"],["Bearer","Credentials for `Bearer` authentication scheme, defined in RFC6750"]],"trait":[["Scheme","Authentication scheme for `Authorization` header."]]}); \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/struct.Authorization.html b/actix_web_httpauth/headers/authorization/struct.Authorization.html new file mode 100644 index 000000000..99881b176 --- /dev/null +++ b/actix_web_httpauth/headers/authorization/struct.Authorization.html @@ -0,0 +1,71 @@ +actix_web_httpauth::headers::authorization::Authorization - Rust + +

Struct actix_web_httpauth::headers::authorization::Authorization[][src]

pub struct Authorization<S: Scheme>(_);

Authorization header, defined in RFC 7235

+

The “Authorization” header field allows a user agent to authenticate +itself with an origin server – usually, but not necessarily, after +receiving a 401 (Unauthorized) response. Its value consists of +credentials containing the authentication information of the user +agent for the realm of the resource being requested.

+

Authorization header is generic over authentication +scheme.

+

Example

+
+fn handler(req: HttpRequest) -> Result<String> {
+    let auth = Authorization::<Basic>::parse(&req)?;
+
+    Ok(format!("Hello, {}!", auth.as_ref().user_id()))
+}
+

Implementations

impl<S> Authorization<S> where
    S: Scheme
[src]

pub fn into_scheme(self) -> S[src]

Consumes Authorization header and returns inner Scheme +implementation.

+

Trait Implementations

impl<S> AsMut<S> for Authorization<S> where
    S: Scheme
[src]

impl<S> AsRef<S> for Authorization<S> where
    S: Scheme
[src]

impl<S: Clone + Scheme> Clone for Authorization<S>[src]

impl<S: Debug + Scheme> Debug for Authorization<S>[src]

impl<S: Default + Scheme> Default for Authorization<S>[src]

impl<S: Scheme> Display for Authorization<S>[src]

impl<S: Eq + Scheme> Eq for Authorization<S>[src]

impl<S> From<S> for Authorization<S> where
    S: Scheme
[src]

impl<S: Hash + Scheme> Hash for Authorization<S>[src]

impl<S: Scheme> Header for Authorization<S>[src]

impl<S: Scheme> IntoHeaderValue for Authorization<S>[src]

type Error = <S as IntoHeaderValue>::Error

The type returned in the event of a conversion error.

+

impl<S: Ord + Scheme> Ord for Authorization<S>[src]

impl<S: PartialEq + Scheme> PartialEq<Authorization<S>> for Authorization<S>[src]

impl<S: PartialOrd + Scheme> PartialOrd<Authorization<S>> for Authorization<S>[src]

impl<S: Scheme> StructuralEq for Authorization<S>[src]

impl<S: Scheme> StructuralPartialEq for Authorization<S>[src]

Auto Trait Implementations

impl<S> RefUnwindSafe for Authorization<S> where
    S: RefUnwindSafe

impl<S> Send for Authorization<S>

impl<S> Sync for Authorization<S>

impl<S> Unpin for Authorization<S> where
    S: Unpin

impl<S> UnwindSafe for Authorization<S> where
    S: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CallHasher for T where
    T: Hash + ?Sized

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<!> for T[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> IntoHeaderPair for T where
    T: Header, 

type Error = <T as IntoHeaderValue>::Error

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/struct.Basic.html b/actix_web_httpauth/headers/authorization/struct.Basic.html new file mode 100644 index 000000000..4e4676fdd --- /dev/null +++ b/actix_web_httpauth/headers/authorization/struct.Basic.html @@ -0,0 +1,54 @@ +actix_web_httpauth::headers::authorization::Basic - Rust + +

Struct actix_web_httpauth::headers::authorization::Basic[][src]

pub struct Basic { /* fields omitted */ }

Credentials for Basic authentication scheme, defined in RFC 7617

+

Implementations

impl Basic[src]

pub fn new<U, P>(user_id: U, password: Option<P>) -> Basic where
    U: Into<Cow<'static, str>>,
    P: Into<Cow<'static, str>>, 
[src]

Creates Basic credentials with provided user_id and optional +password.

+

Example

+
+let credentials = Basic::new("Alladin", Some("open sesame"));
+

pub fn user_id(&self) -> &Cow<'static, str>[src]

Returns client’s user-ID.

+

pub fn password(&self) -> Option<&Cow<'static, str>>[src]

Returns client’s password if provided.

+

Trait Implementations

impl Clone for Basic[src]

impl Debug for Basic[src]

impl Display for Basic[src]

impl Eq for Basic[src]

impl IntoHeaderValue for Basic[src]

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.

+

impl Ord for Basic[src]

impl PartialEq<Basic> for Basic[src]

impl PartialOrd<Basic> for Basic[src]

impl Scheme for Basic[src]

impl StructuralEq for Basic[src]

impl StructuralPartialEq for Basic[src]

Auto Trait Implementations

impl RefUnwindSafe for Basic

impl Send for Basic

impl Sync for Basic

impl Unpin for Basic

impl UnwindSafe for Basic

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/struct.Bearer.html b/actix_web_httpauth/headers/authorization/struct.Bearer.html new file mode 100644 index 000000000..1276ac124 --- /dev/null +++ b/actix_web_httpauth/headers/authorization/struct.Bearer.html @@ -0,0 +1,54 @@ +actix_web_httpauth::headers::authorization::Bearer - Rust + +

Struct actix_web_httpauth::headers::authorization::Bearer[][src]

pub struct Bearer { /* fields omitted */ }

Credentials for Bearer authentication scheme, defined in RFC6750

+

Should be used in combination with +Authorization header.

+

Implementations

impl Bearer[src]

pub fn new<T>(token: T) -> Bearer where
    T: Into<Cow<'static, str>>, 
[src]

Creates new Bearer credentials with the token provided.

+

Example

+
+let credentials = Bearer::new("mF_9.B5f-4.1JqM");
+

pub fn token(&self) -> &Cow<'static, str>[src]

Gets reference to the credentials token.

+

Trait Implementations

impl Clone for Bearer[src]

impl Debug for Bearer[src]

impl Display for Bearer[src]

impl Eq for Bearer[src]

impl IntoHeaderValue for Bearer[src]

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.

+

impl Ord for Bearer[src]

impl PartialEq<Bearer> for Bearer[src]

impl PartialOrd<Bearer> for Bearer[src]

impl Scheme for Bearer[src]

impl StructuralEq for Bearer[src]

impl StructuralPartialEq for Bearer[src]

Auto Trait Implementations

impl RefUnwindSafe for Bearer

impl Send for Bearer

impl Sync for Bearer

impl Unpin for Bearer

impl UnwindSafe for Bearer

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/authorization/trait.Scheme.html b/actix_web_httpauth/headers/authorization/trait.Scheme.html new file mode 100644 index 000000000..ba397a602 --- /dev/null +++ b/actix_web_httpauth/headers/authorization/trait.Scheme.html @@ -0,0 +1,10 @@ +actix_web_httpauth::headers::authorization::Scheme - Rust + +

Trait actix_web_httpauth::headers::authorization::Scheme[][src]

pub trait Scheme: IntoHeaderValue + Debug + Display + Clone + Send + Sync {
+    fn parse(header: &HeaderValue) -> Result<Self, ParseError>;
+}

Authentication scheme for Authorization +header.

+

Required methods

fn parse(header: &HeaderValue) -> Result<Self, ParseError>[src]

Try to parse the authentication scheme from the Authorization header.

+
Loading content...

Implementors

impl Scheme for Basic[src]

impl Scheme for Bearer[src]

Loading content...
+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/index.html b/actix_web_httpauth/headers/index.html new file mode 100644 index 000000000..c47b0ac0c --- /dev/null +++ b/actix_web_httpauth/headers/index.html @@ -0,0 +1,9 @@ +actix_web_httpauth::headers - Rust + +

Module actix_web_httpauth::headers[][src]

Typed HTTP headers

+

Modules

+
authorization

Authorization header and various auth schemes

+
www_authenticate

WWW-Authenticate header and various auth challenges

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/sidebar-items.js b/actix_web_httpauth/headers/sidebar-items.js new file mode 100644 index 000000000..95a819106 --- /dev/null +++ b/actix_web_httpauth/headers/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["authorization","`Authorization` header and various auth schemes"],["www_authenticate","`WWW-Authenticate` header and various auth challenges"]]}); \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/basic/index.html b/actix_web_httpauth/headers/www_authenticate/basic/index.html new file mode 100644 index 000000000..eafb96d3d --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/basic/index.html @@ -0,0 +1,9 @@ +actix_web_httpauth::headers::www_authenticate::basic - Rust + +

Module actix_web_httpauth::headers::www_authenticate::basic[][src]

Challenge for the “Basic” HTTP Authentication Scheme

+

Structs

+
Basic

Challenge for WWW-Authenticate header with HTTP Basic auth scheme, +described in RFC 7617

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/basic/sidebar-items.js b/actix_web_httpauth/headers/www_authenticate/basic/sidebar-items.js new file mode 100644 index 000000000..2257e0dd4 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/basic/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Basic","Challenge for `WWW-Authenticate` header with HTTP Basic auth scheme, described in RFC 7617"]]}); \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/basic/struct.Basic.html b/actix_web_httpauth/headers/www_authenticate/basic/struct.Basic.html new file mode 100644 index 000000000..1f70f989e --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/basic/struct.Basic.html @@ -0,0 +1,75 @@ +actix_web_httpauth::headers::www_authenticate::basic::Basic - Rust + +

Struct actix_web_httpauth::headers::www_authenticate::basic::Basic[][src]

pub struct Basic { /* fields omitted */ }

Challenge for WWW-Authenticate header with HTTP Basic auth scheme, +described in RFC 7617

+

Example

+
+use actix_web_httpauth::headers::www_authenticate::basic::Basic;
+use actix_web_httpauth::headers::www_authenticate::WwwAuthenticate;
+
+fn index(_req: HttpRequest) -> HttpResponse {
+    let challenge = Basic::with_realm("Restricted area");
+
+    HttpResponse::Unauthorized()
+        .insert_header(WwwAuthenticate(challenge))
+        .finish()
+}
+

Implementations

impl Basic[src]

pub fn new() -> Basic[src]

Creates new Basic challenge with an empty realm field.

+

Example

+
+let challenge = Basic::new();
+

pub fn with_realm<T>(value: T) -> Basic where
    T: Into<Cow<'static, str>>, 
[src]

Creates new Basic challenge from the provided realm field value.

+

Examples

+
+let challenge = Basic::with_realm("Restricted area");
+ +
+let my_realm = "Earth realm".to_string();
+let challenge = Basic::with_realm(my_realm);
+

Trait Implementations

impl AsRef<Basic> for Config[src]

impl Clone for Basic[src]

impl Debug for Basic[src]

impl Default for Basic[src]

impl Display for Basic[src]

impl Eq for Basic[src]

impl Hash for Basic[src]

impl IntoHeaderValue for Basic[src]

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.

+

impl Ord for Basic[src]

impl PartialEq<Basic> for Basic[src]

impl PartialOrd<Basic> for Basic[src]

impl StructuralEq for Basic[src]

impl StructuralPartialEq for Basic[src]

Auto Trait Implementations

impl RefUnwindSafe for Basic

impl Send for Basic

impl Sync for Basic

impl Unpin for Basic

impl UnwindSafe for Basic

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CallHasher for T where
    T: Hash + ?Sized

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/bearer/enum.Error.html b/actix_web_httpauth/headers/www_authenticate/bearer/enum.Error.html new file mode 100644 index 000000000..20a857a7f --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/bearer/enum.Error.html @@ -0,0 +1,61 @@ +actix_web_httpauth::headers::www_authenticate::bearer::Error - Rust + +

Enum actix_web_httpauth::headers::www_authenticate::bearer::Error[][src]

pub enum Error {
+    InvalidRequest,
+    InvalidToken,
+    InsufficientScope,
+}

Bearer authorization error types, described in RFC 6750

+

+ Variants

+
InvalidRequest

The request is missing a required parameter, includes an unsupported +parameter or parameter value, repeats the same parameter, uses more +than one method for including an access token, or is otherwise +malformed.

+
InvalidToken

The access token provided is expired, revoked, malformed, or invalid +for other reasons.

+
InsufficientScope

The request requires higher privileges than provided by the access +token.

+

Implementations

impl Error[src]

pub fn status_code(&self) -> StatusCode[src]

Returns HTTP status code suitable for current error type.

+

Trait Implementations

impl Clone for Error[src]

impl Copy for Error[src]

impl Debug for Error[src]

impl Display for Error[src]

impl Eq for Error[src]

impl Hash for Error[src]

impl Ord for Error[src]

impl PartialEq<Error> for Error[src]

impl PartialOrd<Error> for Error[src]

impl StructuralEq for Error[src]

impl StructuralPartialEq for Error[src]

Auto Trait Implementations

impl RefUnwindSafe for Error

impl Send for Error

impl Sync for Error

impl Unpin for Error

impl UnwindSafe for Error

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CallHasher for T where
    T: Hash + ?Sized

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/bearer/index.html b/actix_web_httpauth/headers/www_authenticate/bearer/index.html new file mode 100644 index 000000000..a6e08db5a --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/bearer/index.html @@ -0,0 +1,12 @@ +actix_web_httpauth::headers::www_authenticate::bearer - Rust + +

Module actix_web_httpauth::headers::www_authenticate::bearer[][src]

Challenge for the “Bearer” HTTP Authentication Scheme

+

Structs

+
Bearer

Challenge for WWW-Authenticate header with HTTP Bearer auth scheme, +described in RFC 6750

+
BearerBuilder

Builder for the Bearer challenge.

+

Enums

+
Error

Bearer authorization error types, described in RFC 6750

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/bearer/sidebar-items.js b/actix_web_httpauth/headers/www_authenticate/bearer/sidebar-items.js new file mode 100644 index 000000000..e2562256b --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/bearer/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["Error","Bearer authorization error types, described in RFC 6750"]],"struct":[["Bearer","Challenge for `WWW-Authenticate` header with HTTP Bearer auth scheme, described in RFC 6750"],["BearerBuilder","Builder for the `Bearer` challenge."]]}); \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/bearer/struct.Bearer.html b/actix_web_httpauth/headers/www_authenticate/bearer/struct.Bearer.html new file mode 100644 index 000000000..ccaa131e3 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/bearer/struct.Bearer.html @@ -0,0 +1,78 @@ +actix_web_httpauth::headers::www_authenticate::bearer::Bearer - Rust + +

Struct actix_web_httpauth::headers::www_authenticate::bearer::Bearer[][src]

pub struct Bearer { /* fields omitted */ }

Challenge for WWW-Authenticate header with HTTP Bearer auth scheme, +described in RFC 6750

+

Example

+
+use actix_web_httpauth::headers::www_authenticate::bearer::{
+    Bearer, Error,
+};
+use actix_web_httpauth::headers::www_authenticate::WwwAuthenticate;
+
+fn index(_req: HttpRequest) -> HttpResponse {
+    let challenge = Bearer::build()
+        .realm("example")
+        .scope("openid profile email")
+        .error(Error::InvalidToken)
+        .error_description("The access token expired")
+        .error_uri("http://example.org")
+        .finish();
+
+    HttpResponse::Unauthorized()
+        .insert_header(WwwAuthenticate(challenge))
+        .finish()
+}
+

Implementations

impl Bearer[src]

pub fn build() -> BearerBuilder[src]

Creates the builder for Bearer challenge.

+

Example

+
+let challenge = Bearer::build()
+    .realm("Restricted area")
+    .scope("openid profile email")
+    .finish();
+

Trait Implementations

impl AsRef<Bearer> for Config[src]

impl Clone for Bearer[src]

impl Debug for Bearer[src]

impl Default for Bearer[src]

impl Display for Bearer[src]

impl Eq for Bearer[src]

impl Hash for Bearer[src]

impl IntoHeaderValue for Bearer[src]

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.

+

impl Ord for Bearer[src]

impl PartialEq<Bearer> for Bearer[src]

impl PartialOrd<Bearer> for Bearer[src]

impl StructuralEq for Bearer[src]

impl StructuralPartialEq for Bearer[src]

Auto Trait Implementations

impl RefUnwindSafe for Bearer

impl Send for Bearer

impl Sync for Bearer

impl Unpin for Bearer

impl UnwindSafe for Bearer

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CallHasher for T where
    T: Hash + ?Sized

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/bearer/struct.BearerBuilder.html b/actix_web_httpauth/headers/www_authenticate/bearer/struct.BearerBuilder.html new file mode 100644 index 000000000..0335178e1 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/bearer/struct.BearerBuilder.html @@ -0,0 +1,31 @@ +actix_web_httpauth::headers::www_authenticate::bearer::BearerBuilder - Rust + +

Struct actix_web_httpauth::headers::www_authenticate::bearer::BearerBuilder[][src]

pub struct BearerBuilder(_);

Builder for the Bearer challenge.

+

It is up to implementor to fill all required fields, +neither this Builder or Bearer does not provide any validation.

+

Implementations

impl BearerBuilder[src]

pub fn scope<T>(self, value: T) -> Self where
    T: Into<Cow<'static, str>>, 
[src]

Provides the scope attribute, as defined in RFC6749, Section 3.3

+

pub fn realm<T>(self, value: T) -> Self where
    T: Into<Cow<'static, str>>, 
[src]

Provides the realm attribute, as defined in RFC2617

+

pub fn error(self, value: Error) -> Self[src]

Provides the error attribute, as defined in RFC6750, Section 3.1

+

pub fn error_description<T>(self, value: T) -> Self where
    T: Into<Cow<'static, str>>, 
[src]

Provides the error_description attribute, as defined in RFC6750, Section 3

+

pub fn error_uri<T>(self, value: T) -> Self where
    T: Into<Cow<'static, str>>, 
[src]

Provides the error_uri attribute, as defined in RFC6750, Section 3

+

It is up to implementor to provide properly-formed absolute URI.

+

pub fn finish(self) -> Bearer[src]

Consumes the builder and returns built Bearer instance.

+

Trait Implementations

impl Debug for BearerBuilder[src]

impl Default for BearerBuilder[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/challenge/basic/index.html b/actix_web_httpauth/headers/www_authenticate/challenge/basic/index.html new file mode 100644 index 000000000..038227eef --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/challenge/basic/index.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../../actix_web_httpauth/headers/www_authenticate/basic/index.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/challenge/basic/struct.Basic.html b/actix_web_httpauth/headers/www_authenticate/challenge/basic/struct.Basic.html new file mode 100644 index 000000000..62cd49f03 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/challenge/basic/struct.Basic.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../../actix_web_httpauth/headers/www_authenticate/basic/struct.Basic.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/challenge/bearer/builder/struct.BearerBuilder.html b/actix_web_httpauth/headers/www_authenticate/challenge/bearer/builder/struct.BearerBuilder.html new file mode 100644 index 000000000..ad16ff0df --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/challenge/bearer/builder/struct.BearerBuilder.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../../../actix_web_httpauth/headers/www_authenticate/bearer/struct.BearerBuilder.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/challenge/bearer/challenge/struct.Bearer.html b/actix_web_httpauth/headers/www_authenticate/challenge/bearer/challenge/struct.Bearer.html new file mode 100644 index 000000000..29f95b245 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/challenge/bearer/challenge/struct.Bearer.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../../../actix_web_httpauth/headers/www_authenticate/bearer/struct.Bearer.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/challenge/bearer/errors/enum.Error.html b/actix_web_httpauth/headers/www_authenticate/challenge/bearer/errors/enum.Error.html new file mode 100644 index 000000000..a4c048dfc --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/challenge/bearer/errors/enum.Error.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../../../actix_web_httpauth/extractors/bearer/enum.Error.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/challenge/bearer/index.html b/actix_web_httpauth/headers/www_authenticate/challenge/bearer/index.html new file mode 100644 index 000000000..5570fdcda --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/challenge/bearer/index.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../../actix_web_httpauth/headers/www_authenticate/bearer/index.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/challenge/trait.Challenge.html b/actix_web_httpauth/headers/www_authenticate/challenge/trait.Challenge.html new file mode 100644 index 000000000..24e29a275 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/challenge/trait.Challenge.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../actix_web_httpauth/headers/www_authenticate/trait.Challenge.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/header/struct.WwwAuthenticate.html b/actix_web_httpauth/headers/www_authenticate/header/struct.WwwAuthenticate.html new file mode 100644 index 000000000..a9fe30952 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/header/struct.WwwAuthenticate.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../actix_web_httpauth/headers/www_authenticate/struct.WwwAuthenticate.html...

+ + + \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/index.html b/actix_web_httpauth/headers/www_authenticate/index.html new file mode 100644 index 000000000..af0793d98 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/index.html @@ -0,0 +1,13 @@ +actix_web_httpauth::headers::www_authenticate - Rust + +

Module actix_web_httpauth::headers::www_authenticate[][src]

WWW-Authenticate header and various auth challenges

+

Modules

+
basic

Challenge for the “Basic” HTTP Authentication Scheme

+
bearer

Challenge for the “Bearer” HTTP Authentication Scheme

+

Structs

+
WwwAuthenticate

WWW-Authenticate header, described in RFC 7235

+

Traits

+
Challenge

Authentication challenge for WWW-Authenticate header.

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/sidebar-items.js b/actix_web_httpauth/headers/www_authenticate/sidebar-items.js new file mode 100644 index 000000000..f7fe8c15d --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["basic","Challenge for the “Basic” HTTP Authentication Scheme"],["bearer","Challenge for the “Bearer” HTTP Authentication Scheme"]],"struct":[["WwwAuthenticate","`WWW-Authenticate` header, described in RFC 7235"]],"trait":[["Challenge","Authentication challenge for `WWW-Authenticate` header."]]}); \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/struct.WwwAuthenticate.html b/actix_web_httpauth/headers/www_authenticate/struct.WwwAuthenticate.html new file mode 100644 index 000000000..8707729dd --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/struct.WwwAuthenticate.html @@ -0,0 +1,52 @@ +actix_web_httpauth::headers::www_authenticate::WwwAuthenticate - Rust + +

Struct actix_web_httpauth::headers::www_authenticate::WwwAuthenticate[][src]

pub struct WwwAuthenticate<C: Challenge>(pub C);

WWW-Authenticate header, described in RFC 7235

+

This header is generic over Challenge trait, +see Basic and +Bearer challenges for details.

+

Trait Implementations

impl<C: Clone + Challenge> Clone for WwwAuthenticate<C>[src]

impl<C: Debug + Challenge> Debug for WwwAuthenticate<C>[src]

impl<C: Default + Challenge> Default for WwwAuthenticate<C>[src]

impl<C: Eq + Challenge> Eq for WwwAuthenticate<C>[src]

impl<C: Hash + Challenge> Hash for WwwAuthenticate<C>[src]

impl<C: Challenge> Header for WwwAuthenticate<C>[src]

impl<C: Challenge> IntoHeaderValue for WwwAuthenticate<C>[src]

type Error = <C as IntoHeaderValue>::Error

The type returned in the event of a conversion error.

+

impl<C: Ord + Challenge> Ord for WwwAuthenticate<C>[src]

impl<C: PartialEq + Challenge> PartialEq<WwwAuthenticate<C>> for WwwAuthenticate<C>[src]

impl<C: PartialOrd + Challenge> PartialOrd<WwwAuthenticate<C>> for WwwAuthenticate<C>[src]

impl<C: Challenge> StructuralEq for WwwAuthenticate<C>[src]

impl<C: Challenge> StructuralPartialEq for WwwAuthenticate<C>[src]

Auto Trait Implementations

impl<C> RefUnwindSafe for WwwAuthenticate<C> where
    C: RefUnwindSafe

impl<C> Send for WwwAuthenticate<C>

impl<C> Sync for WwwAuthenticate<C>

impl<C> Unpin for WwwAuthenticate<C> where
    C: Unpin

impl<C> UnwindSafe for WwwAuthenticate<C> where
    C: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CallHasher for T where
    T: Hash + ?Sized

impl<Q, K> Equivalent<K> for Q where
    K: Borrow<Q> + ?Sized,
    Q: Eq + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> IntoHeaderPair for T where
    T: Header, 

type Error = <T as IntoHeaderValue>::Error

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/headers/www_authenticate/trait.Challenge.html b/actix_web_httpauth/headers/www_authenticate/trait.Challenge.html new file mode 100644 index 000000000..e6f7821e0 --- /dev/null +++ b/actix_web_httpauth/headers/www_authenticate/trait.Challenge.html @@ -0,0 +1,9 @@ +actix_web_httpauth::headers::www_authenticate::Challenge - Rust + +

Trait actix_web_httpauth::headers::www_authenticate::Challenge[][src]

pub trait Challenge: IntoHeaderValue + Debug + Display + Clone + Send + Sync {
+    fn to_bytes(&self) -> Bytes;
+}

Authentication challenge for WWW-Authenticate header.

+

Required methods

fn to_bytes(&self) -> Bytes[src]

Converts the challenge into a bytes suitable for HTTP transmission.

+
Loading content...

Implementors

Loading content...
+ \ No newline at end of file diff --git a/actix_web_httpauth/index.html b/actix_web_httpauth/index.html new file mode 100644 index 000000000..25024bff3 --- /dev/null +++ b/actix_web_httpauth/index.html @@ -0,0 +1,21 @@ +actix_web_httpauth - Rust + +

Crate actix_web_httpauth[][src]

HTTP authentication schemes for actix-web.

+

Provides:

+ +

Supported schemes

+ +

Modules

+
extractors

Type-safe authentication information extractors

+
headers

Typed HTTP headers

+
middleware

HTTP Authentication middleware.

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/middleware/index.html b/actix_web_httpauth/middleware/index.html new file mode 100644 index 000000000..b563dd5db --- /dev/null +++ b/actix_web_httpauth/middleware/index.html @@ -0,0 +1,8 @@ +actix_web_httpauth::middleware - Rust + +

Module actix_web_httpauth::middleware[][src]

HTTP Authentication middleware.

+

Structs

+
HttpAuthentication

Middleware for checking HTTP authentication.

+
+ \ No newline at end of file diff --git a/actix_web_httpauth/middleware/sidebar-items.js b/actix_web_httpauth/middleware/sidebar-items.js new file mode 100644 index 000000000..fed5c43f5 --- /dev/null +++ b/actix_web_httpauth/middleware/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["HttpAuthentication","Middleware for checking HTTP authentication."]]}); \ No newline at end of file diff --git a/actix_web_httpauth/middleware/struct.HttpAuthentication.html b/actix_web_httpauth/middleware/struct.HttpAuthentication.html new file mode 100644 index 000000000..eaaa212a3 --- /dev/null +++ b/actix_web_httpauth/middleware/struct.HttpAuthentication.html @@ -0,0 +1,71 @@ +actix_web_httpauth::middleware::HttpAuthentication - Rust + +

Struct actix_web_httpauth::middleware::HttpAuthentication[][src]

pub struct HttpAuthentication<T, F> where
    T: AuthExtractor
{ /* fields omitted */ }

Middleware for checking HTTP authentication.

+

If there is no Authorization header in the request, this middleware returns an error +immediately, without calling the F callback.

+

Otherwise, it will pass both the request and the parsed credentials into it. In case of +successful validation F callback is required to return the ServiceRequest back.

+

Implementations

impl<T, F, O> HttpAuthentication<T, F> where
    T: AuthExtractor,
    F: Fn(ServiceRequest, T) -> O,
    O: Future<Output = Result<ServiceRequest, Error>>, 
[src]

pub fn with_fn(process_fn: F) -> HttpAuthentication<T, F>[src]

Construct HttpAuthentication middleware with the provided auth extractor T and +validation callback F.

+

impl<F, O> HttpAuthentication<BasicAuth, F> where
    F: Fn(ServiceRequest, BasicAuth) -> O,
    O: Future<Output = Result<ServiceRequest, Error>>, 
[src]

pub fn basic(process_fn: F) -> Self[src]

Construct HttpAuthentication middleware for the HTTP “Basic” authentication scheme.

+

Example

+
+// In this example validator returns immediately, but since it is required to return
+// anything that implements `IntoFuture` trait, it can be extended to query database or to
+// do something else in a async manner.
+async fn validator(
+    req: ServiceRequest,
+    credentials: BasicAuth,
+) -> Result<ServiceRequest, Error> {
+    // All users are great and more than welcome!
+    Ok(req)
+}
+
+let middleware = HttpAuthentication::basic(validator);
+

impl<F, O> HttpAuthentication<BearerAuth, F> where
    F: Fn(ServiceRequest, BearerAuth) -> O,
    O: Future<Output = Result<ServiceRequest, Error>>, 
[src]

pub fn bearer(process_fn: F) -> Self[src]

Construct HttpAuthentication middleware for the HTTP “Bearer” authentication scheme.

+

Example

+
+async fn validator(req: ServiceRequest, credentials: BearerAuth) -> Result<ServiceRequest, Error> {
+    if credentials.token() == "mF_9.B5f-4.1JqM" {
+        Ok(req)
+    } else {
+        let config = req.app_data::<Config>()
+            .map(|data| data.clone())
+            .unwrap_or_else(Default::default)
+            .scope("urn:example:channel=HBO&urn:example:rating=G,PG-13");
+
+        Err(AuthenticationError::from(config).into())
+    }
+}
+
+let middleware = HttpAuthentication::bearer(validator);
+

Trait Implementations

impl<T: Clone, F: Clone> Clone for HttpAuthentication<T, F> where
    T: AuthExtractor
[src]

impl<T: Debug, F: Debug> Debug for HttpAuthentication<T, F> where
    T: AuthExtractor
[src]

impl<S, B, T, F, O> Transform<S, ServiceRequest> for HttpAuthentication<T, F> where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    F: Fn(ServiceRequest, T) -> O + 'static,
    O: Future<Output = Result<ServiceRequest, Error>> + 'static,
    T: AuthExtractor + 'static, 
[src]

type Response = ServiceResponse<B>

Responses produced by the service.

+

type Error = Error

Errors produced by the service.

+

type Transform = AuthenticationMiddleware<S, F, T>

The TransformService value created by this factory

+

type InitError = ()

Errors produced while building a transform service.

+

type Future = Ready<Result<Self::Transform, Self::InitError>>

The future response value.

+

Auto Trait Implementations

impl<T, F> RefUnwindSafe for HttpAuthentication<T, F> where
    F: RefUnwindSafe,
    T: RefUnwindSafe

impl<T, F> Send for HttpAuthentication<T, F> where
    F: Send + Sync,
    T: Send

impl<T, F> Sync for HttpAuthentication<T, F> where
    F: Send + Sync,
    T: Sync

impl<T, F> Unpin for HttpAuthentication<T, F> where
    T: Unpin

impl<T, F> UnwindSafe for HttpAuthentication<T, F> where
    F: RefUnwindSafe,
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/actix_web_httpauth/sidebar-items.js b/actix_web_httpauth/sidebar-items.js new file mode 100644 index 000000000..d19fefc0e --- /dev/null +++ b/actix_web_httpauth/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["extractors","Type-safe authentication information extractors"],["headers","Typed HTTP headers"],["middleware","HTTP Authentication middleware."]]}); \ No newline at end of file diff --git a/ayu.css b/ayu.css index 096f6f36e..77e68433e 100644 --- a/ayu.css +++ b/ayu.css @@ -1 +1 @@ - body{background-color:#0f1419;color:#c5c5c5;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:white;}h1.fqn{border-bottom-color:#5c6773;}h1.fqn a{color:#fff;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod){border-bottom-color:#5c6773;}h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){border:none;}.in-band{background-color:#0f1419;}.invisible{background:rgba(0,0,0,0);}code{color:#ffb454;}h3>code,h4>code,h5>code{color:#e6e1cf;}pre>code{color:#e6e1cf;}span code{color:#e6e1cf;}.docblock a>code{color:#39AFD7 !important;}.docblock code,.docblock-short code{background-color:#191f26;}pre{color:#e6e1cf;background-color:#191f26;}.sidebar{background-color:#14191f;}.logo-container.rust-logo>img{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);}*{scrollbar-color:#5c6773 transparent;}.sidebar{scrollbar-color:#5c6773 transparent;}::-webkit-scrollbar-track{background-color:transparent;}::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar::-webkit-scrollbar-track{background-color:transparent;}.sidebar::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar .current{background-color:transparent;color:#ffb44c;}.source .sidebar{background-color:#0f1419;}.sidebar .location{border-color:#000;background-color:#0f1419;color:#fff;}.sidebar-elems .location{color:#ff7733;}.sidebar-elems .location a{color:#fff;}.sidebar .version{border-bottom-color:#424c57;}.sidebar-title{border-top-color:#5c6773;border-bottom-color:#5c6773;}.block a:hover{background:transparent;color:#ffb44c;}.line-numbers span{color:#5c6773;}.line-numbers .line-highlighted{color:#708090;background-color:rgba(255,236,164,0.06);padding-right:4px;border-right:1px solid #ffb44c;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#5c6773;}.docblock table,.docblock table td,.docblock table th{border-color:#5c6773;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#c5c5c5;}.content .highlighted{color:#000 !important;background-color:#c6afb3;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted{background-color:#c6afb3;}.search-results a{color:#0096cf;}.search-results a span.desc{color:#c5c5c5;}.content .item-info::before{color:#ccc;}.content span.foreigntype,.content a.foreigntype{color:#ef57ff;}.content span.union,.content a.union{color:#98a01c;}.content span.constant,.content a.constant,.content span.static,.content a.static{color:#6380a0;}.content span.primitive,.content a.primitive{color:#32889b;}.content span.traitalias,.content a.traitalias{color:#57d399;}.content span.keyword,.content a.keyword{color:#de5249;}.content span.externcrate,.content span.mod,.content a.mod{color:#acccf9;}.content span.struct,.content a.struct{color:#ffa0a5;}.content span.enum,.content a.enum{color:#99e0c9;}.content span.trait,.content a.trait{color:#39AFD7;}.content span.type,.content a.type{color:#cfbcf5;}.content span.fn,.content a.fn,.content span.method,.content a.method,.content span.tymethod,.content a.tymethod,.content .fnname{color:#fdd687;}.content span.attr,.content a.attr,.content span.derive,.content a.derive,.content span.macro,.content a.macro{color:#a37acc;}pre.rust .comment{color:#788797;}pre.rust .doccomment{color:#a1ac88;}nav:not(.sidebar){border-bottom-color:#424c57;}nav.main .current{border-top-color:#5c6773;border-bottom-color:#5c6773;}nav.main .separator{border:1px solid #5c6773;}a{color:#c5c5c5;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.item-info a,#help a{color:#39AFD7;}.collapse-toggle{color:#999;}#crate-search{color:#c5c5c5;background-color:#141920;box-shadow:0 0 0 1px #424c57,0 0 0 2px transparent;border-color:#424c57;}.search-input{color:#ffffff;background-color:#141920;box-shadow:0 0 0 1px #424c57,0 0 0 2px transparent;transition:box-shadow 150ms ease-in-out;}#crate-search+.search-input:focus{box-shadow:0 0 0 1px #148099,0 0 0 2px transparent;}.search-focus:disabled{color:#929292;}.module-item .stab{color:#000;}.stab.unstable,.stab.deprecated,.stab.portability{color:#c5c5c5;background:#314559 !important;border-style:none !important;border-radius:4px;padding:3px 6px 3px 6px;}.stab.portability>code{color:#e6e1cf;background-color:transparent;}#help>div{background:#14191f;box-shadow:0px 6px 20px 0px black;border:none;border-radius:4px;}#help>div>span{border-bottom-color:#5c6773;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#788797;}.line-numbers :target{background-color:transparent;}pre.rust .number,pre.rust .string{color:#b8cc52;}pre.rust .kw,pre.rust .kw-2,pre.rust .prelude-ty,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .op,pre.rust .lifetime{color:#ff7733;}pre.rust .macro,pre.rust .macro-nonterminal{color:#a37acc;}pre.rust .question-mark{color:#ff9011;}pre.rust .self{color:#36a3d9;font-style:italic;}pre.rust .attribute{color:#e6e1cf;}pre.rust .attribute .ident,pre.rust .attribute .op{color:#e6e1cf;}.example-wrap>pre.line-number{color:#5c67736e;border:none;}a.test-arrow{font-size:100%;color:#788797;border-radius:4px;background-color:rgba(57,175,215,0.09);}a.test-arrow:hover{background-color:rgba(57,175,215,0.368);color:#c5c5c5;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:rgba(255,236,164,0.06);border-right:3px solid rgba(255,180,76,0.85);}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.4);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#39AFD7;}.tooltip::after{background-color:#314559;color:#c5c5c5;border:1px solid #5c6773;}.tooltip::before{border-color:transparent #314559 transparent transparent;}.notable-traits-tooltiptext{background-color:#314559;border-color:#5c6773;}#titles>button.selected{background-color:#141920 !important;border-bottom:1px solid #ffb44c !important;border-top:none;}#titles>button:not(.selected){background-color:transparent !important;border:none;}#titles>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#titles>button>div.count{color:#888;}.content .highlighted.mod,.content .highlighted.externcrate{}.search-input:focus{}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{}.content .highlighted.trait{}.content span.struct,.content a.struct,.block a.current.struct{}#titles>button:hover,#titles>button.selected{}.content .highlighted.traitalias{}.content span.type,.content a.type,.block a.current.type{}.content span.union,.content a.union,.block a.current.union{}.content .highlighted.foreigntype{}pre.rust .lifetime{}.content .highlighted.primitive{}.content .highlighted.constant,.content .highlighted.static{}.stab.unstable{}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){}.content span.enum,.content a.enum,.block a.current.enum{}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{}.content span.keyword,.content a.keyword,.block a.current.keyword{}pre.rust .comment{}.content .highlighted.enum{}.content .highlighted.struct{}.content .highlighted.keyword{}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{}pre.rust .kw{}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{}pre.rust .doccomment{}.stab.deprecated{}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{}.stab.portability{}.content .highlighted.union{}.content span.primitive,.content a.primitive,.block a.current.primitive{}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{}.content .highlighted.type{}pre.rust .kw-2,pre.rust .prelude-ty{}.content span.trait,.content a.trait,.block a.current.trait{}@media (max-width:700px){.sidebar-menu{background-color:#14191f;border-bottom-color:#5c6773;border-right-color:#5c6773;}.sidebar-elems{background-color:#14191f;border-right-color:#5c6773;}#sidebar-filler{background-color:#14191f;border-bottom-color:#5c6773;}}kbd{color:#c5c5c5;background-color:#314559;border-color:#5c6773;border-bottom-color:#5c6773;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#5c6773;background-color:#0f1419;color:#fff;}#theme-picker>img,#settings-menu>img{filter:invert(100);}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#e0e0e0;}#theme-choices{border-color:#5c6773;background-color:#0f1419;}#theme-choices>button:not(:first-child){border-top-color:#5c6773;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:rgba(110,110,110,0.33);}@media (max-width:700px){#theme-picker{background:#0f1419;}}#all-types{background-color:#14191f;}#all-types:hover{background-color:rgba(70,70,70,0.33);}.search-results td span.alias{color:#c5c5c5;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#14191f;}#sidebar-toggle:hover{background-color:rgba(70,70,70,0.33);}#source-sidebar{background-color:#14191f;}#source-sidebar>.title{color:#fff;border-bottom-color:#5c6773;}div.files>a:hover,div.name:hover{background-color:#14191f;color:#ffb44c;}div.files>.selected{background-color:#14191f;color:#ffb44c;}.setting-line>.title{border-bottom-color:#5c6773;}input:checked+.slider{background-color:#ffb454 !important;} \ No newline at end of file + body{background-color:#0f1419;color:#c5c5c5;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:white;}h1.fqn{border-bottom-color:#5c6773;}h1.fqn a{color:#fff;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod){border-bottom-color:#5c6773;}h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){border:none;}.in-band{background-color:#0f1419;}.invisible{background:rgba(0,0,0,0);}code{color:#ffb454;}h3>code,h4>code,h5>code{color:#e6e1cf;}pre>code{color:#e6e1cf;}span code{color:#e6e1cf;}.docblock a>code{color:#39AFD7 !important;}.docblock code,.docblock-short code{background-color:#191f26;}pre{color:#e6e1cf;background-color:#191f26;}.sidebar{background-color:#14191f;}.logo-container.rust-logo>img{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);}*{scrollbar-color:#5c6773 transparent;}.sidebar{scrollbar-color:#5c6773 transparent;}::-webkit-scrollbar-track{background-color:transparent;}::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar::-webkit-scrollbar-track{background-color:transparent;}.sidebar::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar .current{background-color:transparent;color:#ffb44c;}.source .sidebar{background-color:#0f1419;}.sidebar .location{border-color:#000;background-color:#0f1419;color:#fff;}.sidebar-elems .location{color:#ff7733;}.sidebar-elems .location a{color:#fff;}.sidebar .version{border-bottom-color:#424c57;}.sidebar-title{border-top-color:#5c6773;border-bottom-color:#5c6773;}.block a:hover{background:transparent;color:#ffb44c;}.line-numbers span{color:#5c6773;}.line-numbers .line-highlighted{color:#708090;background-color:rgba(255,236,164,0.06);padding-right:4px;border-right:1px solid #ffb44c;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#5c6773;}.docblock table,.docblock table td,.docblock table th{border-color:#5c6773;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#c5c5c5;}.content .highlighted{color:#000 !important;background-color:#c6afb3;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted{background-color:#c6afb3;}.search-results a{color:#0096cf;}.search-results a span.desc{color:#c5c5c5;}.content .item-info::before{color:#ccc;}.content span.foreigntype,.content a.foreigntype{color:#ef57ff;}.content span.union,.content a.union{color:#98a01c;}.content span.constant,.content a.constant,.content span.static,.content a.static{color:#6380a0;}.content span.primitive,.content a.primitive{color:#32889b;}.content span.traitalias,.content a.traitalias{color:#57d399;}.content span.keyword,.content a.keyword{color:#de5249;}.content span.externcrate,.content span.mod,.content a.mod{color:#acccf9;}.content span.struct,.content a.struct{color:#ffa0a5;}.content span.enum,.content a.enum{color:#99e0c9;}.content span.trait,.content a.trait{color:#39AFD7;}.content span.type,.content a.type{color:#cfbcf5;}.content span.fn,.content a.fn,.content span.method,.content a.method,.content span.tymethod,.content a.tymethod,.content .fnname{color:#fdd687;}.content span.attr,.content a.attr,.content span.derive,.content a.derive,.content span.macro,.content a.macro{color:#a37acc;}pre.rust .comment{color:#788797;}pre.rust .doccomment{color:#a1ac88;}nav:not(.sidebar){border-bottom-color:#424c57;}nav.main .current{border-top-color:#5c6773;border-bottom-color:#5c6773;}nav.main .separator{border:1px solid #5c6773;}a{color:#c5c5c5;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.item-info a,#help a{color:#39AFD7;}.collapse-toggle{color:#999;}#crate-search{color:#c5c5c5;background-color:#141920;box-shadow:0 0 0 1px #424c57,0 0 0 2px transparent;border-color:#424c57;}.search-input{color:#ffffff;background-color:#141920;box-shadow:0 0 0 1px #424c57,0 0 0 2px transparent;transition:box-shadow 150ms ease-in-out;}#crate-search+.search-input:focus{box-shadow:0 0 0 1px #148099,0 0 0 2px transparent;}.search-focus:disabled{color:#929292;}.module-item .stab{color:#000;}.stab.unstable,.stab.deprecated,.stab.portability{color:#c5c5c5;background:#314559 !important;border-style:none !important;border-radius:4px;padding:3px 6px 3px 6px;}.stab.portability>code{color:#e6e1cf;background:none;}#help>div{background:#14191f;box-shadow:0px 6px 20px 0px black;border:none;border-radius:4px;}#help>div>span{border-bottom-color:#5c6773;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#788797;}.line-numbers :target{background-color:transparent;}pre.rust .number,pre.rust .string{color:#b8cc52;}pre.rust .kw,pre.rust .kw-2,pre.rust .prelude-ty,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .op,pre.rust .lifetime{color:#ff7733;}pre.rust .macro,pre.rust .macro-nonterminal{color:#a37acc;}pre.rust .question-mark{color:#ff9011;}pre.rust .self{color:#36a3d9;font-style:italic;}pre.rust .attribute{color:#e6e1cf;}pre.rust .attribute .ident,pre.rust .attribute .op{color:#e6e1cf;}.example-wrap>pre.line-number{color:#5c67736e;border:none;}a.test-arrow{font-size:100%;color:#788797;border-radius:4px;background-color:rgba(57,175,215,0.09);}a.test-arrow:hover{background-color:rgba(57,175,215,0.368);color:#c5c5c5;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:rgba(255,236,164,0.06);border-right:3px solid rgba(255,180,76,0.85);}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.4);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#39AFD7;}.tooltip::after{background-color:#314559;color:#c5c5c5;border:1px solid #5c6773;}.tooltip::before{border-color:transparent #314559 transparent transparent;}.notable-traits-tooltiptext{background-color:#314559;border-color:#5c6773;}#titles>button.selected{background-color:#141920 !important;border-bottom:1px solid #ffb44c !important;border-top:none;}#titles>button:not(.selected){background-color:transparent !important;border:none;}#titles>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#titles>button>div.count{color:#888;}.content .highlighted.mod,.content .highlighted.externcrate{}.search-input:focus{}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{}.content .highlighted.trait{}.content span.struct,.content a.struct,.block a.current.struct{}#titles>button:hover,#titles>button.selected{}.content .highlighted.traitalias{}.content span.type,.content a.type,.block a.current.type{}.content span.union,.content a.union,.block a.current.union{}.content .highlighted.foreigntype{}pre.rust .lifetime{}.content .highlighted.primitive{}.content .highlighted.constant,.content .highlighted.static{}.stab.unstable{}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){}.content span.enum,.content a.enum,.block a.current.enum{}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{}.content span.keyword,.content a.keyword,.block a.current.keyword{}pre.rust .comment{}.content .highlighted.enum{}.content .highlighted.struct{}.content .highlighted.keyword{}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{}pre.rust .kw{}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{}pre.rust .doccomment{}.stab.deprecated{}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{}.stab.portability{}.content .highlighted.union{}.content span.primitive,.content a.primitive,.block a.current.primitive{}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{}.content .highlighted.type{}pre.rust .kw-2,pre.rust .prelude-ty{}.content span.trait,.content a.trait,.block a.current.trait{}@media (max-width:700px){.sidebar-menu{background-color:#14191f;border-bottom-color:#5c6773;border-right-color:#5c6773;}.sidebar-elems{background-color:#14191f;border-right-color:#5c6773;}#sidebar-filler{background-color:#14191f;border-bottom-color:#5c6773;}}kbd{color:#c5c5c5;background-color:#314559;border-color:#5c6773;border-bottom-color:#5c6773;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#5c6773;background-color:#0f1419;color:#fff;}#theme-picker>img,#settings-menu>img{filter:invert(100);}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#e0e0e0;}#theme-choices{border-color:#5c6773;background-color:#0f1419;}#theme-choices>button:not(:first-child){border-top-color:#5c6773;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:rgba(110,110,110,0.33);}@media (max-width:700px){#theme-picker{background:#0f1419;}}#all-types{background-color:#14191f;}#all-types:hover{background-color:rgba(70,70,70,0.33);}.search-results td span.alias{color:#c5c5c5;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#14191f;}#sidebar-toggle:hover{background-color:rgba(70,70,70,0.33);}#source-sidebar{background-color:#14191f;}#source-sidebar>.title{color:#fff;border-bottom-color:#5c6773;}div.files>a:hover,div.name:hover{background-color:#14191f;color:#ffb44c;}div.files>.selected{background-color:#14191f;color:#ffb44c;}.setting-line>.title{border-bottom-color:#5c6773;}input:checked+.slider{background-color:#ffb454 !important;} \ No newline at end of file diff --git a/crates.js b/crates.js new file mode 100644 index 000000000..5176ac7e3 --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["actix_cors","actix_identity","actix_protobuf","actix_redis","actix_session","actix_web_httpauth","prost_example"]; \ No newline at end of file diff --git a/dark.css b/dark.css index 85dec489d..8ee9c65d6 100644 --- a/dark.css +++ b/dark.css @@ -1 +1 @@ -body{background-color:#353535;color:#ddd;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:#ddd;}h1.fqn{border-bottom-color:#d2d2d2;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#d2d2d2;}.in-band{background-color:#353535;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#2A2A2A;}pre{background-color:#2A2A2A;}.sidebar{background-color:#505050;}.logo-container.rust-logo>img{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)}*{scrollbar-color:rgb(64,65,67) #717171;}.sidebar{scrollbar-color:rgba(32,34,37,.6) transparent;}::-webkit-scrollbar-track{background-color:#717171;}::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar::-webkit-scrollbar-track{background-color:#717171;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar .current{background-color:#333;}.source .sidebar{background-color:#353535;}.sidebar .location{border-color:#fff;background:#575757;color:#DDD;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#444;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#DDD;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#ddd;}.content .highlighted{color:#eee !important;background-color:#616161;}.content .highlighted a,.content .highlighted span{color:#eee !important;}.content .highlighted.trait{background-color:#013191;}.content .highlighted.traitalias{background-color:#013191;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.mod{background-color:#803a1b;}.content .highlighted.externcrate{background-color:#396bac;}.content .highlighted.enum{background-color:#5b4e68;}.content .highlighted.struct{background-color:#194e9f;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#4950ed;}.content .highlighted.type{background-color:#38902c;}.content .highlighted.foreigntype{background-color:#b200d6;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#217d1c;}.content .highlighted.constant,.content .highlighted.static{background-color:#0063cc;}.content .highlighted.primitive{background-color:#00708a;}.content .highlighted.keyword{background-color:#884719;}.content .item-info::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#82b089;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#ff7f00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#dd7de8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#a6ae37;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#82a5c9;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#43aec7;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#bda000;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b397da;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav:not(.sidebar){border-bottom-color:#4e4e4e;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#ddd;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.item-info a,#help a{color:#D2991D;}a.test-arrow{color:#dedede;}.collapse-toggle{color:#999;}#crate-search{color:#111;background-color:#f0f0f0;border-color:#000;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input{color:#111;background-color:#f0f0f0;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input:focus{border-color:#008dfd;}.search-focus:disabled{background-color:#c5c4c4;}#crate-search+.search-input:focus{box-shadow:0 0 8px 4px #078dd8;}.module-item .stab{color:#ddd;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;color:#2f2f2f;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;color:#2f2f2f;}.stab.portability>code{color:#ddd;}#help>div{background:#4d4d4d;border-color:#bfbfbf;}#help>div>span{border-bottom-color:#bfbfbf;}#help dt{border-color:#bfbfbf;background:rgba(0,0,0,0);color:black;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#ddd;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background-color:#494a3d;border-right:3px solid #bb7410;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.8);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.8);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.8);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.8);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip::after{background-color:#000;color:#fff;border-color:#000;}.tooltip::before{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#111;border-color:#777;}#titles>button:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>button:hover,#titles>button.selected{border-top-color:#0089ff;background-color:#353535;}#titles>button>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#505050;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#505050;border-right-color:#000;}#sidebar-filler{background-color:#505050;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#e0e0e0;background:#f0f0f0;color:#000;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#ffb900;}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}@media (max-width:700px){#theme-picker{background:#f0f0f0;}}#all-types{background-color:#505050;}#all-types:hover{background-color:#606060;}.search-results td span.alias{color:#fff;}.search-results td span.grey{color:#ccc;}#sidebar-toggle{background-color:#565656;}#sidebar-toggle:hover{background-color:#676767;}#source-sidebar{background-color:#565656;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#444;}div.files>.selected{background-color:#333;}.setting-line>.title{border-bottom-color:#ddd;} \ No newline at end of file +body{background-color:#353535;color:#ddd;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:#ddd;}h1.fqn{border-bottom-color:#d2d2d2;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#d2d2d2;}.in-band{background-color:#353535;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#2A2A2A;}pre{background-color:#2A2A2A;}.sidebar{background-color:#505050;}.logo-container.rust-logo>img{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)}*{scrollbar-color:rgb(64,65,67) #717171;}.sidebar{scrollbar-color:rgba(32,34,37,.6) transparent;}::-webkit-scrollbar-track{background-color:#717171;}::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar::-webkit-scrollbar-track{background-color:#717171;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar .current{background-color:#333;}.source .sidebar{background-color:#353535;}.sidebar .location{border-color:#fff;background:#575757;color:#DDD;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#444;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#DDD;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#ddd;}.content .highlighted{color:#eee !important;background-color:#616161;}.content .highlighted a,.content .highlighted span{color:#eee !important;}.content .highlighted.trait{background-color:#013191;}.content .highlighted.traitalias{background-color:#013191;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.mod{background-color:#803a1b;}.content .highlighted.externcrate{background-color:#396bac;}.content .highlighted.enum{background-color:#5b4e68;}.content .highlighted.struct{background-color:#194e9f;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#4950ed;}.content .highlighted.type{background-color:#38902c;}.content .highlighted.foreigntype{background-color:#b200d6;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#217d1c;}.content .highlighted.constant,.content .highlighted.static{background-color:#0063cc;}.content .highlighted.primitive{background-color:#00708a;}.content .highlighted.keyword{background-color:#884719;}.content .item-info::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#82b089;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#ff7f00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#dd7de8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#a6ae37;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#82a5c9;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#43aec7;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#bda000;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b397da;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav:not(.sidebar){border-bottom-color:#4e4e4e;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#ddd;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.item-info a,#help a{color:#D2991D;}a.test-arrow{color:#dedede;}.collapse-toggle{color:#999;}#crate-search{color:#111;background-color:#f0f0f0;border-color:#000;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input{color:#111;background-color:#f0f0f0;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input:focus{border-color:#008dfd;}.search-focus:disabled{background-color:#c5c4c4;}#crate-search+.search-input:focus{box-shadow:0 0 8px 4px #078dd8;}.module-item .stab{color:#ddd;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;color:#2f2f2f;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;color:#2f2f2f;}.stab.portability>code{background:none;}#help>div{background:#4d4d4d;border-color:#bfbfbf;}#help>div>span{border-bottom-color:#bfbfbf;}#help dt{border-color:#bfbfbf;background:rgba(0,0,0,0);}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#ddd;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background-color:#494a3d;border-right:3px solid #bb7410;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.8);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.8);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.8);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.8);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip::after{background-color:#000;color:#fff;border-color:#000;}.tooltip::before{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#111;border-color:#777;}#titles>button:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>button:hover,#titles>button.selected{border-top-color:#0089ff;background-color:#353535;}#titles>button>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#505050;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#505050;border-right-color:#000;}#sidebar-filler{background-color:#505050;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#e0e0e0;background:#f0f0f0;color:#000;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#ffb900;}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}@media (max-width:700px){#theme-picker{background:#f0f0f0;}}#all-types{background-color:#505050;}#all-types:hover{background-color:#606060;}.search-results td span.alias{color:#fff;}.search-results td span.grey{color:#ccc;}#sidebar-toggle{background-color:#565656;}#sidebar-toggle:hover{background-color:#676767;}#source-sidebar{background-color:#565656;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#444;}div.files>.selected{background-color:#333;}.setting-line>.title{border-bottom-color:#ddd;} \ No newline at end of file diff --git a/implementors/actix/actor/trait.Actor.js b/implementors/actix/actor/trait.Actor.js index 2c8d8bc5f..b4c3f9029 100644 --- a/implementors/actix/actor/trait.Actor.js +++ b/implementors/actix/actor/trait.Actor.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Actor for RedisActor","synthetic":false,"types":[]}]; +implementors["actix_redis"] = [{"text":"impl Actor for RedisActor","synthetic":false,"types":["actix_redis::redis::RedisActor"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix/actor/trait.Supervised.js b/implementors/actix/actor/trait.Supervised.js index 596db6c71..95c02710f 100644 --- a/implementors/actix/actor/trait.Supervised.js +++ b/implementors/actix/actor/trait.Supervised.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Supervised for RedisActor","synthetic":false,"types":[]}]; +implementors["actix_redis"] = [{"text":"impl Supervised for RedisActor","synthetic":false,"types":["actix_redis::redis::RedisActor"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix/handler/trait.Handler.js b/implementors/actix/handler/trait.Handler.js index a8ef349f4..346312f89 100644 --- a/implementors/actix/handler/trait.Handler.js +++ b/implementors/actix/handler/trait.Handler.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Handler<Command> for RedisActor","synthetic":false,"types":[]}]; +implementors["actix_redis"] = [{"text":"impl Handler<Command> for RedisActor","synthetic":false,"types":["actix_redis::redis::RedisActor"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix/handler/trait.Message.js b/implementors/actix/handler/trait.Message.js index 8715db074..3452fecee 100644 --- a/implementors/actix/handler/trait.Message.js +++ b/implementors/actix/handler/trait.Message.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Message for Command","synthetic":false,"types":[]}]; +implementors["actix_redis"] = [{"text":"impl Message for Command","synthetic":false,"types":["actix_redis::redis::Command"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix/io/trait.WriteHandler.js b/implementors/actix/io/trait.WriteHandler.js index 7fb22707f..7269818df 100644 --- a/implementors/actix/io/trait.WriteHandler.js +++ b/implementors/actix/io/trait.WriteHandler.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl WriteHandler<Error> for RedisActor","synthetic":false,"types":[]}]; +implementors["actix_redis"] = [{"text":"impl WriteHandler<Error> for RedisActor","synthetic":false,"types":["actix_redis::redis::RedisActor"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix/stream/trait.StreamHandler.js b/implementors/actix/stream/trait.StreamHandler.js index b9efd888f..d3c529c1e 100644 --- a/implementors/actix/stream/trait.StreamHandler.js +++ b/implementors/actix/stream/trait.StreamHandler.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl StreamHandler<Result<RespValue, Error>> for RedisActor","synthetic":false,"types":[]}]; +implementors["actix_redis"] = [{"text":"impl StreamHandler<Result<RespValue, Error>> for RedisActor","synthetic":false,"types":["actix_redis::redis::RedisActor"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_http/error/trait.ResponseError.js b/implementors/actix_http/error/trait.ResponseError.js index ce9c557c0..14e1a9ca3 100644 --- a/implementors/actix_http/error/trait.ResponseError.js +++ b/implementors/actix_http/error/trait.ResponseError.js @@ -1,3 +1,6 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl ResponseError for Error","synthetic":false,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl ResponseError for CorsError","synthetic":false,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_protobuf"] = [{"text":"impl ResponseError for ProtoBufPayloadError","synthetic":false,"types":["actix_protobuf::ProtoBufPayloadError"]}]; +implementors["actix_redis"] = [{"text":"impl ResponseError for Error","synthetic":false,"types":["actix_redis::Error"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl<C: 'static + Challenge> ResponseError for AuthenticationError<C>","synthetic":false,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_http/header/into_value/trait.IntoHeaderValue.js b/implementors/actix_http/header/into_value/trait.IntoHeaderValue.js new file mode 100644 index 000000000..e87ac8002 --- /dev/null +++ b/implementors/actix_http/header/into_value/trait.IntoHeaderValue.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl<S: Scheme> IntoHeaderValue for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl IntoHeaderValue for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl IntoHeaderValue for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl IntoHeaderValue for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl IntoHeaderValue for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl<C: Challenge> IntoHeaderValue for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_http/header/trait.Header.js b/implementors/actix_http/header/trait.Header.js new file mode 100644 index 000000000..0e9d23dbb --- /dev/null +++ b/implementors/actix_http/header/trait.Header.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl<S: Scheme> Header for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl<C: Challenge> Header for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_identity/trait.IdentityPolicy.js b/implementors/actix_identity/trait.IdentityPolicy.js new file mode 100644 index 000000000..61f047b35 --- /dev/null +++ b/implementors/actix_identity/trait.IdentityPolicy.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_identity"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_identity/trait.RequestIdentity.js b/implementors/actix_identity/trait.RequestIdentity.js new file mode 100644 index 000000000..61f047b35 --- /dev/null +++ b/implementors/actix_identity/trait.RequestIdentity.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_identity"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_protobuf/trait.ProtoBufResponseBuilder.js b/implementors/actix_protobuf/trait.ProtoBufResponseBuilder.js new file mode 100644 index 000000000..51f92b40a --- /dev/null +++ b/implementors/actix_protobuf/trait.ProtoBufResponseBuilder.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_protobuf"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_service/transform/trait.Transform.js b/implementors/actix_service/transform/trait.Transform.js index b238c1210..6e0be361a 100644 --- a/implementors/actix_service/transform/trait.Transform.js +++ b/implementors/actix_service/transform/trait.Transform.js @@ -1,3 +1,7 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl<S, B> Transform<S, ServiceRequest> for RedisSession where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    B: 'static, 
","synthetic":false,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl<S, B> Transform<S, ServiceRequest> for Cors where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static, 
","synthetic":false,"types":["actix_cors::builder::Cors"]}]; +implementors["actix_identity"] = [{"text":"impl<S, T, B> Transform<S, ServiceRequest> for IdentityService<T> where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    T: IdentityPolicy,
    B: 'static, 
","synthetic":false,"types":["actix_identity::IdentityService"]}]; +implementors["actix_redis"] = [{"text":"impl<S, B> Transform<S, ServiceRequest> for RedisSession where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    B: 'static, 
","synthetic":false,"types":["actix_redis::session::RedisSession"]}]; +implementors["actix_session"] = [{"text":"impl<S, B: 'static> Transform<S, ServiceRequest> for CookieSession where
    S: Service<ServiceRequest, Response = ServiceResponse<B>>,
    S::Future: 'static,
    S::Error: 'static, 
","synthetic":false,"types":["actix_session::cookie::CookieSession"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl<S, B, T, F, O> Transform<S, ServiceRequest> for HttpAuthentication<T, F> where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    F: Fn(ServiceRequest, T) -> O + 'static,
    O: Future<Output = Result<ServiceRequest, Error>> + 'static,
    T: AuthExtractor + 'static, 
","synthetic":false,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_session/trait.UserSession.js b/implementors/actix_session/trait.UserSession.js new file mode 100644 index 000000000..035242606 --- /dev/null +++ b/implementors/actix_session/trait.UserSession.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_session"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_web/extract/trait.FromRequest.js b/implementors/actix_web/extract/trait.FromRequest.js new file mode 100644 index 000000000..23c8e9fb5 --- /dev/null +++ b/implementors/actix_web/extract/trait.FromRequest.js @@ -0,0 +1,6 @@ +(function() {var implementors = {}; +implementors["actix_identity"] = [{"text":"impl FromRequest for Identity","synthetic":false,"types":["actix_identity::Identity"]}]; +implementors["actix_protobuf"] = [{"text":"impl<T> FromRequest for ProtoBuf<T> where
    T: Message + Default + 'static, 
","synthetic":false,"types":["actix_protobuf::ProtoBuf"]}]; +implementors["actix_session"] = [{"text":"impl FromRequest for Session","synthetic":false,"types":["actix_session::Session"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl FromRequest for BasicAuth","synthetic":false,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl FromRequest for BearerAuth","synthetic":false,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_web/responder/trait.Responder.js b/implementors/actix_web/responder/trait.Responder.js new file mode 100644 index 000000000..9132f60ab --- /dev/null +++ b/implementors/actix_web/responder/trait.Responder.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_protobuf"] = [{"text":"impl<T: Message + Default> Responder for ProtoBuf<T>","synthetic":false,"types":["actix_protobuf::ProtoBuf"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_web_httpauth/extractors/trait.AuthExtractor.js b/implementors/actix_web_httpauth/extractors/trait.AuthExtractor.js new file mode 100644 index 000000000..558cda4bf --- /dev/null +++ b/implementors/actix_web_httpauth/extractors/trait.AuthExtractor.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_web_httpauth/extractors/trait.AuthExtractorConfig.js b/implementors/actix_web_httpauth/extractors/trait.AuthExtractorConfig.js new file mode 100644 index 000000000..558cda4bf --- /dev/null +++ b/implementors/actix_web_httpauth/extractors/trait.AuthExtractorConfig.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/actix_web_httpauth/headers/authorization/trait.Scheme.js b/implementors/actix_web_httpauth/headers/authorization/trait.Scheme.js new file mode 100644 index 000000000..558cda4bf --- /dev/null +++ b/implementors/actix_web_httpauth/headers/authorization/trait.Scheme.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ 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 000000000..22cd79f42 --- /dev/null +++ b/implementors/core/clone/trait.Clone.js @@ -0,0 +1,7 @@ +(function() {var implementors = {}; +implementors["actix_cors"] = [{"text":"impl Clone for CorsError","synthetic":false,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_identity"] = [{"text":"impl Clone for Identity","synthetic":false,"types":["actix_identity::Identity"]}]; +implementors["actix_session"] = [{"text":"impl Clone for SessionStatus","synthetic":false,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl Clone for Config","synthetic":false,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl Clone for BasicAuth","synthetic":false,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl Clone for Config","synthetic":false,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl Clone for BearerAuth","synthetic":false,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]},{"text":"impl<S: Clone + Scheme> Clone for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Clone for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Clone for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Clone for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Clone for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl Clone for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: Clone + Challenge> Clone for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]},{"text":"impl<T: Clone, F: Clone> Clone for HttpAuthentication<T, F> where
    T: AuthExtractor
","synthetic":false,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; +implementors["prost_example"] = [{"text":"impl Clone for MyObj","synthetic":false,"types":["prost_example::MyObj"]}]; +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 000000000..76402dd9c --- /dev/null +++ b/implementors/core/cmp/trait.Eq.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl<S: Eq + Scheme> Eq for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Eq for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Eq for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Eq for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Eq for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl Eq for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: Eq + Challenge> Eq for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +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.Ord.js b/implementors/core/cmp/trait.Ord.js new file mode 100644 index 000000000..3ff3d932b --- /dev/null +++ b/implementors/core/cmp/trait.Ord.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl<S: Ord + Scheme> Ord for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Ord for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Ord for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Ord for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Ord for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl Ord for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: Ord + Challenge> Ord for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +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 000000000..ae49bb3c3 --- /dev/null +++ b/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["actix_session"] = [{"text":"impl PartialEq<SessionStatus> for SessionStatus","synthetic":false,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl<S: PartialEq + Scheme> PartialEq<Authorization<S>> for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl PartialEq<Basic> for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl PartialEq<Bearer> for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl PartialEq<Basic> for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl PartialEq<Bearer> for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl PartialEq<Error> for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: PartialEq + Challenge> PartialEq<WwwAuthenticate<C>> for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +implementors["prost_example"] = [{"text":"impl PartialEq<MyObj> for MyObj","synthetic":false,"types":["prost_example::MyObj"]}]; +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.PartialOrd.js b/implementors/core/cmp/trait.PartialOrd.js new file mode 100644 index 000000000..e6ada2f3d --- /dev/null +++ b/implementors/core/cmp/trait.PartialOrd.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl<S: PartialOrd + Scheme> PartialOrd<Authorization<S>> for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl PartialOrd<Basic> for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl PartialOrd<Bearer> for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl PartialOrd<Basic> for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl PartialOrd<Bearer> for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl PartialOrd<Error> for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: PartialOrd + Challenge> PartialOrd<WwwAuthenticate<C>> for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +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 000000000..5f51175a4 --- /dev/null +++ b/implementors/core/convert/trait.AsMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl<S> AsMut<S> for Authorization<S> where
    S: Scheme
","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]}]; +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 000000000..23b7d36b9 --- /dev/null +++ b/implementors/core/convert/trait.AsRef.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl AsRef<Basic> for Config","synthetic":false,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl AsRef<Bearer> for Config","synthetic":false,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl<S> AsRef<S> for Authorization<S> where
    S: Scheme
","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]}]; +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 index 5414804e3..fdfe580b0 100644 --- a/implementors/core/convert/trait.From.js +++ b/implementors/core/convert/trait.From.js @@ -1,3 +1,5 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl From<Error> for Error","synthetic":false,"types":[]}]; +implementors["actix_protobuf"] = [{"text":"impl From<PayloadError> for ProtoBufPayloadError","synthetic":false,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl From<DecodeError> for ProtoBufPayloadError","synthetic":false,"types":["actix_protobuf::ProtoBufPayloadError"]}]; +implementors["actix_redis"] = [{"text":"impl From<Error> for Error","synthetic":false,"types":["actix_redis::Error"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl<T> From<T> for AuthenticationError<<T as AuthExtractorConfig>::Inner> where
    T: AuthExtractorConfig
","synthetic":false,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl From<ToStrError> for ParseError","synthetic":false,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl From<DecodeError> for ParseError","synthetic":false,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl From<Utf8Error> for ParseError","synthetic":false,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S> From<S> for Authorization<S> where
    S: Scheme
","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]}]; 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 000000000..9ccc8eda3 --- /dev/null +++ b/implementors/core/default/trait.Default.js @@ -0,0 +1,7 @@ +(function() {var implementors = {}; +implementors["actix_cors"] = [{"text":"impl Default for Cors","synthetic":false,"types":["actix_cors::builder::Cors"]}]; +implementors["actix_protobuf"] = [{"text":"impl Default for ProtoBufConfig","synthetic":false,"types":["actix_protobuf::ProtoBufConfig"]}]; +implementors["actix_session"] = [{"text":"impl Default for SessionStatus","synthetic":false,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl Default for Config","synthetic":false,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl Default for Config","synthetic":false,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl<S: Default + Scheme> Default for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Default for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Default for BearerBuilder","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::builder::BearerBuilder"]},{"text":"impl Default for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl<C: Default + Challenge> Default for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +implementors["prost_example"] = [{"text":"impl Default for MyObj","synthetic":false,"types":["prost_example::MyObj"]}]; +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 index 0033b62df..17c3a769e 100644 --- a/implementors/core/fmt/trait.Debug.js +++ b/implementors/core/fmt/trait.Debug.js @@ -1,3 +1,8 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Debug for Command","synthetic":false,"types":[]},{"text":"impl Debug for Error","synthetic":false,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl Debug for Cors","synthetic":false,"types":["actix_cors::builder::Cors"]},{"text":"impl Debug for CorsError","synthetic":false,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_protobuf"] = [{"text":"impl Debug for ProtoBufPayloadError","synthetic":false,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl<T: Message> Debug for ProtoBuf<T> where
    T: Debug
","synthetic":false,"types":["actix_protobuf::ProtoBuf"]}]; +implementors["actix_redis"] = [{"text":"impl Debug for Command","synthetic":false,"types":["actix_redis::redis::Command"]},{"text":"impl Debug for Error","synthetic":false,"types":["actix_redis::Error"]}]; +implementors["actix_session"] = [{"text":"impl Debug for SessionStatus","synthetic":false,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl Debug for Config","synthetic":false,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl Debug for BasicAuth","synthetic":false,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl Debug for Config","synthetic":false,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl Debug for BearerAuth","synthetic":false,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]},{"text":"impl<C: Debug + Challenge> Debug for AuthenticationError<C>","synthetic":false,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl Debug for ParseError","synthetic":false,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S: Debug + Scheme> Debug for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Debug for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Debug for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Debug for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Debug for BearerBuilder","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::builder::BearerBuilder"]},{"text":"impl Debug for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl Debug for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: Debug + Challenge> Debug for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]},{"text":"impl<T: Debug, F: Debug> Debug for HttpAuthentication<T, F> where
    T: AuthExtractor
","synthetic":false,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; +implementors["prost_example"] = [{"text":"impl Debug for MyObj","synthetic":false,"types":["prost_example::MyObj"]}]; 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 index 652c84762..98da6c9ff 100644 --- a/implementors/core/fmt/trait.Display.js +++ b/implementors/core/fmt/trait.Display.js @@ -1,3 +1,6 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Display for Error","synthetic":false,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl Display for CorsError","synthetic":false,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_protobuf"] = [{"text":"impl Display for ProtoBufPayloadError","synthetic":false,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl<T: Message> Display for ProtoBuf<T> where
    T: Display
","synthetic":false,"types":["actix_protobuf::ProtoBuf"]}]; +implementors["actix_redis"] = [{"text":"impl Display for Error","synthetic":false,"types":["actix_redis::Error"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl<C: Challenge> Display for AuthenticationError<C>","synthetic":false,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl Display for ParseError","synthetic":false,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S: Scheme> Display for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Display for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Display for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Display for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Display for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl Display for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/future/future/trait.Future.js b/implementors/core/future/future/trait.Future.js new file mode 100644 index 000000000..3fc3c810e --- /dev/null +++ b/implementors/core/future/future/trait.Future.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_protobuf"] = [{"text":"impl<T: Message + Default + 'static> Future for ProtoBufMessage<T>","synthetic":false,"types":["actix_protobuf::ProtoBufMessage"]}]; +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 000000000..75ab7620d --- /dev/null +++ b/implementors/core/hash/trait.Hash.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl<S: Hash + Scheme> Hash for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Hash for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Hash for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl Hash for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: Hash + Challenge> Hash for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +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 000000000..4745aaf6b --- /dev/null +++ b/implementors/core/marker/trait.Copy.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl Copy for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]}]; +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 index 5c01075a3..d6fcb4af1 100644 --- a/implementors/core/marker/trait.Freeze.js +++ b/implementors/core/marker/trait.Freeze.js @@ -1,3 +1,9 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Freeze for Command","synthetic":true,"types":[]},{"text":"impl Freeze for RedisActor","synthetic":true,"types":[]},{"text":"impl Freeze for RedisSession","synthetic":true,"types":[]},{"text":"impl Freeze for Error","synthetic":true,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl Freeze for Cors","synthetic":true,"types":["actix_cors::builder::Cors"]},{"text":"impl Freeze for CorsError","synthetic":true,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_identity"] = [{"text":"impl Freeze for Identity","synthetic":true,"types":["actix_identity::Identity"]},{"text":"impl<T> Freeze for IdentityService<T>","synthetic":true,"types":["actix_identity::IdentityService"]},{"text":"impl Freeze for CookieIdentityPolicy","synthetic":true,"types":["actix_identity::CookieIdentityPolicy"]}]; +implementors["actix_protobuf"] = [{"text":"impl Freeze for ProtoBufPayloadError","synthetic":true,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl<T> Freeze for ProtoBuf<T> where
    T: Freeze, 
","synthetic":true,"types":["actix_protobuf::ProtoBuf"]},{"text":"impl Freeze for ProtoBufConfig","synthetic":true,"types":["actix_protobuf::ProtoBufConfig"]},{"text":"impl<T> Freeze for ProtoBufMessage<T>","synthetic":true,"types":["actix_protobuf::ProtoBufMessage"]}]; +implementors["actix_redis"] = [{"text":"impl Freeze for Command","synthetic":true,"types":["actix_redis::redis::Command"]},{"text":"impl Freeze for RedisActor","synthetic":true,"types":["actix_redis::redis::RedisActor"]},{"text":"impl Freeze for RedisSession","synthetic":true,"types":["actix_redis::session::RedisSession"]},{"text":"impl Freeze for Error","synthetic":true,"types":["actix_redis::Error"]}]; +implementors["actix_session"] = [{"text":"impl Freeze for CookieSession","synthetic":true,"types":["actix_session::cookie::CookieSession"]},{"text":"impl Freeze for Session","synthetic":true,"types":["actix_session::Session"]},{"text":"impl Freeze for SessionStatus","synthetic":true,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl Freeze for Config","synthetic":true,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl Freeze for BasicAuth","synthetic":true,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl Freeze for Error","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl Freeze for Config","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl Freeze for BearerAuth","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]},{"text":"impl<C> Freeze for AuthenticationError<C> where
    C: Freeze, 
","synthetic":true,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl Freeze for ParseError","synthetic":true,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S> Freeze for Authorization<S> where
    S: Freeze, 
","synthetic":true,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Freeze for Basic","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Freeze for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Freeze for Basic","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Freeze for BearerBuilder","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::builder::BearerBuilder"]},{"text":"impl Freeze for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl<C> Freeze for WwwAuthenticate<C> where
    C: Freeze, 
","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]},{"text":"impl<T, F> Freeze for HttpAuthentication<T, F>","synthetic":true,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; +implementors["prost_example"] = [{"text":"impl Freeze for MyObj","synthetic":true,"types":["prost_example::MyObj"]}]; 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 index a6445a3ae..3e973c8e7 100644 --- a/implementors/core/marker/trait.Send.js +++ b/implementors/core/marker/trait.Send.js @@ -1,3 +1,9 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Send for Command","synthetic":true,"types":[]},{"text":"impl !Send for RedisActor","synthetic":true,"types":[]},{"text":"impl !Send for RedisSession","synthetic":true,"types":[]},{"text":"impl Send for Error","synthetic":true,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl !Send for Cors","synthetic":true,"types":["actix_cors::builder::Cors"]},{"text":"impl Send for CorsError","synthetic":true,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_identity"] = [{"text":"impl !Send for Identity","synthetic":true,"types":["actix_identity::Identity"]},{"text":"impl<T> !Send for IdentityService<T>","synthetic":true,"types":["actix_identity::IdentityService"]},{"text":"impl !Send for CookieIdentityPolicy","synthetic":true,"types":["actix_identity::CookieIdentityPolicy"]}]; +implementors["actix_protobuf"] = [{"text":"impl Send for ProtoBufPayloadError","synthetic":true,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl<T> Send for ProtoBuf<T>","synthetic":true,"types":["actix_protobuf::ProtoBuf"]},{"text":"impl Send for ProtoBufConfig","synthetic":true,"types":["actix_protobuf::ProtoBufConfig"]},{"text":"impl<T> !Send for ProtoBufMessage<T>","synthetic":true,"types":["actix_protobuf::ProtoBufMessage"]}]; +implementors["actix_redis"] = [{"text":"impl Send for Command","synthetic":true,"types":["actix_redis::redis::Command"]},{"text":"impl !Send for RedisActor","synthetic":true,"types":["actix_redis::redis::RedisActor"]},{"text":"impl !Send for RedisSession","synthetic":true,"types":["actix_redis::session::RedisSession"]},{"text":"impl Send for Error","synthetic":true,"types":["actix_redis::Error"]}]; +implementors["actix_session"] = [{"text":"impl !Send for CookieSession","synthetic":true,"types":["actix_session::cookie::CookieSession"]},{"text":"impl !Send for Session","synthetic":true,"types":["actix_session::Session"]},{"text":"impl Send for SessionStatus","synthetic":true,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl Send for Config","synthetic":true,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl Send for BasicAuth","synthetic":true,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl Send for Error","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl Send for Config","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl Send for BearerAuth","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]},{"text":"impl<C> Send for AuthenticationError<C>","synthetic":true,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl Send for ParseError","synthetic":true,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S> Send for Authorization<S>","synthetic":true,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Send for Basic","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Send for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Send for Basic","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Send for BearerBuilder","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::builder::BearerBuilder"]},{"text":"impl Send for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl<C> Send for WwwAuthenticate<C>","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]},{"text":"impl<T, F> Send for HttpAuthentication<T, F> where
    F: Send + Sync,
    T: Send
","synthetic":true,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; +implementors["prost_example"] = [{"text":"impl Send for MyObj","synthetic":true,"types":["prost_example::MyObj"]}]; 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 000000000..d8ad32cc5 --- /dev/null +++ b/implementors/core/marker/trait.StructuralEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_web_httpauth"] = [{"text":"impl<S: Scheme> StructuralEq for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl StructuralEq for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl StructuralEq for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl StructuralEq for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl StructuralEq for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl StructuralEq for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: Challenge> StructuralEq for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +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 000000000..e997f2eef --- /dev/null +++ b/implementors/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["actix_session"] = [{"text":"impl StructuralPartialEq for SessionStatus","synthetic":false,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl<S: Scheme> StructuralPartialEq for Authorization<S>","synthetic":false,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl StructuralPartialEq for Basic","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl StructuralPartialEq for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl StructuralPartialEq for Basic","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl StructuralPartialEq for Bearer","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl StructuralPartialEq for Error","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl<C: Challenge> StructuralPartialEq for WwwAuthenticate<C>","synthetic":false,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]}]; +implementors["prost_example"] = [{"text":"impl StructuralPartialEq for MyObj","synthetic":false,"types":["prost_example::MyObj"]}]; +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 index 6dff08f70..04ddf5612 100644 --- a/implementors/core/marker/trait.Sync.js +++ b/implementors/core/marker/trait.Sync.js @@ -1,3 +1,9 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Sync for Command","synthetic":true,"types":[]},{"text":"impl !Sync for RedisActor","synthetic":true,"types":[]},{"text":"impl !Sync for RedisSession","synthetic":true,"types":[]},{"text":"impl Sync for Error","synthetic":true,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl !Sync for Cors","synthetic":true,"types":["actix_cors::builder::Cors"]},{"text":"impl Sync for CorsError","synthetic":true,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_identity"] = [{"text":"impl !Sync for Identity","synthetic":true,"types":["actix_identity::Identity"]},{"text":"impl<T> !Sync for IdentityService<T>","synthetic":true,"types":["actix_identity::IdentityService"]},{"text":"impl !Sync for CookieIdentityPolicy","synthetic":true,"types":["actix_identity::CookieIdentityPolicy"]}]; +implementors["actix_protobuf"] = [{"text":"impl Sync for ProtoBufPayloadError","synthetic":true,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl<T> Sync for ProtoBuf<T>","synthetic":true,"types":["actix_protobuf::ProtoBuf"]},{"text":"impl Sync for ProtoBufConfig","synthetic":true,"types":["actix_protobuf::ProtoBufConfig"]},{"text":"impl<T> !Sync for ProtoBufMessage<T>","synthetic":true,"types":["actix_protobuf::ProtoBufMessage"]}]; +implementors["actix_redis"] = [{"text":"impl Sync for Command","synthetic":true,"types":["actix_redis::redis::Command"]},{"text":"impl !Sync for RedisActor","synthetic":true,"types":["actix_redis::redis::RedisActor"]},{"text":"impl !Sync for RedisSession","synthetic":true,"types":["actix_redis::session::RedisSession"]},{"text":"impl Sync for Error","synthetic":true,"types":["actix_redis::Error"]}]; +implementors["actix_session"] = [{"text":"impl !Sync for CookieSession","synthetic":true,"types":["actix_session::cookie::CookieSession"]},{"text":"impl !Sync for Session","synthetic":true,"types":["actix_session::Session"]},{"text":"impl Sync for SessionStatus","synthetic":true,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl Sync for Config","synthetic":true,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl Sync for BasicAuth","synthetic":true,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl Sync for Error","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl Sync for Config","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl Sync for BearerAuth","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]},{"text":"impl<C> Sync for AuthenticationError<C>","synthetic":true,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl Sync for ParseError","synthetic":true,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S> Sync for Authorization<S>","synthetic":true,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Sync for Basic","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Sync for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Sync for Basic","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Sync for BearerBuilder","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::builder::BearerBuilder"]},{"text":"impl Sync for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl<C> Sync for WwwAuthenticate<C>","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]},{"text":"impl<T, F> Sync for HttpAuthentication<T, F> where
    F: Send + Sync,
    T: Sync
","synthetic":true,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; +implementors["prost_example"] = [{"text":"impl Sync for MyObj","synthetic":true,"types":["prost_example::MyObj"]}]; 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 index 470cbc1ba..548159339 100644 --- a/implementors/core/marker/trait.Unpin.js +++ b/implementors/core/marker/trait.Unpin.js @@ -1,3 +1,9 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Unpin for Command","synthetic":true,"types":[]},{"text":"impl Unpin for RedisActor","synthetic":true,"types":[]},{"text":"impl Unpin for RedisSession","synthetic":true,"types":[]},{"text":"impl Unpin for Error","synthetic":true,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl Unpin for Cors","synthetic":true,"types":["actix_cors::builder::Cors"]},{"text":"impl Unpin for CorsError","synthetic":true,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_identity"] = [{"text":"impl Unpin for Identity","synthetic":true,"types":["actix_identity::Identity"]},{"text":"impl<T> Unpin for IdentityService<T>","synthetic":true,"types":["actix_identity::IdentityService"]},{"text":"impl Unpin for CookieIdentityPolicy","synthetic":true,"types":["actix_identity::CookieIdentityPolicy"]}]; +implementors["actix_protobuf"] = [{"text":"impl Unpin for ProtoBufPayloadError","synthetic":true,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl<T> Unpin for ProtoBuf<T> where
    T: Unpin
","synthetic":true,"types":["actix_protobuf::ProtoBuf"]},{"text":"impl Unpin for ProtoBufConfig","synthetic":true,"types":["actix_protobuf::ProtoBufConfig"]},{"text":"impl<T> Unpin for ProtoBufMessage<T>","synthetic":true,"types":["actix_protobuf::ProtoBufMessage"]}]; +implementors["actix_redis"] = [{"text":"impl Unpin for Command","synthetic":true,"types":["actix_redis::redis::Command"]},{"text":"impl Unpin for RedisActor","synthetic":true,"types":["actix_redis::redis::RedisActor"]},{"text":"impl Unpin for RedisSession","synthetic":true,"types":["actix_redis::session::RedisSession"]},{"text":"impl Unpin for Error","synthetic":true,"types":["actix_redis::Error"]}]; +implementors["actix_session"] = [{"text":"impl Unpin for CookieSession","synthetic":true,"types":["actix_session::cookie::CookieSession"]},{"text":"impl Unpin for Session","synthetic":true,"types":["actix_session::Session"]},{"text":"impl Unpin for SessionStatus","synthetic":true,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl Unpin for Config","synthetic":true,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl Unpin for BasicAuth","synthetic":true,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl Unpin for Error","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl Unpin for Config","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl Unpin for BearerAuth","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]},{"text":"impl<C> Unpin for AuthenticationError<C> where
    C: Unpin
","synthetic":true,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl Unpin for ParseError","synthetic":true,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S> Unpin for Authorization<S> where
    S: Unpin
","synthetic":true,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl Unpin for Basic","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl Unpin for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl Unpin for Basic","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl Unpin for BearerBuilder","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::builder::BearerBuilder"]},{"text":"impl Unpin for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl<C> Unpin for WwwAuthenticate<C> where
    C: Unpin
","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]},{"text":"impl<T, F> Unpin for HttpAuthentication<T, F> where
    T: Unpin
","synthetic":true,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; +implementors["prost_example"] = [{"text":"impl Unpin for MyObj","synthetic":true,"types":["prost_example::MyObj"]}]; 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 000000000..25a04a10f --- /dev/null +++ b/implementors/core/ops/deref/trait.Deref.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_protobuf"] = [{"text":"impl<T: Message> Deref for ProtoBuf<T>","synthetic":false,"types":["actix_protobuf::ProtoBuf"]}]; +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.DerefMut.js b/implementors/core/ops/deref/trait.DerefMut.js new file mode 100644 index 000000000..efd2b0100 --- /dev/null +++ b/implementors/core/ops/deref/trait.DerefMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["actix_protobuf"] = [{"text":"impl<T: Message> DerefMut for ProtoBuf<T>","synthetic":false,"types":["actix_protobuf::ProtoBuf"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/prost/message/trait.Message.js b/implementors/prost/message/trait.Message.js new file mode 100644 index 000000000..008a88697 --- /dev/null +++ b/implementors/prost/message/trait.Message.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["prost_example"] = [{"text":"impl Message for MyObj","synthetic":false,"types":["prost_example::MyObj"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/error/trait.Error.js b/implementors/std/error/trait.Error.js index 5054ae4f9..46b04da50 100644 --- a/implementors/std/error/trait.Error.js +++ b/implementors/std/error/trait.Error.js @@ -1,3 +1,5 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl Error for Error","synthetic":false,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl Error for CorsError","synthetic":false,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_redis"] = [{"text":"impl Error for Error","synthetic":false,"types":["actix_redis::Error"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl<C: 'static + Challenge> Error for AuthenticationError<C>","synthetic":false,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl Error for ParseError","synthetic":false,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/panic/trait.RefUnwindSafe.js b/implementors/std/panic/trait.RefUnwindSafe.js index 2a58818a8..03a82ab02 100644 --- a/implementors/std/panic/trait.RefUnwindSafe.js +++ b/implementors/std/panic/trait.RefUnwindSafe.js @@ -1,3 +1,9 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl RefUnwindSafe for Command","synthetic":true,"types":[]},{"text":"impl !RefUnwindSafe for RedisActor","synthetic":true,"types":[]},{"text":"impl !RefUnwindSafe for RedisSession","synthetic":true,"types":[]},{"text":"impl !RefUnwindSafe for Error","synthetic":true,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl !RefUnwindSafe for Cors","synthetic":true,"types":["actix_cors::builder::Cors"]},{"text":"impl RefUnwindSafe for CorsError","synthetic":true,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_identity"] = [{"text":"impl !RefUnwindSafe for Identity","synthetic":true,"types":["actix_identity::Identity"]},{"text":"impl<T> !RefUnwindSafe for IdentityService<T>","synthetic":true,"types":["actix_identity::IdentityService"]},{"text":"impl !RefUnwindSafe for CookieIdentityPolicy","synthetic":true,"types":["actix_identity::CookieIdentityPolicy"]}]; +implementors["actix_protobuf"] = [{"text":"impl !RefUnwindSafe for ProtoBufPayloadError","synthetic":true,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl<T> RefUnwindSafe for ProtoBuf<T> where
    T: RefUnwindSafe
","synthetic":true,"types":["actix_protobuf::ProtoBuf"]},{"text":"impl RefUnwindSafe for ProtoBufConfig","synthetic":true,"types":["actix_protobuf::ProtoBufConfig"]},{"text":"impl<T> !RefUnwindSafe for ProtoBufMessage<T>","synthetic":true,"types":["actix_protobuf::ProtoBufMessage"]}]; +implementors["actix_redis"] = [{"text":"impl RefUnwindSafe for Command","synthetic":true,"types":["actix_redis::redis::Command"]},{"text":"impl !RefUnwindSafe for RedisActor","synthetic":true,"types":["actix_redis::redis::RedisActor"]},{"text":"impl !RefUnwindSafe for RedisSession","synthetic":true,"types":["actix_redis::session::RedisSession"]},{"text":"impl !RefUnwindSafe for Error","synthetic":true,"types":["actix_redis::Error"]}]; +implementors["actix_session"] = [{"text":"impl !RefUnwindSafe for CookieSession","synthetic":true,"types":["actix_session::cookie::CookieSession"]},{"text":"impl !RefUnwindSafe for Session","synthetic":true,"types":["actix_session::Session"]},{"text":"impl RefUnwindSafe for SessionStatus","synthetic":true,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl RefUnwindSafe for Config","synthetic":true,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl RefUnwindSafe for BasicAuth","synthetic":true,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl RefUnwindSafe for Error","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl RefUnwindSafe for Config","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl RefUnwindSafe for BearerAuth","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]},{"text":"impl<C> RefUnwindSafe for AuthenticationError<C> where
    C: RefUnwindSafe
","synthetic":true,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl RefUnwindSafe for ParseError","synthetic":true,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S> RefUnwindSafe for Authorization<S> where
    S: RefUnwindSafe
","synthetic":true,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl RefUnwindSafe for Basic","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl RefUnwindSafe for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl RefUnwindSafe for Basic","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl RefUnwindSafe for BearerBuilder","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::builder::BearerBuilder"]},{"text":"impl RefUnwindSafe for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl<C> RefUnwindSafe for WwwAuthenticate<C> where
    C: RefUnwindSafe
","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]},{"text":"impl<T, F> RefUnwindSafe for HttpAuthentication<T, F> where
    F: RefUnwindSafe,
    T: RefUnwindSafe
","synthetic":true,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; +implementors["prost_example"] = [{"text":"impl RefUnwindSafe for MyObj","synthetic":true,"types":["prost_example::MyObj"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/panic/trait.UnwindSafe.js b/implementors/std/panic/trait.UnwindSafe.js index 4d2a32ac8..2edf38f13 100644 --- a/implementors/std/panic/trait.UnwindSafe.js +++ b/implementors/std/panic/trait.UnwindSafe.js @@ -1,3 +1,9 @@ (function() {var implementors = {}; -implementors["actix_redis"] = [{"text":"impl UnwindSafe for Command","synthetic":true,"types":[]},{"text":"impl !UnwindSafe for RedisActor","synthetic":true,"types":[]},{"text":"impl !UnwindSafe for RedisSession","synthetic":true,"types":[]},{"text":"impl !UnwindSafe for Error","synthetic":true,"types":[]}]; +implementors["actix_cors"] = [{"text":"impl !UnwindSafe for Cors","synthetic":true,"types":["actix_cors::builder::Cors"]},{"text":"impl UnwindSafe for CorsError","synthetic":true,"types":["actix_cors::error::CorsError"]}]; +implementors["actix_identity"] = [{"text":"impl !UnwindSafe for Identity","synthetic":true,"types":["actix_identity::Identity"]},{"text":"impl<T> UnwindSafe for IdentityService<T> where
    T: RefUnwindSafe
","synthetic":true,"types":["actix_identity::IdentityService"]},{"text":"impl UnwindSafe for CookieIdentityPolicy","synthetic":true,"types":["actix_identity::CookieIdentityPolicy"]}]; +implementors["actix_protobuf"] = [{"text":"impl !UnwindSafe for ProtoBufPayloadError","synthetic":true,"types":["actix_protobuf::ProtoBufPayloadError"]},{"text":"impl<T> UnwindSafe for ProtoBuf<T> where
    T: UnwindSafe
","synthetic":true,"types":["actix_protobuf::ProtoBuf"]},{"text":"impl UnwindSafe for ProtoBufConfig","synthetic":true,"types":["actix_protobuf::ProtoBufConfig"]},{"text":"impl<T> !UnwindSafe for ProtoBufMessage<T>","synthetic":true,"types":["actix_protobuf::ProtoBufMessage"]}]; +implementors["actix_redis"] = [{"text":"impl UnwindSafe for Command","synthetic":true,"types":["actix_redis::redis::Command"]},{"text":"impl !UnwindSafe for RedisActor","synthetic":true,"types":["actix_redis::redis::RedisActor"]},{"text":"impl !UnwindSafe for RedisSession","synthetic":true,"types":["actix_redis::session::RedisSession"]},{"text":"impl !UnwindSafe for Error","synthetic":true,"types":["actix_redis::Error"]}]; +implementors["actix_session"] = [{"text":"impl UnwindSafe for CookieSession","synthetic":true,"types":["actix_session::cookie::CookieSession"]},{"text":"impl !UnwindSafe for Session","synthetic":true,"types":["actix_session::Session"]},{"text":"impl UnwindSafe for SessionStatus","synthetic":true,"types":["actix_session::SessionStatus"]}]; +implementors["actix_web_httpauth"] = [{"text":"impl UnwindSafe for Config","synthetic":true,"types":["actix_web_httpauth::extractors::basic::Config"]},{"text":"impl UnwindSafe for BasicAuth","synthetic":true,"types":["actix_web_httpauth::extractors::basic::BasicAuth"]},{"text":"impl UnwindSafe for Error","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::errors::Error"]},{"text":"impl UnwindSafe for Config","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::Config"]},{"text":"impl UnwindSafe for BearerAuth","synthetic":true,"types":["actix_web_httpauth::extractors::bearer::BearerAuth"]},{"text":"impl<C> UnwindSafe for AuthenticationError<C> where
    C: UnwindSafe
","synthetic":true,"types":["actix_web_httpauth::extractors::errors::AuthenticationError"]},{"text":"impl UnwindSafe for ParseError","synthetic":true,"types":["actix_web_httpauth::headers::authorization::errors::ParseError"]},{"text":"impl<S> UnwindSafe for Authorization<S> where
    S: UnwindSafe
","synthetic":true,"types":["actix_web_httpauth::headers::authorization::header::Authorization"]},{"text":"impl UnwindSafe for Basic","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::basic::Basic"]},{"text":"impl UnwindSafe for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::authorization::scheme::bearer::Bearer"]},{"text":"impl UnwindSafe for Basic","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::basic::Basic"]},{"text":"impl UnwindSafe for BearerBuilder","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::builder::BearerBuilder"]},{"text":"impl UnwindSafe for Bearer","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::challenge::bearer::challenge::Bearer"]},{"text":"impl<C> UnwindSafe for WwwAuthenticate<C> where
    C: UnwindSafe
","synthetic":true,"types":["actix_web_httpauth::headers::www_authenticate::header::WwwAuthenticate"]},{"text":"impl<T, F> UnwindSafe for HttpAuthentication<T, F> where
    F: RefUnwindSafe,
    T: UnwindSafe
","synthetic":true,"types":["actix_web_httpauth::middleware::HttpAuthentication"]}]; +implementors["prost_example"] = [{"text":"impl UnwindSafe for MyObj","synthetic":true,"types":["prost_example::MyObj"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/index.html b/index.html index 6f1104967..7e402f8f8 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ - + diff --git a/light.css b/light.css index fa73fe223..050c4f296 100644 --- a/light.css +++ b/light.css @@ -1 +1 @@ - body{background-color:white;color:black;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:black;}h1.fqn{border-bottom-color:#D5D5D5;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#DDDDDD;}.in-band{background-color:white;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#F5F5F5;}pre{background-color:#F5F5F5;}.sidebar{background-color:#F1F1F1;}*{scrollbar-color:rgba(36,37,39,0.6) #e6e6e6;}.sidebar{scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;}.logo-container.rust-logo>img{}::-webkit-scrollbar-track{background-color:#ecebeb;}::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar::-webkit-scrollbar-track{background-color:#dcdcdc;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar .current{background-color:#fff;}.source .sidebar{background-color:#fff;}.sidebar .location{border-color:#000;background-color:#fff;color:#333;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#F5F5F5;}.line-numbers span{color:#c67e2d;}.line-numbers .line-highlighted{background-color:#f6fdb0 !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#ddd;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#4E4C4C;}.content .highlighted{color:#000 !important;background-color:#ccc;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted.trait{background-color:#c7b6ff;}.content .highlighted.traitalias{background-color:#c7b6ff;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.enum{background-color:#b4d1b9;}.content .highlighted.struct{background-color:#e7b1a0;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#c6afb3;}.content .highlighted.type{background-color:#ffc891;}.content .highlighted.foreigntype{background-color:#f5c4ff;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#8ce488;}.content .highlighted.constant,.content .highlighted.static{background-color:#c3e0ff;}.content .highlighted.primitive{background-color:#9aecff;}.content .highlighted.keyword{background-color:#f99650;}.content .item-info::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#508157;}.content span.struct,.content a.struct,.block a.current.struct{color:#ad448e;}.content span.type,.content a.type,.block a.current.type{color:#ba5d00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#cd00e2;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#068000;}.content span.union,.content a.union,.block a.current.union{color:#767b27;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#546e8a;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2c8093;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#4d76ae;}.content span.trait,.content a.trait,.block a.current.trait{color:#7c5af3;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#6841f1;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#9a6e31;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8E908C;}pre.rust .doccomment{color:#4D4D4C;}nav:not(.sidebar){border-bottom-color:#e0e0e0;}nav.main .current{border-top-color:#000;border-bottom-color:#000;}nav.main .separator{border:1px solid #000;}a{color:#000;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.item-info a,#help a{color:#3873AD;}a.test-arrow{color:#f5f5f5;}.collapse-toggle{color:#999;}#crate-search{color:#555;background-color:white;border-color:#e0e0e0;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input{color:#555;background-color:white;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input:focus{border-color:#66afe9;}.search-focus:disabled{background-color:#e6e6e6;}#crate-search+.search-input:focus{box-shadow:0 0 8px #078dd8;}.module-item .stab{color:#000;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;}.stab.portability>code{color:#000;}#help>div{background:#e9e9e9;border-color:#bfbfbf;}#help>div>span{border-bottom-color:#bfbfbf;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:black;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#8959A8;}pre.rust .kw-2,pre.rust .prelude-ty{color:#4271AE;}pre.rust .number,pre.rust .string{color:#718C00;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#C82829;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#B76514;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#c7c7c7;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:#FDFFD3;border-right:3px solid #ffb44c;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.5);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.5);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip::after{background-color:#000;color:#fff;}.tooltip::before{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#eee;border-color:#999;}#titles>button:not(.selected){background-color:#e6e6e6;border-top-color:#e6e6e6;}#titles>button:hover,#titles>button.selected{background-color:#ffffff;border-top-color:#0089ff;}#titles>button>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#F1F1F1;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#F1F1F1;border-right-color:#000;}#sidebar-filler{background-color:#F1F1F1;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#e0e0e0;background-color:#fff;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#717171;}#theme-choices{border-color:#ccc;background-color:#fff;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#eee;}@media (max-width:700px){#theme-picker{background:#fff;}}#all-types{background-color:#fff;}#all-types:hover{background-color:#f9f9f9;}.search-results td span.alias{color:#000;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#F1F1F1;}#sidebar-toggle:hover{background-color:#E0E0E0;}#source-sidebar{background-color:#F1F1F1;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#E0E0E0;}div.files>.selected{background-color:#fff;}.setting-line>.title{border-bottom-color:#D5D5D5;} \ No newline at end of file + body{background-color:white;color:black;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:black;}h1.fqn{border-bottom-color:#D5D5D5;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#DDDDDD;}.in-band{background-color:white;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#F5F5F5;}pre{background-color:#F5F5F5;}.sidebar{background-color:#F1F1F1;}*{scrollbar-color:rgba(36,37,39,0.6) #e6e6e6;}.sidebar{scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;}.logo-container.rust-logo>img{}::-webkit-scrollbar-track{background-color:#ecebeb;}::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar::-webkit-scrollbar-track{background-color:#dcdcdc;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar .current{background-color:#fff;}.source .sidebar{background-color:#fff;}.sidebar .location{border-color:#000;background-color:#fff;color:#333;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#F5F5F5;}.line-numbers span{color:#c67e2d;}.line-numbers .line-highlighted{background-color:#f6fdb0 !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#ddd;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#4E4C4C;}.content .highlighted{color:#000 !important;background-color:#ccc;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted.trait{background-color:#c7b6ff;}.content .highlighted.traitalias{background-color:#c7b6ff;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.enum{background-color:#b4d1b9;}.content .highlighted.struct{background-color:#e7b1a0;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#c6afb3;}.content .highlighted.type{background-color:#ffc891;}.content .highlighted.foreigntype{background-color:#f5c4ff;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#8ce488;}.content .highlighted.constant,.content .highlighted.static{background-color:#c3e0ff;}.content .highlighted.primitive{background-color:#9aecff;}.content .highlighted.keyword{background-color:#f99650;}.content .item-info::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#508157;}.content span.struct,.content a.struct,.block a.current.struct{color:#ad448e;}.content span.type,.content a.type,.block a.current.type{color:#ba5d00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#cd00e2;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#068000;}.content span.union,.content a.union,.block a.current.union{color:#767b27;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#546e8a;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2c8093;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#4d76ae;}.content span.trait,.content a.trait,.block a.current.trait{color:#7c5af3;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#6841f1;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#9a6e31;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8E908C;}pre.rust .doccomment{color:#4D4D4C;}nav:not(.sidebar){border-bottom-color:#e0e0e0;}nav.main .current{border-top-color:#000;border-bottom-color:#000;}nav.main .separator{border:1px solid #000;}a{color:#000;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.item-info a,#help a{color:#3873AD;}a.test-arrow{color:#f5f5f5;}.collapse-toggle{color:#999;}#crate-search{color:#555;background-color:white;border-color:#e0e0e0;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input{color:#555;background-color:white;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input:focus{border-color:#66afe9;}.search-focus:disabled{background-color:#e6e6e6;}#crate-search+.search-input:focus{box-shadow:0 0 8px #078dd8;}.module-item .stab{color:#000;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;}.stab.portability>code{background:none;}#help>div{background:#e9e9e9;border-color:#bfbfbf;}#help>div>span{border-bottom-color:#bfbfbf;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:black;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#8959A8;}pre.rust .kw-2,pre.rust .prelude-ty{color:#4271AE;}pre.rust .number,pre.rust .string{color:#718C00;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#C82829;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#B76514;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#c7c7c7;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:#FDFFD3;border-right:3px solid #ffb44c;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.5);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.5);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip::after{background-color:#000;color:#fff;}.tooltip::before{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#eee;border-color:#999;}#titles>button:not(.selected){background-color:#e6e6e6;border-top-color:#e6e6e6;}#titles>button:hover,#titles>button.selected{background-color:#ffffff;border-top-color:#0089ff;}#titles>button>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#F1F1F1;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#F1F1F1;border-right-color:#000;}#sidebar-filler{background-color:#F1F1F1;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#e0e0e0;background-color:#fff;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#717171;}#theme-choices{border-color:#ccc;background-color:#fff;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#eee;}@media (max-width:700px){#theme-picker{background:#fff;}}#all-types{background-color:#fff;}#all-types:hover{background-color:#f9f9f9;}.search-results td span.alias{color:#000;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#F1F1F1;}#sidebar-toggle:hover{background-color:#E0E0E0;}#source-sidebar{background-color:#F1F1F1;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#E0E0E0;}div.files>.selected{background-color:#fff;}.setting-line>.title{border-bottom-color:#D5D5D5;} \ No newline at end of file diff --git a/main.js b/main.js index 03cfb2cc3..9beaa881f 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,8 @@ -if(!String.prototype.startsWith){String.prototype.startsWith=function(searchString,position){position=position||0;return this.indexOf(searchString,position)===position}}if(!String.prototype.endsWith){String.prototype.endsWith=function(suffix,length){var l=length||this.length;return this.indexOf(suffix,l-suffix.length)!==-1}}if(!DOMTokenList.prototype.add){DOMTokenList.prototype.add=function(className){if(className&&!hasClass(this,className)){if(this.className&&this.className.length>0){this.className+=" "+className}else{this.className=className}}}}if(!DOMTokenList.prototype.remove){DOMTokenList.prototype.remove=function(className){if(className&&this.className){this.className=(" "+this.className+" ").replace(" "+className+" "," ").trim()}}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!="undefined"){return ev.key}var c=ev.charCode||ev.keyCode;if(c==27){return"Escape"}return String.fromCharCode(c)}function getSearchInput(){return document.getElementsByClassName("search-input")[0]}function getSearchElement(){return document.getElementById("search")}function getThemesElement(){return document.getElementById("theme-choices")}function getThemePickerElement(){return document.getElementById("theme-picker")}function focusSearchBar(){getSearchInput().focus()}function defocusSearchBar(){getSearchInput().blur()}(function(){"use strict";var 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"];var disableShortcuts=getSettingValue("disable-shortcuts")==="true";var search_input=getSearchInput();var searchTimeout=null;var toggleAllDocsId="toggle-all-docs";var currentTab=0;var mouseMovedAfterSearch=true;var titleBeforeSearch=document.title;var searchTitle=null;function clearInputTimeout(){if(searchTimeout!==null){clearTimeout(searchTimeout);searchTimeout=null}}function getPageId(){if(window.location.hash){var tmp=window.location.hash.replace(/^#/,"");if(tmp.length>0){return tmp}}return null}function showSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){addClass(elems,"show-it")}var sidebar=document.getElementsByClassName("sidebar")[0];if(sidebar){addClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(!filler){var div=document.createElement("div");div.id="sidebar-filler";sidebar.appendChild(div)}}}function hideSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){removeClass(elems,"show-it")}var sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(filler){filler.remove()}document.getElementsByTagName("body")[0].style.marginTop=""}function showSearchResults(search){if(search===null||typeof search==='undefined'){search=getSearchElement()}addClass(main,"hidden");removeClass(search,"hidden");mouseMovedAfterSearch=false;document.title=searchTitle}function hideSearchResults(search){if(search===null||typeof search==='undefined'){search=getSearchElement()}addClass(search,"hidden");removeClass(main,"hidden");document.title=titleBeforeSearch}var TY_PRIMITIVE=itemTypes.indexOf("primitive");var TY_KEYWORD=itemTypes.indexOf("keyword");function getQueryStringParams(){var params={};window.location.search.substring(1).split("&").map(function(s){var pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function isHidden(elem){return elem.offsetHeight===0}var main=document.getElementById("main");var savedHash="";function handleHashes(ev){var elem;var search=getSearchElement();if(ev!==null&&search&&!hasClass(search,"hidden")&&ev.newURL){hideSearchResults(search);var hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(hash,"","?search=#"+hash)}elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}if(savedHash!==window.location.hash){savedHash=window.location.hash;if(savedHash.length===0){return}elem=document.getElementById(savedHash.slice(1));if(!elem||!isHidden(elem)){return}var parent=elem.parentNode;if(parent&&hasClass(parent,"impl-items")){onEachLazy(parent.getElementsByClassName("collapsed"),function(e){if(e.parentNode===parent){e.click();return true}});if(isHidden(elem)){if(hasClass(parent.lastElementChild,"collapse-toggle")){parent.lastElementChild.click()}}}}}function highlightSourceLines(match,ev){if(typeof match==="undefined"){hideSidebar();match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/)}if(!match){return}var from=parseInt(match[1],10);var to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to0){collapseDocs(collapses[0],"show")}}}}function getHelpElement(){buildHelperPopup();return document.getElementById("help")}function displayHelp(display,ev,help){help=help?help:getHelpElement();if(display===true){if(hasClass(help,"hidden")){ev.preventDefault();removeClass(help,"hidden");addClass(document.body,"blur")}}else if(hasClass(help,"hidden")===false){ev.preventDefault();addClass(help,"hidden");removeClass(document.body,"blur")}}function handleEscape(ev){var help=getHelpElement();var search=getSearchElement();if(hasClass(help,"hidden")===false){displayHelp(false,ev,help)}else if(hasClass(search,"hidden")===false){clearInputTimeout();ev.preventDefault();hideSearchResults(search)}defocusSearchBar();hideThemeButtonState()}function handleShortcut(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts===true){return}if(document.activeElement.tagName==="INPUT"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":displayHelp(false,ev);ev.preventDefault();focusSearchBar();break;case"+":case"-":ev.preventDefault();toggleAllDocs();break;case"?":displayHelp(true,ev);break;case"t":case"T":displayHelp(false,ev);ev.preventDefault();var themePicker=getThemePickerElement();themePicker.click();themePicker.focus();break;default:var themePicker=getThemePickerElement();if(themePicker.parentNode.contains(ev.target)){handleThemeKeyDown(ev)}}}}function handleThemeKeyDown(ev){var active=document.activeElement;var themes=getThemesElement();switch(getVirtualKey(ev)){case"ArrowUp":ev.preventDefault();if(active.previousElementSibling&&ev.target.id!=="theme-picker"){active.previousElementSibling.focus()}else{showThemeButtonState();themes.lastElementChild.focus()}break;case"ArrowDown":ev.preventDefault();if(active.nextElementSibling&&ev.target.id!=="theme-picker"){active.nextElementSibling.focus()}else{showThemeButtonState();themes.firstElementChild.focus()}break;case"Enter":case"Return":case"Space":if(ev.target.id==="theme-picker"&&themes.style.display==="none"){ev.preventDefault();showThemeButtonState();themes.firstElementChild.focus()}break;case"Home":ev.preventDefault();themes.firstElementChild.focus();break;case"End":ev.preventDefault();themes.lastElementChild.focus();break}}function findParentElement(elem,tagName){do{if(elem&&elem.tagName===tagName){return elem}elem=elem.parentNode}while(elem);return null}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function resetMouseMoved(ev){mouseMovedAfterSearch=true}document.addEventListener("mousemove",resetMouseMoved);var handleSourceHighlight=(function(){var prev_line_id=0;var set_fragment=function(name){var x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSourceLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return function(ev){var cur_line_id=parseInt(ev.target.id,10);ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){var 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)}}}());document.addEventListener("click",function(ev){if(hasClass(ev.target,"help-button")){displayHelp(true,ev)}else if(hasClass(ev.target,"collapse-toggle")){collapseDocs(ev.target,"toggle")}else if(hasClass(ev.target.parentNode,"collapse-toggle")){collapseDocs(ev.target.parentNode,"toggle")}else if(ev.target.tagName==="SPAN"&&hasClass(ev.target.parentNode,"line-numbers")){handleSourceHighlight(ev)}else if(hasClass(getHelpElement(),"hidden")===false){var help=getHelpElement();var is_inside_help_popup=ev.target!==help&&help.contains(ev.target);if(is_inside_help_popup===false){addClass(help,"hidden");removeClass(document.body,"blur")}}else{var a=findParentElement(ev.target,"A");if(a&&a.hash){expandSection(a.hash.replace(/^#/,""))}}});(function(){var x=document.getElementsByClassName("version-selector");if(x.length>0){x[0].onchange=function(){var i,match,url=document.location.href,stripped="",len=rootPath.match(/\.\.\//g).length+1;for(i=0;i-1){var obj=searchIndex[results[i].id];obj.lev=results[i].lev;if(isType!==true||obj.type){var res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}}return out}function sortResults(results,isType){var ar=[];for(var entry in results){if(hasOwnProperty(results,entry)){ar.push(results[entry])}}results=ar;var i;var nresults=results.length;for(i=0;ib?+1:-1)}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}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});var length=results.length;for(i=0;i"));return{name:val.substring(0,val.indexOf("<")),generics:values.split(/\s*,\s*/),}}return{name:val,generics:[],}}function getObjectFromId(id){if(typeof id==="number"){return searchIndex[id]}return{'name':id}}function checkGenerics(obj,val){var lev_distance=MAX_LEV_DISTANCE+1;if(val.generics.length>0){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=obj[GENERICS_DATA].slice(0);var total=0;var done=0;var vlength=val.generics.length;for(var y=0;yGENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=obj[GENERICS_DATA].slice(0);var allFound=true;for(var y=0;allFound===true&&yGENERICS_DATA&&obj[GENERICS_DATA].length!==0){var tmp_lev=checkGenerics(obj,val);if(tmp_lev<=MAX_LEV_DISTANCE){return tmp_lev}}else{return 0}}if(literalSearch===true){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>0){var length=obj[GENERICS_DATA].length;for(x=0;xGENERICS_DATA&&obj[GENERICS_DATA].length>0){var olength=obj[GENERICS_DATA].length;for(x=0;x0){var length=obj.type[INPUTS_DATA].length;for(var i=0;iOUTPUT_DATA){var ret=obj.type[OUTPUT_DATA];if(typeof ret[0]==="string"){ret=[ret]}for(var x=0;xlength){return MAX_LEV_DISTANCE+1}for(var i=0;ilength){break}var lev_total=0;var aborted=false;for(var x=0;xMAX_LEV_DISTANCE){aborted=true;break}lev_total+=lev}if(aborted===false){ret_lev=Math.min(ret_lev,Math.round(lev_total/clength))}}return ret_lev}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER)return true;if(filter===type)return true;var 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 generateId(ty){if(ty.parent&&ty.parent.name){return itemTypes[ty.ty]+ty.path+ty.parent.name+ty.name}return itemTypes[ty.ty]+ty.path+ty.name}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,}}function handleAliases(ret,query,filterCrates){var aliases=[];var crateAliases=[];var i;if(filterCrates!==undefined){if(ALIASES[filterCrates]&&ALIASES[filterCrates][query.search]){for(i=0;iMAX_RESULTS){ret.others.pop()}};onEach(aliases,pushFunc);onEach(crateAliases,pushFunc)}var nSearchWords=searchWords.length;var i;var ty;var fullId;var returned;var in_args;if((val.charAt(0)==="\""||val.charAt(0)==="'")&&val.charAt(val.length-1)===val.charAt(0)){val=extractGenerics(val.substr(1,val.length-2));for(i=0;i")>-1){var trimmer=function(s){return s.trim()};var parts=val.split("->").map(trimmer);var input=parts[0];var inputs=input.split(",").map(trimmer).sort();for(i=0;i1?paths.length-1:1);var lev;for(j=0;j1){lev=checkPath(contains,paths[paths.length-1],ty);if(lev>MAX_LEV_DISTANCE){continue}else if(lev>0){lev_add=lev/10}}returned=MAX_LEV_DISTANCE+1;in_args=MAX_LEV_DISTANCE+1;var index=-1;lev=MAX_LEV_DISTANCE+1;fullId=generateId(ty);if(searchWords[j].indexOf(split[i])>-1||searchWords[j].indexOf(val)>-1||searchWords[j].replace(/_/g,"").indexOf(val)>-1){if(typePassesFilter(typeFilter,ty.ty)&&results[fullId]===undefined){index=searchWords[j].replace(/_/g,"").indexOf(val)}}if((lev=levenshtein(searchWords[j],val))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){lev=MAX_LEV_DISTANCE+1}else{lev+=1}}in_args=findArg(ty,valGenerics,false,typeFilter);returned=checkReturned(ty,valGenerics,false,typeFilter);lev+=lev_add;if(lev>0&&val.length>3&&searchWords[j].indexOf(val)>-1){if(val.length<6){lev-=1}else{lev=0}}if(in_args<=MAX_LEV_DISTANCE){if(results_in_args[fullId]===undefined){results_in_args[fullId]={id:j,index:index,lev:in_args,}}results_in_args[fullId].lev=Math.min(results_in_args[fullId].lev,in_args)}if(returned<=MAX_LEV_DISTANCE){if(results_returned[fullId]===undefined){results_returned[fullId]={id:j,index:index,lev:returned,}}results_returned[fullId].lev=Math.min(results_returned[fullId].lev,returned)}if(index!==-1||lev<=MAX_LEV_DISTANCE){if(index!==-1&&paths.length<2){lev=0}if(results[fullId]===undefined){results[fullId]={id:j,index:index,lev:lev,}}results[fullId].lev=Math.min(results[fullId].lev,lev)}}}var ret={"in_args":sortResults(results_in_args,true),"returned":sortResults(results_returned,true),"others":sortResults(results),};handleAliases(ret,query,filterCrates);return ret}function validateResult(name,path,keys,parent){for(var i=0;i-1||path.indexOf(keys[i])>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(keys[i])>-1)||levenshtein(name,keys[i])<=MAX_LEV_DISTANCE)){return false}}return true}function getQuery(raw){var matches,type,query;query=raw;matches=query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i);if(matches){type=matches[1].replace(/^const$/,"constant");query=query.substring(matches[0].length)}return{raw:raw,query:query,type:type,id:query+type}}function initSearchNav(){var hoverTimeout;var click_func=function(e){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode}var dst=e.target.getElementsByTagName("a");if(dst.length<1){return}dst=dst[0];if(window.location.pathname===dst.pathname){hideSearchResults();document.location.href=dst.href}};var mouseover_func=function(e){if(mouseMovedAfterSearch){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode}clearTimeout(hoverTimeout);hoverTimeout=setTimeout(function(){onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){removeClass(i_e,"highlighted")})});addClass(el,"highlighted")},20)}};onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){i_e.onclick=click_func;i_e.onmouseover=mouseover_func})});search_input.onkeydown=function(e){var actives=[[],[],[]];var current=0;onEachLazy(document.getElementById("results").childNodes,function(e){onEachLazy(e.getElementsByClassName("highlighted"),function(h_e){actives[current].push(h_e)});current+=1});if(e.which===38){if(e.ctrlKey){printTab(currentTab>0?currentTab-1:2)}else{if(!actives[currentTab].length||!actives[currentTab][0].previousElementSibling){return}addClass(actives[currentTab][0].previousElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted")}e.preventDefault()}else if(e.which===40){if(e.ctrlKey){printTab(currentTab>1?0:currentTab+1)}else if(!actives[currentTab].length){var results=document.getElementById("results").childNodes;if(results.length>0){var res=results[currentTab].getElementsByClassName("result");if(res.length>0){addClass(res[0],"highlighted")}}}else if(actives[currentTab][0].nextElementSibling){addClass(actives[currentTab][0].nextElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted")}e.preventDefault()}else if(e.which===13){if(actives[currentTab].length){document.location.href=actives[currentTab][0].getElementsByTagName("a")[0].href}}else if(e.which===16){}else if(actives[currentTab].length>0){removeClass(actives[currentTab][0],"highlighted")}}}function buildHrefAndPath(item){var displayPath;var href;var type=itemTypes[item.ty];var name=item.name;var path=item.path;if(type==="mod"){displayPath=path+"::";href=rootPath+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="primitive"||type==="keyword"){displayPath="";href=rootPath+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=rootPath+name+"/index.html"}else if(item.parent!==undefined){var myparent=item.parent;var anchor="#"+type+"."+name;var parentType=itemTypes[myparent.ty];var pageType=parentType;var pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){var splitPath=item.path.split("::");var enumName=splitPath.pop();path=splitPath.join("::");displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=rootPath+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=rootPath+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function escape(content){var h1=document.createElement("h1");h1.textContent=content;return h1.innerHTML}function pathSplitter(path){var tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){var extraStyle="";if(display===false){extraStyle=" style=\"display: none;\""}var output="";var duplicates={};var length=0;if(array.length>0){output="";array.forEach(function(item){var name,type;name=item.name;type=itemTypes[item.ty];if(item.is_alias!==true){if(duplicates[item.fullPath]){return}duplicates[item.fullPath]=true}length+=1;output+=""});output+="
"+""+(item.is_alias===true?(""+item.alias+"  - see "):"")+item.displayPath+""+name+""+""+""+item.desc+" 
"}else{output="
No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:
"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(currentTab===tabNb){return""}return""}function showResults(results){var search=getSearchElement();if(results.others.length===1&&getSettingValue("go-to-only-result")==="true"&&(!search.firstChild||search.firstChild.innerText!==getSearchLoadingText())){var elem=document.createElement("a");elem.href=results.others[0].href;elem.style.display="none";document.body.appendChild(elem);elem.click();return}var query=getQuery(search_input.value);currentResults=query.id;var ret_others=addTab(results.others,query);var ret_in_args=addTab(results.in_args,query,false);var ret_returned=addTab(results.returned,query,false);var output="

Results for "+escape(query.query)+(query.type?" (type: "+escape(query.type)+")":"")+"

"+"
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"+ret_others[0]+ret_in_args[0]+ret_returned[0]+"
";search.innerHTML=output;showSearchResults(search);var tds=search.getElementsByTagName("td");var td_width=0;if(tds.length>0){td_width=tds[0].offsetWidth}var width=search.offsetWidth-40-td_width;onEachLazy(search.getElementsByClassName("desc"),function(e){e.style.width=width+"px"});initSearchNav();var elems=document.getElementById("titles").childNodes;elems[0].onclick=function(){printTab(0)};elems[1].onclick=function(){printTab(1)};elems[2].onclick=function(){printTab(2)};printTab(currentTab)}function execSearch(query,searchWords,filterCrates){function getSmallest(arrays,positions,notDuplicates){var start=null;for(var it=0;itpositions[it]&&(start===null||start>arrays[it][positions[it]].lev)&&!notDuplicates[arrays[it][positions[it]].fullPath]){start=arrays[it][positions[it]].lev}}return start}function mergeArrays(arrays){var ret=[];var positions=[];var notDuplicates={};for(var x=0;xpositions[x]&&arrays[x][positions[x]].lev===smallest&&!notDuplicates[arrays[x][positions[x]].fullPath]){ret.push(arrays[x][positions[x]]);notDuplicates[arrays[x][positions[x]].fullPath]=true;positions[x]+=1}}}return ret}var queries=query.raw.split(",");var results={"in_args":[],"returned":[],"others":[],};for(var i=0;i1){return{"in_args":mergeArrays(results.in_args),"returned":mergeArrays(results.returned),"others":mergeArrays(results.others),}}return{"in_args":results.in_args[0],"returned":results.returned[0],"others":results.others[0],}}function getFilterCrates(){var elem=document.getElementById("crate-search");if(elem&&elem.value!=="All crates"&&hasOwnProperty(rawSearchIndex,elem.value)){return elem.value}return undefined}function search(e,forced){var params=getQueryStringParams();var query=getQuery(search_input.value.trim());if(e){e.preventDefault()}if(query.query.length===0){return}if(forced!==true&&query.id===currentResults){if(query.query.length>0){putBackSearch(search_input)}return}searchTitle="Results for "+query.query+" - Rust";if(browserSupportsHistoryApi()){if(!history.state&&!params.search){history.pushState(query,"","?search="+encodeURIComponent(query.raw))}else{history.replaceState(query,"","?search="+encodeURIComponent(query.raw))}}var filterCrates=getFilterCrates();showResults(execSearch(query,index,filterCrates))}function buildIndex(rawSearchIndex){searchIndex=[];var searchWords=[];var i;var currentIndex=0;for(var crate in rawSearchIndex){if(!hasOwnProperty(rawSearchIndex,crate)){continue}var crateSize=0;searchWords.push(crate);searchIndex.push({crate:crate,ty:1,name:crate,path:"",desc:rawSearchIndex[crate].doc,type:null,});currentIndex+=1;var items=rawSearchIndex[crate].i;var paths=rawSearchIndex[crate].p;var aliases=rawSearchIndex[crate].a;var len=paths.length;for(i=0;i0){search_input.value=params.search;search(e)}else{search_input.value="";hideSearchResults()}})}search()}index=buildIndex(rawSearchIndex);startSearch();if(rootPath==="../"||rootPath==="./"){var sidebar=document.getElementsByClassName("sidebar-elems")[0];if(sidebar){var div=document.createElement("div");div.className="block crate";div.innerHTML="

Crates

";var ul=document.createElement("ul");div.appendChild(ul);var crates=[];for(var crate in rawSearchIndex){if(!hasOwnProperty(rawSearchIndex,crate)){continue}crates.push(crate)}crates.sort();for(var i=0;i','`').replace('','`');return x.innerText}window.initSidebarItems=function(items){var sidebar=document.getElementsByClassName("sidebar-elems")[0];var current=window.sidebarCurrent;function block(shortty,longty){var filtered=items[shortty];if(!filtered){return}var div=document.createElement("div");div.className="block "+shortty;var h3=document.createElement("h3");h3.textContent=longty;div.appendChild(h3);var ul=document.createElement("ul");var length=filtered.length;for(var i=0;i"+""+"
"+code.outerHTML+"
";list.appendChild(display)}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function labelForToggleButton(sectionIsCollapsed){if(sectionIsCollapsed){return"+"}return"\u2212"}function onEveryMatchingChild(elem,className,func){if(elem&&className&&func){var length=elem.childNodes.length;var nodes=elem.childNodes;for(var i=0;i"+labelForToggleButton(sectionIsCollapsed)+"
]";return toggle}function createToggle(toggle,otherMessage,fontSize,extraClass,show){var span=document.createElement("span");span.className="toggle-label";if(show){span.style.display="none"}if(!otherMessage){span.innerHTML=" Expand description"}else{span.innerHTML=otherMessage}if(fontSize){span.style.fontSize=fontSize}var mainToggle=toggle.cloneNode(true);mainToggle.appendChild(span);var wrapper=document.createElement("div");wrapper.className="toggle-wrapper";if(!show){addClass(wrapper,"collapsed");var inner=mainToggle.getElementsByClassName("inner");if(inner&&inner.length>0){inner[0].innerHTML="+"}}if(extraClass){addClass(wrapper,extraClass)}wrapper.appendChild(mainToggle);return wrapper}(function(){var toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}var toggle=createSimpleToggle(false);var hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";var hideImplementors=getSettingValue("auto-collapse-implementors")!=="false";var pageId=getPageId();var func=function(e){var next=e.nextElementSibling;if(next&&hasClass(next,"item-info")){next=next.nextElementSibling}if(!next){return}if(hasClass(next,"docblock")){var newToggle=toggle.cloneNode(true);insertAfter(newToggle,e.childNodes[e.childNodes.length-1]);if(hideMethodDocs===true&&hasClass(e,"method")===true){collapseDocs(newToggle,"hide",pageId)}}};var funcImpl=function(e){var next=e.nextElementSibling;if(next&&hasClass(next,"item-info")){next=next.nextElementSibling}if(next&&hasClass(next,"docblock")){next=next.nextElementSibling}if(!next){return}if(hasClass(e,"impl")&&(next.getElementsByClassName("method").length>0||next.getElementsByClassName("associatedconstant").length>0)){var newToggle=toggle.cloneNode(true);insertAfter(newToggle,e.childNodes[e.childNodes.length-1]);if(hideImplementors===true&&e.parentNode.id==="implementors-list"){collapseDocs(newToggle,"hide",pageId)}}};onEachLazy(document.getElementsByClassName("method"),func);onEachLazy(document.getElementsByClassName("associatedconstant"),func);onEachLazy(document.getElementsByClassName("impl"),funcImpl);var impl_call=function(){};if(hideMethodDocs===true){impl_call=function(e,newToggle){if(e.id.match(/^impl(?:-\d+)?$/)===null){if(hasClass(e,"impl")===true){collapseDocs(newToggle,"hide",pageId)}}}}var newToggle=document.createElement("a");newToggle.href="javascript:void(0)";newToggle.className="collapse-toggle hidden-default collapsed";newToggle.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items";function toggleClicked(){if(hasClass(this,"collapsed")){removeClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("hidden"),function(x){if(hasClass(x,"content")===false){removeClass(x,"hidden");addClass(x,"x")}},true);this.innerHTML="["+labelForToggleButton(false)+"] Hide undocumented items"}else{addClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("x"),function(x){if(hasClass(x,"content")===false){addClass(x,"hidden");removeClass(x,"x")}},true);this.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items"}}onEachLazy(document.getElementsByClassName("impl-items"),function(e){onEachLazy(e.getElementsByClassName("associatedconstant"),func);var hiddenElems=e.getElementsByClassName("hidden");var needToggle=false;var hlength=hiddenElems.length;for(var i=0;i"+getSearchLoadingText()+"";showSearchResults(search)}var sidebar_menu=document.getElementsByClassName("sidebar-menu")[0];if(sidebar_menu){sidebar_menu.onclick=function(){var sidebar=document.getElementsByClassName("sidebar")[0];if(hasClass(sidebar,"mobile")===true){hideSidebar()}else{showSidebar()}}}if(main){onEachLazy(main.getElementsByClassName("loading-content"),function(e){e.remove()});onEachLazy(main.childNodes,function(e){if(e.tagName==="H2"||e.tagName==="H3"){var nextTagName=e.nextElementSibling.tagName;if(nextTagName=="H2"||nextTagName=="H3"){e.nextElementSibling.style.display="flex"}else{e.nextElementSibling.style.display="block"}}})}function enableSearchInput(){if(search_input){search_input.removeAttribute('disabled')}}window.addSearchOptions=function(crates){var elem=document.getElementById("crate-search");if(!elem){enableSearchInput();return}var crates_text=[];if(Object.keys(crates).length>1){for(var crate in crates){if(hasOwnProperty(crates,crate)){crates_text.push(crate)}}}crates_text.sort(function(a,b){var lower_a=a.toLowerCase();var lower_b=b.toLowerCase();if(lower_alower_b){return 1}return 0});var savedCrate=getSettingValue("saved-filter-crate");for(var i=0;ithe rustdoc book.";var container=document.createElement("div");var shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["T","Focus the theme picker menu"],["↑","Move up in search results"],["↓","Move down in search results"],["ctrl + ↑ / ↓","Switch result tab"],["⏎","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("");var div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";var infos=["Prefix searches with a type followed by a colon (e.g., fn:) to \ +if(!String.prototype.startsWith){String.prototype.startsWith=function(searchString,position){position=position||0;return this.indexOf(searchString,position)===position}}if(!String.prototype.endsWith){String.prototype.endsWith=function(suffix,length){var l=length||this.length;return this.indexOf(suffix,l-suffix.length)!==-1}}if(!DOMTokenList.prototype.add){DOMTokenList.prototype.add=function(className){if(className&&!hasClass(this,className)){if(this.className&&this.className.length>0){this.className+=" "+className}else{this.className=className}}}}if(!DOMTokenList.prototype.remove){DOMTokenList.prototype.remove=function(className){if(className&&this.className){this.className=(" "+this.className+" ").replace(" "+className+" "," ").trim()}}}(function(){var rustdocVars=document.getElementById("rustdoc-vars");if(rustdocVars){window.rootPath=rustdocVars.attributes["data-root-path"].value;window.currentCrate=rustdocVars.attributes["data-current-crate"].value;window.searchJS=rustdocVars.attributes["data-search-js"].value}var sidebarVars=document.getElementById("sidebar-vars");if(sidebarVars){window.sidebarCurrent={name:sidebarVars.attributes["data-name"].value,ty:sidebarVars.attributes["data-ty"].value,relpath:sidebarVars.attributes["data-relpath"].value,}}}());function getVirtualKey(ev){if("key"in ev&&typeof ev.key!="undefined"){return ev.key}var c=ev.charCode||ev.keyCode;if(c==27){return"Escape"}return String.fromCharCode(c)}function getSearchInput(){return document.getElementsByClassName("search-input")[0]}function getSearchElement(){return document.getElementById("search")}function getThemesElement(){return document.getElementById("theme-choices")}function getThemePickerElement(){return document.getElementById("theme-picker")}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function focusSearchBar(){getSearchInput().focus()}function defocusSearchBar(){getSearchInput().blur()}(function(){"use strict";var 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"];var disableShortcuts=getSettingValue("disable-shortcuts")==="true";var search_input=getSearchInput();var searchTimeout=null;var toggleAllDocsId="toggle-all-docs";var currentTab=0;var mouseMovedAfterSearch=true;var titleBeforeSearch=document.title;var searchTitle=null;function clearInputTimeout(){if(searchTimeout!==null){clearTimeout(searchTimeout);searchTimeout=null}}function getPageId(){if(window.location.hash){var tmp=window.location.hash.replace(/^#/,"");if(tmp.length>0){return tmp}}return null}function showSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){addClass(elems,"show-it")}var sidebar=document.getElementsByClassName("sidebar")[0];if(sidebar){addClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(!filler){var div=document.createElement("div");div.id="sidebar-filler";sidebar.appendChild(div)}}}function hideSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){removeClass(elems,"show-it")}var sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(filler){filler.remove()}document.getElementsByTagName("body")[0].style.marginTop=""}function showSearchResults(search){if(search===null||typeof search==='undefined'){search=getSearchElement()}addClass(main,"hidden");removeClass(search,"hidden");mouseMovedAfterSearch=false;document.title=searchTitle}function hideSearchResults(search){if(search===null||typeof search==='undefined'){search=getSearchElement()}addClass(search,"hidden");removeClass(main,"hidden");document.title=titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState("",window.currentCrate+" - Rust",getNakedUrl()+window.location.hash)}}var TY_PRIMITIVE=itemTypes.indexOf("primitive");var TY_KEYWORD=itemTypes.indexOf("keyword");function getQueryStringParams(){var params={};window.location.search.substring(1).split("&").map(function(s){var pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function isHidden(elem){return elem.offsetHeight===0}var main=document.getElementById("main");var savedHash="";function handleHashes(ev){var elem;var search=getSearchElement();if(ev!==null&&search&&!hasClass(search,"hidden")&&ev.newURL){hideSearchResults(search);var hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(hash,"",getNakedUrl()+window.location.search+"#"+hash)}elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}if(savedHash!==window.location.hash){savedHash=window.location.hash;if(savedHash.length===0){return}elem=document.getElementById(savedHash.slice(1));if(!elem||!isHidden(elem)){return}var parent=elem.parentNode;if(parent&&hasClass(parent,"impl-items")){onEachLazy(parent.getElementsByClassName("collapsed"),function(e){if(e.parentNode===parent){e.click();return true}});if(isHidden(elem)){if(hasClass(parent.lastElementChild,"collapse-toggle")){parent.lastElementChild.click()}}}}}function highlightSourceLines(match,ev){if(typeof match==="undefined"){hideSidebar();match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/)}if(!match){return}var from=parseInt(match[1],10);var to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to0){collapseDocs(collapses[0],"show")}}}}function getHelpElement(build){if(build!==false){buildHelperPopup()}return document.getElementById("help")}function displayHelp(display,ev,help){if(display===true){help=help?help:getHelpElement(true);if(hasClass(help,"hidden")){ev.preventDefault();removeClass(help,"hidden");addClass(document.body,"blur")}}else{help=help?help:getHelpElement(false);if(help&&hasClass(help,"hidden")===false){ev.preventDefault();addClass(help,"hidden");removeClass(document.body,"blur")}}}function handleEscape(ev){var help=getHelpElement(false);var search=getSearchElement();if(hasClass(help,"hidden")===false){displayHelp(false,ev,help)}else if(hasClass(search,"hidden")===false){clearInputTimeout();ev.preventDefault();hideSearchResults(search)}defocusSearchBar();hideThemeButtonState()}function handleShortcut(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts===true){return}if(document.activeElement.tagName==="INPUT"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":displayHelp(false,ev);ev.preventDefault();focusSearchBar();break;case"+":case"-":ev.preventDefault();toggleAllDocs();break;case"?":displayHelp(true,ev);break;case"t":case"T":displayHelp(false,ev);ev.preventDefault();var themePicker=getThemePickerElement();themePicker.click();themePicker.focus();break;default:var themePicker=getThemePickerElement();if(themePicker.parentNode.contains(ev.target)){handleThemeKeyDown(ev)}}}}function handleThemeKeyDown(ev){var active=document.activeElement;var themes=getThemesElement();switch(getVirtualKey(ev)){case"ArrowUp":ev.preventDefault();if(active.previousElementSibling&&ev.target.id!=="theme-picker"){active.previousElementSibling.focus()}else{showThemeButtonState();themes.lastElementChild.focus()}break;case"ArrowDown":ev.preventDefault();if(active.nextElementSibling&&ev.target.id!=="theme-picker"){active.nextElementSibling.focus()}else{showThemeButtonState();themes.firstElementChild.focus()}break;case"Enter":case"Return":case"Space":if(ev.target.id==="theme-picker"&&themes.style.display==="none"){ev.preventDefault();showThemeButtonState();themes.firstElementChild.focus()}break;case"Home":ev.preventDefault();themes.firstElementChild.focus();break;case"End":ev.preventDefault();themes.lastElementChild.focus();break}}function findParentElement(elem,tagName){do{if(elem&&elem.tagName===tagName){return elem}elem=elem.parentNode}while(elem);return null}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);document.addEventListener("mousemove",function(){mouseMovedAfterSearch=true});var handleSourceHighlight=(function(){var prev_line_id=0;var set_fragment=function(name){var x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSourceLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return function(ev){var cur_line_id=parseInt(ev.target.id,10);ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){var 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)}}}());document.addEventListener("click",function(ev){var helpElem=getHelpElement(false);if(hasClass(ev.target,"help-button")){displayHelp(true,ev)}else if(hasClass(ev.target,"collapse-toggle")){collapseDocs(ev.target,"toggle")}else if(hasClass(ev.target.parentNode,"collapse-toggle")){collapseDocs(ev.target.parentNode,"toggle")}else if(ev.target.tagName==="SPAN"&&hasClass(ev.target.parentNode,"line-numbers")){handleSourceHighlight(ev)}else if(helpElem&&hasClass(helpElem,"hidden")===false){var is_inside_help_popup=ev.target!==helpElem&&helpElem.contains(ev.target);if(is_inside_help_popup===false){addClass(helpElem,"hidden");removeClass(document.body,"blur")}}else{var a=findParentElement(ev.target,"A");if(a&&a.hash){expandSection(a.hash.replace(/^#/,""))}}});(function(){var x=document.getElementsByClassName("version-selector");if(x.length>0){x[0].onchange=function(){var i,match,url=document.location.href,stripped="",len=window.rootPath.match(/\.\.\//g).length+1;for(i=0;i-1){var obj=searchIndex[results[i].id];obj.lev=results[i].lev;if(isType!==true||obj.type){var res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}}return out}function sortResults(results,isType){var ar=[];for(var entry in results){if(hasOwnProperty(results,entry)){ar.push(results[entry])}}results=ar;var i,len,result;for(i=0,len=results.length;ib?+1:-1)}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}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});for(i=0,len=results.length;i"));return{name:val.substring(0,val.indexOf("<")),generics:values.split(/\s*,\s*/),}}return{name:val,generics:[],}}function getObjectNameFromId(id){if(typeof id==="number"){return searchIndex[id].name}return id}function checkGenerics(obj,val){var tmp_lev,elem_name;if(val.generics.length>0){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=Object.create(null);var elength=object[GENERICS_DATA].length;for(var x=0;xGENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=Object.create(null);len=obj[GENERICS_DATA].length;for(x=0;xGENERICS_DATA&&obj[GENERICS_DATA].length!==0){var tmp_lev=checkGenerics(obj,val);if(tmp_lev<=MAX_LEV_DISTANCE){return tmp_lev}}else{return 0}}if(literalSearch===true){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>0){return obj[GENERICS_DATA].some(function(name){return name===val.name})}return false}lev_distance=Math.min(levenshtein(obj[NAME],val.name),lev_distance);if(lev_distance<=MAX_LEV_DISTANCE){lev_distance=Math.ceil((checkGenerics(obj,val)+lev_distance)/2)}else if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>0){var olength=obj[GENERICS_DATA].length;for(x=0;x0){var length=obj.type[INPUTS_DATA].length;for(var i=0;iOUTPUT_DATA){var ret=obj.type[OUTPUT_DATA];if(typeof ret[0]==="string"){ret=[ret]}for(var x=0,len=ret.length;xlength){return MAX_LEV_DISTANCE+1}for(var i=0;ilength){break}var lev_total=0;var aborted=false;for(var x=0;xMAX_LEV_DISTANCE){aborted=true;break}lev_total+=lev}if(aborted===false){ret_lev=Math.min(ret_lev,Math.round(lev_total/clength))}}return ret_lev}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER)return true;if(filter===type)return true;var 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,}}function handleAliases(ret,query,filterCrates){var aliases=[];var crateAliases=[];if(filterCrates!==undefined){if(ALIASES[filterCrates]&&ALIASES[filterCrates][query.search]){var query_aliases=ALIASES[filterCrates][query.search];var len=query_aliases.length;for(var i=0;iMAX_RESULTS){ret.others.pop()}};onEach(aliases,pushFunc);onEach(crateAliases,pushFunc)}var nSearchWords=searchWords.length;var i,it;var ty;var fullId;var returned;var in_args;var len;if((val.charAt(0)==="\""||val.charAt(0)==="'")&&val.charAt(val.length-1)===val.charAt(0)){val=extractGenerics(val.substr(1,val.length-2));for(i=0;i")>-1){var trimmer=function(s){return s.trim()};var parts=val.split("->").map(trimmer);var input=parts[0];var inputs=input.split(",").map(trimmer).sort();for(i=0,len=inputs.length;i1?paths.length-1:1);var lev;for(j=0;j1){lev=checkPath(contains,paths[paths.length-1],ty);if(lev>MAX_LEV_DISTANCE){continue}else if(lev>0){lev_add=lev/10}}returned=MAX_LEV_DISTANCE+1;in_args=MAX_LEV_DISTANCE+1;var index=-1;lev=MAX_LEV_DISTANCE+1;fullId=ty.id;if(searchWords[j].indexOf(split[i])>-1||searchWords[j].indexOf(val)>-1||ty.normalizedName.indexOf(val)>-1){if(typePassesFilter(typeFilter,ty.ty)&&results[fullId]===undefined){index=ty.normalizedName.indexOf(val)}}if((lev=levenshtein(searchWords[j],val))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){lev=MAX_LEV_DISTANCE+1}else{lev+=1}}in_args=findArg(ty,valGenerics,false,typeFilter);returned=checkReturned(ty,valGenerics,false,typeFilter);lev+=lev_add;if(lev>0&&val.length>3&&searchWords[j].indexOf(val)>-1){if(val.length<6){lev-=1}else{lev=0}}if(in_args<=MAX_LEV_DISTANCE){if(results_in_args[fullId]===undefined){results_in_args[fullId]={id:j,index:index,lev:in_args,}}results_in_args[fullId].lev=Math.min(results_in_args[fullId].lev,in_args)}if(returned<=MAX_LEV_DISTANCE){if(results_returned[fullId]===undefined){results_returned[fullId]={id:j,index:index,lev:returned,}}results_returned[fullId].lev=Math.min(results_returned[fullId].lev,returned)}if(index!==-1||lev<=MAX_LEV_DISTANCE){if(index!==-1&&paths.length<2){lev=0}if(results[fullId]===undefined){results[fullId]={id:j,index:index,lev:lev,}}results[fullId].lev=Math.min(results[fullId].lev,lev)}}}var ret={"in_args":sortResults(results_in_args,true),"returned":sortResults(results_returned,true),"others":sortResults(results),};handleAliases(ret,query,filterCrates);return ret}function validateResult(name,path,keys,parent){for(var i=0,len=keys.length;i-1||path.indexOf(keys[i])>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(keys[i])>-1)||levenshtein(name,keys[i])<=MAX_LEV_DISTANCE)){return false}}return true}function getQuery(raw){var matches,type,query;query=raw;matches=query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i);if(matches){type=matches[1].replace(/^const$/,"constant");query=query.substring(matches[0].length)}return{raw:raw,query:query,type:type,id:query+type}}function initSearchNav(){var hoverTimeout;var click_func=function(e){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode}var dst=e.target.getElementsByTagName("a");if(dst.length<1){return}dst=dst[0];if(window.location.pathname===dst.pathname){hideSearchResults();document.location.href=dst.href}};var mouseover_func=function(e){if(mouseMovedAfterSearch){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode}clearTimeout(hoverTimeout);hoverTimeout=setTimeout(function(){onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){removeClass(i_e,"highlighted")})});addClass(el,"highlighted")},20)}};onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){i_e.onclick=click_func;i_e.onmouseover=mouseover_func})});search_input.onkeydown=function(e){var actives=[[],[],[]];var current=0;onEachLazy(document.getElementById("results").childNodes,function(e){onEachLazy(e.getElementsByClassName("highlighted"),function(h_e){actives[current].push(h_e)});current+=1});if(e.which===38){if(e.ctrlKey){printTab(currentTab>0?currentTab-1:2)}else{if(!actives[currentTab].length||!actives[currentTab][0].previousElementSibling){return}addClass(actives[currentTab][0].previousElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted")}e.preventDefault()}else if(e.which===40){if(e.ctrlKey){printTab(currentTab>1?0:currentTab+1)}else if(!actives[currentTab].length){var results=document.getElementById("results").childNodes;if(results.length>0){var res=results[currentTab].getElementsByClassName("result");if(res.length>0){addClass(res[0],"highlighted")}}}else if(actives[currentTab][0].nextElementSibling){addClass(actives[currentTab][0].nextElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted")}e.preventDefault()}else if(e.which===13){if(actives[currentTab].length){document.location.href=actives[currentTab][0].getElementsByTagName("a")[0].href}}else if(e.which===16){}else if(actives[currentTab].length>0){removeClass(actives[currentTab][0],"highlighted")}}}function buildHrefAndPath(item){var displayPath;var href;var type=itemTypes[item.ty];var name=item.name;var path=item.path;if(type==="mod"){displayPath=path+"::";href=window.rootPath+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="primitive"||type==="keyword"){displayPath="";href=window.rootPath+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=window.rootPath+name+"/index.html"}else if(item.parent!==undefined){var myparent=item.parent;var anchor="#"+type+"."+name;var parentType=itemTypes[myparent.ty];var pageType=parentType;var pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){var enumNameIdx=item.path.lastIndexOf("::");var 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=window.rootPath+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=window.rootPath+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function escape(content){var h1=document.createElement("h1");h1.textContent=content;return h1.innerHTML}function pathSplitter(path){var tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){var extraStyle="";if(display===false){extraStyle=" style=\"display: none;\""}var output="";var duplicates={};var length=0;if(array.length>0){output="";array.forEach(function(item){var name,type;name=item.name;type=itemTypes[item.ty];if(item.is_alias!==true){if(duplicates[item.fullPath]){return}duplicates[item.fullPath]=true}length+=1;output+=""});output+="
"+""+(item.is_alias===true?(""+item.alias+"  - see "):"")+item.displayPath+""+name+""+""+""+item.desc+" 
"}else{output="
No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:
"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(currentTab===tabNb){return""}return""}function showResults(results){var search=getSearchElement();if(results.others.length===1&&getSettingValue("go-to-only-result")==="true"&&(!search.firstChild||search.firstChild.innerText!==getSearchLoadingText())){var elem=document.createElement("a");elem.href=results.others[0].href;elem.style.display="none";document.body.appendChild(elem);elem.click();return}var query=getQuery(search_input.value);currentResults=query.id;var ret_others=addTab(results.others,query);var ret_in_args=addTab(results.in_args,query,false);var ret_returned=addTab(results.returned,query,false);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}}var output="

Results for "+escape(query.query)+(query.type?" (type: "+escape(query.type)+")":"")+"

"+"
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"+ret_others[0]+ret_in_args[0]+ret_returned[0]+"
";search.innerHTML=output;showSearchResults(search);initSearchNav();var elems=document.getElementById("titles").childNodes;elems[0].onclick=function(){printTab(0)};elems[1].onclick=function(){printTab(1)};elems[2].onclick=function(){printTab(2)};printTab(currentTab)}function execSearch(query,searchWords,filterCrates){function getSmallest(arrays,positions,notDuplicates){var start=null;for(var it=0,len=positions.length;itpositions[it]&&(start===null||start>arrays[it][positions[it]].lev)&&!notDuplicates[arrays[it][positions[it]].fullPath]){start=arrays[it][positions[it]].lev}}return start}function mergeArrays(arrays){var ret=[];var positions=[];var notDuplicates={};for(var x=0,arrays_len=arrays.length;xpositions[x]&&arrays[x][positions[x]].lev===smallest&&!notDuplicates[arrays[x][positions[x]].fullPath]){ret.push(arrays[x][positions[x]]);notDuplicates[arrays[x][positions[x]].fullPath]=true;positions[x]+=1}}}return ret}var queries=query.raw.split(",");var results={"in_args":[],"returned":[],"others":[],};for(var i=0,len=queries.length;i1){return{"in_args":mergeArrays(results.in_args),"returned":mergeArrays(results.returned),"others":mergeArrays(results.others),}}return{"in_args":results.in_args[0],"returned":results.returned[0],"others":results.others[0],}}function getFilterCrates(){var elem=document.getElementById("crate-search");if(elem&&elem.value!=="All crates"&&hasOwnProperty(rawSearchIndex,elem.value)){return elem.value}return undefined}function search(e,forced){var params=getQueryStringParams();var query=getQuery(search_input.value.trim());if(e){e.preventDefault()}if(query.query.length===0){return}if(forced!==true&&query.id===currentResults){if(query.query.length>0){putBackSearch(search_input)}return}searchTitle="Results for "+query.query+" - Rust";if(browserSupportsHistoryApi()){var newURL=getNakedUrl()+"?search="+encodeURIComponent(query.raw)+window.location.hash;if(!history.state&&!params.search){history.pushState(query,"",newURL)}else{history.replaceState(query,"",newURL)}}var filterCrates=getFilterCrates();showResults(execSearch(query,index,filterCrates))}function buildIndex(rawSearchIndex){searchIndex=[];var searchWords=[];var i,word;var currentIndex=0;var id=0;for(var crate in rawSearchIndex){if(!hasOwnProperty(rawSearchIndex,crate)){continue}var crateSize=0;searchWords.push(crate);var normalizedName=crate.indexOf("_")===-1?crate:crate.replace(/_/g,"");var crateRow={crate:crate,ty:1,name:crate,path:"",desc:rawSearchIndex[crate].doc,parent:undefined,type:null,id:id,normalizedName:normalizedName,};id+=1;searchIndex.push(crateRow);currentIndex+=1;var itemTypes=rawSearchIndex[crate].t;var itemNames=rawSearchIndex[crate].n;var itemPaths=rawSearchIndex[crate].q;var itemDescs=rawSearchIndex[crate].d;var itemParentIdxs=rawSearchIndex[crate].i;var itemFunctionSearchTypes=rawSearchIndex[crate].f;var paths=rawSearchIndex[crate].p;var aliases=rawSearchIndex[crate].a;var len=paths.length;for(i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:itemFunctionSearchTypes[i],id:id,normalizedName:normalizedName,};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){ALIASES[crate]={};var j,local_aliases;for(var alias_name in aliases){if(!aliases.hasOwnProperty(alias_name)){continue}if(!ALIASES[crate].hasOwnProperty(alias_name)){ALIASES[crate][alias_name]=[]}local_aliases=aliases[alias_name];for(j=0,len=local_aliases.length;j0){search_input.value=params.search;search(e)}else{search_input.value="";hideSearchResults()}})}window.onpageshow=function(){var qSearch=getQueryStringParams().search;if(search_input.value===""&&qSearch){search_input.value=qSearch}search()}}index=buildIndex(rawSearchIndex);registerSearchEvents();if(getQueryStringParams().search){search()}};function addSidebarCrates(crates){if(window.rootPath==="../"||window.rootPath==="./"){var sidebar=document.getElementsByClassName("sidebar-elems")[0];if(sidebar){var div=document.createElement("div");div.className="block crate";div.innerHTML="

Crates

";var ul=document.createElement("ul");div.appendChild(ul);for(var i=0;i"+""+"
"+code.outerHTML+"
";list.appendChild(display)}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function labelForToggleButton(sectionIsCollapsed){if(sectionIsCollapsed){return"+"}return"\u2212"}function onEveryMatchingChild(elem,className,func){if(elem&&className&&func){var length=elem.childNodes.length;var nodes=elem.childNodes;for(var i=0;i"+labelForToggleButton(sectionIsCollapsed)+"
]";return toggle}function createToggle(toggle,otherMessage,fontSize,extraClass,show){var span=document.createElement("span");span.className="toggle-label";if(show){span.style.display="none"}if(!otherMessage){span.innerHTML=" Expand description"}else{span.innerHTML=otherMessage}if(fontSize){span.style.fontSize=fontSize}var mainToggle=toggle.cloneNode(true);mainToggle.appendChild(span);var wrapper=document.createElement("div");wrapper.className="toggle-wrapper";if(!show){addClass(wrapper,"collapsed");var inner=mainToggle.getElementsByClassName("inner");if(inner&&inner.length>0){inner[0].innerHTML="+"}}if(extraClass){addClass(wrapper,extraClass)}wrapper.appendChild(mainToggle);return wrapper}(function(){var toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}var toggle=createSimpleToggle(false);var hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";var hideImplementors=getSettingValue("auto-collapse-implementors")!=="false";var func=function(e){var next=e.nextElementSibling;if(next&&hasClass(next,"item-info")){next=next.nextElementSibling}if(!next){return}if(hasClass(next,"docblock")){var newToggle=toggle.cloneNode(true);insertAfter(newToggle,e.childNodes[e.childNodes.length-1]);if(hideMethodDocs===true&&hasClass(e,"method")===true){collapseDocs(newToggle,"hide")}}};var funcImpl=function(e){var next=e.nextElementSibling;if(next&&hasClass(next,"item-info")){next=next.nextElementSibling}if(next&&hasClass(next,"docblock")){next=next.nextElementSibling}if(!next){return}if(hasClass(e,"impl")&&(next.getElementsByClassName("method").length>0||next.getElementsByClassName("associatedconstant").length>0)){var newToggle=toggle.cloneNode(true);insertAfter(newToggle,e.childNodes[e.childNodes.length-1]);if(hideImplementors===true&&e.parentNode.id==="implementors-list"){collapseDocs(newToggle,"hide")}}};onEachLazy(document.getElementsByClassName("method"),func);onEachLazy(document.getElementsByClassName("associatedconstant"),func);onEachLazy(document.getElementsByClassName("impl"),funcImpl);var impl_call=function(){};if(hideMethodDocs===true){impl_call=function(e,newToggle){if(e.id.match(/^impl(?:-\d+)?$/)===null){if(hasClass(e,"impl")===true){collapseDocs(newToggle,"hide")}}}}var newToggle=document.createElement("a");newToggle.href="javascript:void(0)";newToggle.className="collapse-toggle hidden-default collapsed";newToggle.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items";function toggleClicked(){if(hasClass(this,"collapsed")){removeClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("hidden"),function(x){if(hasClass(x,"content")===false){removeClass(x,"hidden");addClass(x,"x")}},true);this.innerHTML="["+labelForToggleButton(false)+"] Hide undocumented items"}else{addClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("x"),function(x){if(hasClass(x,"content")===false){addClass(x,"hidden");removeClass(x,"x")}},true);this.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items"}}onEachLazy(document.getElementsByClassName("impl-items"),function(e){onEachLazy(e.getElementsByClassName("associatedconstant"),func);var hiddenElems=Array.prototype.slice.call(e.getElementsByClassName("hidden"));var needToggle=hiddenElems.some(function(hiddenElem){return hasClass(hiddenElem,"content")===false&&hasClass(hiddenElem,"docblock")===false});if(needToggle===true){var inner_toggle=newToggle.cloneNode(true);inner_toggle.onclick=toggleClicked;e.insertBefore(inner_toggle,e.firstChild);impl_call(e.previousSibling,inner_toggle)}});var currentType=document.getElementsByClassName("type-decl")[0];var className=null;if(currentType){currentType=currentType.getElementsByClassName("rust")[0];if(currentType){currentType.classList.forEach(function(item){if(item!=="main"){className=item;return true}})}}var showItemDeclarations=getSettingValue("auto-hide-"+className);if(showItemDeclarations===null){if(className==="enum"||className==="macro"){showItemDeclarations="false"}else if(className==="struct"||className==="union"||className==="trait"){showItemDeclarations="true"}else{showItemDeclarations=getSettingValue("auto-hide-declarations")}}showItemDeclarations=showItemDeclarations==="false";function buildToggleWrapper(e){if(hasClass(e,"autohide")){var wrap=e.previousElementSibling;if(wrap&&hasClass(wrap,"toggle-wrapper")){var inner_toggle=wrap.childNodes[0];var extra=e.childNodes[0].tagName==="H3";e.style.display="none";addClass(wrap,"collapsed");onEachLazy(inner_toggle.getElementsByClassName("inner"),function(e){e.innerHTML=labelForToggleButton(true)});onEachLazy(inner_toggle.getElementsByClassName("toggle-label"),function(e){e.style.display="inline-block";if(extra===true){e.innerHTML=" Show "+e.childNodes[0].innerHTML}})}}if(e.parentNode.id==="main"){var otherMessage="";var fontSize;var extraClass;if(hasClass(e,"type-decl")){fontSize="20px";otherMessage=" Show declaration";if(showItemDeclarations===false){extraClass="collapsed"}}else if(hasClass(e,"sub-variant")){otherMessage=" Show fields"}else if(hasClass(e,"non-exhaustive")){otherMessage=" This ";if(hasClass(e,"non-exhaustive-struct")){otherMessage+="struct"}else if(hasClass(e,"non-exhaustive-enum")){otherMessage+="enum"}else if(hasClass(e,"non-exhaustive-variant")){otherMessage+="enum variant"}else if(hasClass(e,"non-exhaustive-type")){otherMessage+="type"}otherMessage+=" is marked as non-exhaustive"}else if(hasClass(e.childNodes[0],"impl-items")){extraClass="marg-left"}e.parentNode.insertBefore(createToggle(toggle,otherMessage,fontSize,extraClass,hasClass(e,"type-decl")===false||showItemDeclarations===true),e);if(hasClass(e,"type-decl")===true&&showItemDeclarations===true){collapseDocs(e.previousSibling.childNodes[0],"toggle")}if(hasClass(e,"non-exhaustive")===true){collapseDocs(e.previousSibling.childNodes[0],"toggle")}}}onEachLazy(document.getElementsByClassName("docblock"),buildToggleWrapper);onEachLazy(document.getElementsByClassName("sub-variant"),buildToggleWrapper);autoCollapse(getSettingValue("collapse")==="true");var pageId=getPageId();if(pageId!==null){expandSection(pageId)}}());function createToggleWrapper(tog){var span=document.createElement("span");span.className="toggle-label";span.style.display="none";span.innerHTML=" Expand attributes";tog.appendChild(span);var wrapper=document.createElement("div");wrapper.className="toggle-wrapper toggle-attributes";wrapper.appendChild(tog);return wrapper}(function(){var itemAttributesFunc=function(){};if(getSettingValue("auto-hide-attributes")!=="false"){itemAttributesFunc=function(x){collapseDocs(x.previousSibling.childNodes[0],"toggle")}}var attributesToggle=createToggleWrapper(createSimpleToggle(false));onEachLazy(main.getElementsByClassName("attributes"),function(i_e){var attr_tog=attributesToggle.cloneNode(true);if(hasClass(i_e,"top-attr")===true){addClass(attr_tog,"top-attr")}i_e.parentNode.insertBefore(attr_tog,i_e);itemAttributesFunc(i_e)})}());(function(){var lineNumbersFunc=function(){};if(getSettingValue("line-numbers")==="true"){lineNumbersFunc=function(x){var count=x.textContent.split("\n").length;var elems=[];for(var i=0;i"+getSearchLoadingText()+"";showSearchResults(search)}var sidebar_menu=document.getElementsByClassName("sidebar-menu")[0];if(sidebar_menu){sidebar_menu.onclick=function(){var sidebar=document.getElementsByClassName("sidebar")[0];if(hasClass(sidebar,"mobile")===true){hideSidebar()}else{showSidebar()}}}if(main){onEachLazy(main.getElementsByClassName("loading-content"),function(e){e.remove()});onEachLazy(main.childNodes,function(e){if(e.tagName==="H2"||e.tagName==="H3"){var nextTagName=e.nextElementSibling.tagName;if(nextTagName=="H2"||nextTagName=="H3"){e.nextElementSibling.style.display="flex"}else{e.nextElementSibling.style.display="block"}}})}function addSearchOptions(crates){var elem=document.getElementById("crate-search");if(!elem){return}var savedCrate=getSettingValue("saved-filter-crate");for(var i=0,len=crates.length;ithe rustdoc book.";var container=document.createElement("div");var shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["T","Focus the theme picker menu"],["↑","Move up in search results"],["↓","Move down in search results"],["ctrl + ↑ / ↓","Switch result tab"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(function(x){return"
"+x[0].split(" ").map(function(y,index){return(index&1)===0?""+y+"":" "+y+" "}).join("")+"
"+x[1]+"
"}).join("");var div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";var infos=["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)","Search multiple things at once by splitting your query with comma (e.g., \ str,u8 or String,struct:Vec,test)","You can look for items with an exact name by putting double quotes around \ - your request: \"string\"","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");var div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;container.appendChild(book_info);container.appendChild(div_shortcuts);container.appendChild(div_infos);popup.appendChild(container);insertAfter(popup,getSearchElement());buildHelperPopup=function(){}}onHashChange(null);window.onhashchange=onHashChange}());window.onunload=function(){} \ No newline at end of file + your request: \"string\"","Look for items inside another one by searching for a path: vec::Vec",].map(function(x){return"

"+x+"

"}).join("");var div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;container.appendChild(book_info);container.appendChild(div_shortcuts);container.appendChild(div_infos);popup.appendChild(container);insertAfter(popup,getSearchElement());buildHelperPopup=function(){}}function loadScript(url){var script=document.createElement('script');script.src=url;document.head.append(script)}function setupSearchLoader(){var searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(window.searchJS)}}addSearchOptions(window.ALL_CRATES);addSidebarCrates(window.ALL_CRATES);search_input.addEventListener("focus",function(){search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});search_input.addEventListener("blur",function(){search_input.placeholder=search_input.origPlaceholder});search_input.removeAttribute('disabled');var crateSearchDropDown=document.getElementById("crate-search");if(crateSearchDropDown){crateSearchDropDown.addEventListener("focus",loadSearch)}var params=getQueryStringParams();if(params.search!==undefined){loadSearch()}}onHashChange(null);window.onhashchange=onHashChange;setupSearchLoader()}()) \ No newline at end of file diff --git a/noscript.css b/noscript.css index 5cbcb9016..b833ff8c7 100644 --- a/noscript.css +++ b/noscript.css @@ -1 +1 @@ - #main>h2+div,#main>h2+h3,#main>h3+div{display:block;}.loading-content{display:none;}#main>h2+div,#main>h3+div{display:block;}#main>h2+h3{display:flex;}#main .impl-items .hidden{display:block !important;} \ No newline at end of file + #main>h2+div,#main>h2+h3,#main>h3+div{display:block;}.loading-content{display:none;}#main>h2+div,#main>h3+div{display:block;}#main>h2+h3{display:flex;}#main .impl-items .hidden{display:block !important;}#main .impl-items h4.hidden{display:flex !important;}#main .attributes{margin-left:0 !important;} \ No newline at end of file diff --git a/prost_example/all.html b/prost_example/all.html new file mode 100644 index 000000000..39425f52b --- /dev/null +++ b/prost_example/all.html @@ -0,0 +1,7 @@ +List of all items in this crate + +

List of all items[] + +

Structs

Functions

+ \ No newline at end of file diff --git a/prost_example/fn.index.html b/prost_example/fn.index.html new file mode 100644 index 000000000..bc98300ed --- /dev/null +++ b/prost_example/fn.index.html @@ -0,0 +1,5 @@ +prost_example::index - Rust + +

Function prost_example::index[][src]

pub(crate) async fn index(msg: ProtoBuf<MyObj>) -> Result<HttpResponse>
+ \ No newline at end of file diff --git a/prost_example/fn.main.html b/prost_example/fn.main.html new file mode 100644 index 000000000..23c52fb4f --- /dev/null +++ b/prost_example/fn.main.html @@ -0,0 +1,5 @@ +prost_example::main - Rust + +

Function prost_example::main[][src]

pub(crate) fn main() -> Result<()>
+ \ No newline at end of file diff --git a/prost_example/index.html b/prost_example/index.html new file mode 100644 index 000000000..371684103 --- /dev/null +++ b/prost_example/index.html @@ -0,0 +1,7 @@ +prost_example - Rust + +

Crate prost_example[][src]

Structs

+
MyObj

Functions

+
index
main
+ \ No newline at end of file diff --git a/prost_example/sidebar-items.js b/prost_example/sidebar-items.js new file mode 100644 index 000000000..86fee7d81 --- /dev/null +++ b/prost_example/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["index",""],["main",""]],"struct":[["MyObj",""]]}); \ No newline at end of file diff --git a/prost_example/struct.MyObj.html b/prost_example/struct.MyObj.html new file mode 100644 index 000000000..b544848d8 --- /dev/null +++ b/prost_example/struct.MyObj.html @@ -0,0 +1,43 @@ +prost_example::MyObj - Rust + +

Struct prost_example::MyObj[][src]

pub struct MyObj {
+    pub number: i32,
+    pub name: String,
+}

+ Fields

number: i32name: String

Trait Implementations

impl Clone for MyObj[src]

impl Debug for MyObj[src]

impl Default for MyObj[src]

impl Message for MyObj[src]

impl PartialEq<MyObj> for MyObj[src]

impl StructuralPartialEq for MyObj[src]

Auto Trait Implementations

impl RefUnwindSafe for MyObj

impl Send for MyObj

impl Sync for MyObj

impl Unpin for MyObj

impl UnwindSafe for MyObj

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

+

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

+

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

+ \ No newline at end of file diff --git a/rustdoc.css b/rustdoc.css index 757de1995..e5412cbdb 100644 --- a/rustdoc.css +++ b/rustdoc.css @@ -1 +1 @@ - @font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular.woff") format('woff');}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:400;src:local('Source Serif Pro'),url("SourceSerifPro-Regular.ttf.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:italic;font-weight:400;src:local('Source Serif Pro Italic'),url("SourceSerifPro-It.ttf.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:700;src:local('Source Serif Pro Bold'),url("SourceSerifPro-Bold.ttf.woff") format('woff');}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular.woff") format('woff');}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold.woff") format('woff');}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html{content:"";}@media (prefers-color-scheme:light){html{content:"light";}}@media (prefers-color-scheme:dark){html{content:"dark";}}body{font:16px/1.4 "Source Serif Pro",serif;margin:0;position:relative;padding:10px 15px 20px 15px;-webkit-font-feature-settings:"kern","liga";-moz-font-feature-settings:"kern","liga";font-feature-settings:"kern","liga";}h1{font-size:1.5em;}h2{font-size:1.4em;}h3{font-size:1.3em;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.notable),h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){font-weight:500;margin:20px 0 15px 0;padding-bottom:6px;}h1.fqn{border-bottom:1px dashed;margin-top:0;}h1.fqn>.in-band>a:hover{text-decoration:underline;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){border-bottom:1px solid;}h3.impl,h3.method,h4.method,h3.type,h4.type,h4.associatedconstant{flex-basis:100%;font-weight:600;margin-top:16px;margin-bottom:10px;position:relative;}h3.impl,h3.method,h3.type{padding-left:15px;}h1,h2,h3,h4,.sidebar,a.source,.search-input,.content table td:first-child>a,.collapse-toggle,div.item-list .out-of-band,#source-sidebar,#sidebar-toggle{font-family:"Fira Sans",sans-serif;}.content ul.crate a.crate{font:16px/1.6 "Fira Sans";}ol,ul{padding-left:25px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.6em;}p{margin:0 0 .6em 0;}summary{outline:none;}code,pre,a.test-arrow{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.1em;}.docblock pre code,.docblock-short pre code,.docblock code.spotlight{padding:0;}.docblock code.spotlight :last-child{padding-bottom:0.6em;}pre{padding:14px;}.source .content pre{padding:20px;}img{max-width:100%;}li{position:relative;}.source .content{margin-top:50px;max-width:none;overflow:visible;margin-left:0px;min-width:70em;}nav.sub{font-size:16px;text-transform:uppercase;}.sidebar{width:200px;position:fixed;left:0;top:0;bottom:0;overflow:auto;}*{scrollbar-width:initial;}.sidebar{scrollbar-width:thin;}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;}.sidebar .block>ul>li{margin-right:-10px;}.content,nav{max-width:960px;}.hidden{display:none !important;}.logo-container{height:100px;width:100px;position:relative;margin:20px auto;display:block;margin-top:10px;}.logo-container>img{max-width:100px;max-height:100px;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;}.sidebar .location{border:1px solid;font-size:17px;margin:30px 10px 20px 10px;text-align:center;word-wrap:break-word;}.sidebar .version{font-size:15px;text-align:center;border-bottom:1px solid;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;}.location:empty{border:none;}.location a:first-child{font-weight:500;}.block{padding:0;margin-bottom:14px;}.block h2,.block h3{margin-top:0;margin-bottom:8px;text-align:center;}.block ul,.block li{margin:0 10px;padding:0;list-style:none;}.block a{display:block;text-overflow:ellipsis;overflow:hidden;line-height:15px;padding:7px 5px;font-size:14px;font-weight:300;transition:border 500ms ease-out;}.sidebar-title{border-top:1px solid;border-bottom:1px solid;text-align:center;font-size:17px;margin-bottom:5px;}.sidebar-links{margin-bottom:15px;}.sidebar-links>a{padding-left:10px;width:100%;}.sidebar-menu{display:none;}.content{padding:15px 0;}.source .content pre.rust{white-space:pre;overflow:auto;padding-left:0;}.rustdoc:not(.source) .example-wrap{display:inline-flex;margin-bottom:10px;position:relative;}.example-wrap{width:100%;}.example-wrap>pre.line-number{overflow:initial;border:1px solid;border-top-left-radius:5px;border-bottom-left-radius:5px;padding:13px 8px;text-align:right;}.rustdoc:not(.source) .example-wrap>pre.rust{width:100%;overflow-x:auto;}.rustdoc:not(.source) .example-wrap>pre{margin:0;}#search{margin-left:230px;position:relative;}#results{position:absolute;right:0;left:0;overflow:auto;}#results>table{width:100%;table-layout:fixed;margin-bottom:40px;}.content pre.line-numbers{float:left;border:none;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.line-numbers span{cursor:pointer;}.docblock-short{overflow-wrap:anywhere;}.docblock-short p{display:inline;}.docblock-short p{overflow:hidden;text-overflow:ellipsis;margin:0;}.docblock code,.docblock-short code{white-space:pre-wrap;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom:1px solid;}#main>.docblock h1{font-size:1.3em;}#main>.docblock h2{font-size:1.15em;}#main>.docblock h3,#main>.docblock h4,#main>.docblock h5{font-size:1em;}#main>h2+div,#main>h2+h3,#main>h3+div{display:none;flex-wrap:wrap;}.docblock h1{font-size:1em;}.docblock h2{font-size:0.95em;}.docblock h3,.docblock h4,.docblock h5{font-size:0.9em;}.docblock{margin-left:24px;position:relative;}.content .out-of-band{float:right;font-size:23px;margin:0px;padding:0px;font-weight:normal;}h3.impl>.out-of-band{font-size:21px;}h4.method>.out-of-band{font-size:19px;}h4>code,h3>code,.invisible>code{max-width:calc(100% - 41px);display:block;}.invisible{width:100%;display:inline-block;}.content .in-band{margin:0px;padding:0px;}.in-band>code{display:inline-block;}#main{position:relative;}#main>.since{top:inherit;font-family:"Fira Sans",sans-serif;}.content table:not(.table-display){border-spacing:0 5px;}.content td{vertical-align:top;}.content td:first-child{padding-right:20px;}.content td p:first-child{margin-top:0;}.content td h1,.content td h2{margin-left:0;font-size:1.1em;}.content tr:first-child td{border-top:0;}.docblock table{margin:.5em 0;width:calc(100% - 2px);border:1px dashed;}.docblock table td{padding:.5em;border:1px dashed;}.docblock table th{padding:.5em;text-align:left;border:1px solid;}.fields+table{margin-bottom:1em;}.content .item-list{list-style-type:none;padding:0;}.content .multi-column{-moz-column-count:5;-moz-column-gap:2.5em;-webkit-column-count:5;-webkit-column-gap:2.5em;column-count:5;column-gap:2.5em;}.content .multi-column li{width:100%;display:inline-block;}.content .method{font-size:1em;position:relative;}.content .method .where,.content .fn .where,.content .where.fmt-newline{display:block;font-size:0.8em;}.content .methods>div:not(.notable-traits){margin-left:40px;margin-bottom:15px;}.content .docblock>.impl-items{margin-left:20px;margin-top:-34px;}.content .docblock>.impl-items>h4{border-bottom:0;}.content .docblock>.impl-items .table-display{margin:0;}.content .docblock>.impl-items table td{padding:0;}.toggle-wrapper.marg-left>.collapse-toggle{left:-24px;}.content .docblock>.impl-items .table-display,.impl-items table td{border:none;}.content .item-info code{font-size:90%;}.content .item-info{position:relative;margin-left:33px;margin-top:-13px;}.sub-variant>div>.item-info{margin-top:initial;}.content .item-info::before{content:'⬑';font-size:25px;position:absolute;top:-6px;left:-19px;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{margin-left:20px;}.content .impl-items .docblock,.content .impl-items .item-info{margin-bottom:.6em;}.content .impl-items>.item-info{margin-left:40px;}.methods>.item-info,.content .impl-items>.item-info{margin-top:-8px;}.impl-items{flex-basis:100%;}#main>.item-info{margin-top:0;}nav:not(.sidebar){border-bottom:1px solid;padding-bottom:10px;margin-bottom:10px;}nav.main{padding:20px 0;text-align:center;}nav.main .current{border-top:1px solid;border-bottom:1px solid;}nav.main .separator{border:1px solid;display:inline-block;height:23px;margin:0 20px;}nav.sum{text-align:right;}nav.sub form{display:inline;}nav.sub,.content{margin-left:230px;}a{text-decoration:none;background:transparent;}.small-section-header:hover>.anchor{display:initial;}.in-band:hover>.anchor,.impl:hover>.anchor{display:inline-block;position:absolute;}.anchor{display:none;position:absolute;left:-7px;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-28px;padding-right:10px;}.anchor:before{content:'\2002\00a7\2002';}.docblock a:not(.srclink):not(.test-arrow):hover,.docblock-short a:not(.srclink):not(.test-arrow):hover,.item-info a{text-decoration:underline;}.invisible>.srclink,h4>code+.srclink,h3>code+.srclink{position:absolute;top:0;right:0;font-size:17px;font-weight:normal;}.block a.current.crate{font-weight:500;}.search-container{position:relative;}.search-container>div{display:inline-flex;width:calc(100% - 63px);}#crate-search{margin-top:5px;padding:6px;padding-right:19px;flex:none;border:0;border-right:0;border-radius:4px 0 0 4px;outline:none;cursor:pointer;border-right:1px solid;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;text-overflow:"";background-repeat:no-repeat;background-color:transparent;background-size:20px;background-position:calc(100% - 1px) 56%;}.search-container>.top-button{position:absolute;right:0;top:10px;}.search-input{-moz-box-sizing:border-box !important;box-sizing:border-box !important;outline:none;border:none;border-radius:1px;margin-top:5px;padding:10px 16px;font-size:17px;transition:border-color 300ms ease;transition:border-radius 300ms ease-in-out;transition:box-shadow 300ms ease-in-out;width:100%;}#crate-search+.search-input{border-radius:0 1px 1px 0;width:calc(100% - 32px);}.search-input:focus{border-radius:2px;border:0;outline:0;}.search-results .desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;display:block;}.search-results a{display:block;}.content .search-results td:first-child{padding-right:0;width:50%;}.content .search-results td:first-child a{padding-right:10px;}.content .search-results td:first-child a:after{clear:both;content:"";display:block;}.content .search-results td:first-child a span{float:left;}tr.result span.primitive::after{content:' (primitive type)';font-style:italic;}tr.result span.keyword::after{content:' (keyword)';font-style:italic;}body.blur>:not(#help){filter:blur(8px);-webkit-filter:blur(8px);opacity:.7;}#help{width:100%;height:100vh;position:fixed;top:0;left:0;display:flex;justify-content:center;align-items:center;}#help>div{flex:0 0 auto;box-shadow:0 0 6px rgba(0,0,0,.2);width:550px;height:auto;border:1px solid;}#help dt{float:left;clear:left;display:block;}#help>div>span{text-align:center;display:block;margin:10px 0;font-size:18px;border-bottom:1px solid #ccc;padding-bottom:4px;margin-bottom:6px;}#help dd{margin:5px 35px;}#help .infos{padding-left:0;}#help h1,#help h2{margin-top:0;}#help>div div{width:50%;float:left;padding:0 20px 20px 17px;;}.stab{display:table;border-width:1px;border-style:solid;padding:3px;margin-bottom:5px;font-size:90%;}.stab p{display:inline;}.stab summary{display:list-item;}.stab .emoji{font-size:1.5em;}.module-item .stab{border-radius:3px;display:inline-block;font-size:80%;line-height:1.2;margin-bottom:0;margin-right:.3em;padding:2px;vertical-align:text-bottom;}.module-item.unstable{opacity:0.65;}.since{font-weight:normal;font-size:initial;position:absolute;right:0;top:0;}.impl-items .since,.impl .since,.methods .since{flex-grow:0;padding-left:12px;padding-right:2px;position:initial;}.impl-items .srclink,.impl .srclink,.methods .srclink{flex-grow:0;font-size:17px;font-weight:normal;}.impl-items code,.impl code,.methods code{flex-grow:1;}.impl-items h4,h4.impl,h3.impl,.methods h3{display:flex;flex-basis:100%;font-size:16px;margin-bottom:12px;justify-content:space-between;}.variants_table{width:100%;}.variants_table tbody tr td:first-child{width:1%;}td.summary-column{width:100%;}.summary{padding-right:0px;}pre.rust .question-mark{font-weight:bold;}a.test-arrow{display:inline-block;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:130%;top:5px;right:5px;z-index:1;}a.test-arrow:hover{text-decoration:none;}.section-header:hover a:before{position:absolute;left:-25px;padding-right:10px;content:'\2002\00a7\2002';}.section-header:hover a{text-decoration:none;}.section-header a{color:inherit;}.collapse-toggle{font-weight:300;position:absolute;left:-23px;top:0;}h3>.collapse-toggle,h4>.collapse-toggle{font-size:0.8em;top:5px;}.toggle-wrapper>.collapse-toggle{left:-24px;margin-top:0px;}.toggle-wrapper{position:relative;margin-top:0;}.toggle-wrapper.collapsed{height:25px;transition:height .2s;margin-bottom:.6em;}.collapse-toggle>.inner{display:inline-block;width:1.2ch;text-align:center;}.collapse-toggle.hidden-default{position:relative;margin-left:20px;}.since+.srclink{display:table-cell;padding-left:10px;}.item-spacer{width:100%;height:12px;}.out-of-band>span.since{position:initial;font-size:20px;margin-right:5px;}.toggle-wrapper>.collapse-toggle{left:0;}.variant+.toggle-wrapper+.docblock>p{margin-top:5px;}.sub-variant,.sub-variant>h3{margin-top:1px !important;}#main>.sub-variant>h3{font-size:15px;margin-left:25px;margin-bottom:5px;}.sub-variant>div{margin-left:20px;margin-bottom:10px;}.sub-variant>div>span{display:block;position:relative;}.toggle-label{display:inline-block;margin-left:4px;margin-top:3px;}.enum>.toggle-wrapper+.docblock,.struct>.toggle-wrapper+.docblock{margin-left:30px;margin-bottom:20px;margin-top:5px;}.docblock>.section-header:first-child{margin-left:15px;margin-top:0;}.docblock>.section-header:first-child:hover>a:before{left:-10px;}.enum>.collapsed,.struct>.collapsed{margin-bottom:25px;}#main>.variant,#main>.structfield{display:block;}.attributes{display:block;margin-top:0px !important;margin-right:0px;margin-bottom:0px !important;margin-left:30px;}.toggle-attributes.collapsed{margin-bottom:0;}.impl-items>.toggle-attributes{margin-left:20px;}.impl-items .attributes{font-weight:500;}:target>code{opacity:1;}.information{position:absolute;left:-25px;margin-top:7px;z-index:1;}.tooltip{position:relative;display:inline-block;cursor:pointer;}.tooltip::after{display:none;text-align:center;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;font-size:16px;}.tooltip.ignore::after{content:"This example is not tested";}.tooltip.compile_fail::after{content:"This example deliberately fails to compile";}.tooltip.should_panic::after{content:"This example panics";}.tooltip.edition::after{content:"This code runs with edition " attr(data-edition);}.tooltip::before{content:" ";position:absolute;top:50%;left:16px;margin-top:-5px;border-width:5px;border-style:solid;display:none;}.tooltip:hover::before,.tooltip:hover::after{display:inline;}.tooltip.compile_fail,.tooltip.should_panic,.tooltip.ignore{font-weight:bold;font-size:20px;}.notable-traits-tooltip{display:inline-block;cursor:pointer;}.notable-traits:hover .notable-traits-tooltiptext,.notable-traits .notable-traits-tooltiptext.force-tooltip{display:inline-block;}.notable-traits .notable-traits-tooltiptext{display:none;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;z-index:10;font-size:16px;cursor:default;position:absolute;border:1px solid;}.notable-traits-tooltip::after{content:"\00a0\00a0\00a0";}.notable-traits .notable,.notable-traits .docblock{margin:0;}.notable-traits .docblock code.content{margin:0;padding:0;font-size:20px;}pre.rust.rust-example-rendered{position:relative;}pre.rust{tab-size:4;-moz-tab-size:4;}.search-failed{text-align:center;margin-top:20px;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#titles{height:35px;}#titles>button{float:left;width:33.3%;text-align:center;font-size:18px;cursor:pointer;border:0;border-top:2px solid;}#titles>button:not(:last-child){margin-right:1px;width:calc(33.3% - 1px);}#titles>button>div.count{display:inline-block;font-size:16px;}.notable-traits{cursor:pointer;z-index:2;margin-left:5px;}h4>.notable-traits{position:absolute;left:-44px;top:2px;}#all-types{text-align:center;border:1px solid;margin:0 10px;margin-bottom:10px;display:block;border-radius:7px;}#all-types>p{margin:5px 0;}#sidebar-toggle{position:fixed;top:30px;left:300px;z-index:10;padding:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;cursor:pointer;font-weight:bold;transition:left .5s;font-size:1.2em;border:1px solid;border-left:0;}#source-sidebar{position:fixed;top:0;bottom:0;left:0;width:300px;z-index:1;overflow:auto;transition:left .5s;border-right:1px solid;}#source-sidebar>.title{font-size:1.5em;text-align:center;border-bottom:1px solid;margin-bottom:6px;}.theme-picker{position:absolute;left:211px;top:19px;}.theme-picker button{outline:none;}#settings-menu,.help-button{position:absolute;top:10px;}#settings-menu{right:0;outline:none;}.help-button{right:30px;font-family:"Fira Sans",sans-serif;text-align:center;font-size:17px;}#theme-picker,#settings-menu,.help-button{padding:4px;width:27px;height:29px;border:1px solid;border-radius:3px;cursor:pointer;}#theme-choices{display:none;position:absolute;left:0;top:28px;border:1px solid;border-radius:3px;z-index:1;cursor:pointer;}#theme-choices>button{border:none;width:100%;padding:4px 8px;text-align:center;background:rgba(0,0,0,0);}#theme-choices>button:not(:first-child){border-top:1px solid;}@media (min-width:701px){.information:first-child>.tooltip{margin-top:16px;}}@media (max-width:700px){body{padding-top:0px;}.rustdoc>.sidebar{height:45px;min-height:40px;margin:0;margin-left:-15px;padding:0 15px;position:static;z-index:11;}.sidebar>.location{float:right;margin:0px;margin-top:2px;padding:3px 10px 1px 10px;min-height:39px;background:inherit;text-align:left;font-size:24px;}.sidebar .location:empty{padding:0;}.sidebar .logo-container{width:35px;height:35px;margin-top:5px;margin-bottom:5px;float:left;margin-left:50px;}.sidebar .logo-container>img{max-width:35px;max-height:35px;}.sidebar-menu{position:fixed;z-index:10;font-size:2rem;cursor:pointer;width:45px;left:0;text-align:center;display:block;border-bottom:1px solid;border-right:1px solid;height:45px;}.rustdoc.source>.sidebar>.sidebar-menu{display:none;}.sidebar-elems{position:fixed;z-index:1;left:0;top:45px;bottom:0;overflow-y:auto;border-right:1px solid;display:none;}.sidebar>.block.version{border-bottom:none;margin-top:12px;}nav.sub{width:calc(100% - 32px);float:right;}.content{margin-left:0px;}#main{margin-top:45px;padding:0;}.content .in-band{width:100%;}.content h4>.out-of-band{position:inherit;}.toggle-wrapper>.collapse-toggle{left:0px;}.toggle-wrapper{height:1.5em;}#search{margin-left:0;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{display:flex;}.anchor{display:none !important;}h1.fqn{overflow:initial;}.theme-picker{left:10px;top:54px;z-index:1;}h4>.notable-traits{position:absolute;left:-22px;top:24px;}#titles>button>div.count{float:left;width:100%;}#titles{height:50px;}.sidebar.mobile{position:fixed;width:100%;margin-left:0;background-color:rgba(0,0,0,0);height:100%;}.sidebar{width:calc(100% + 30px);}.show-it{display:block;width:246px;}.show-it>.block.items{margin:8px 0;}.show-it>.block.items>ul{margin:0;}.show-it>.block.items>ul>li{text-align:center;margin:2px 0;}.show-it>.block.items>ul>li>a{font-size:21px;}#sidebar-filler{position:fixed;left:45px;width:calc(100% - 45px);top:0;height:45px;z-index:-1;border-bottom:1px solid;}.collapse-toggle{left:-20px;}.impl>.collapse-toggle{left:-10px;}#all-types{margin:10px;}#sidebar-toggle{top:100px;width:30px;font-size:1.5rem;text-align:center;padding:0;}#source-sidebar{z-index:11;}#main>.line-numbers{margin-top:0;}.notable-traits .notable-traits-tooltiptext{left:0;top:100%;}.help-button{display:none;}.search-container>div{width:calc(100% - 32px);}}@media print{nav.sub,.content .out-of-band,.collapse-toggle{display:none;}}@media (max-width:416px){#titles,#titles>button{height:73px;}#main{margin-top:100px;}#main>table:not(.table-display) td{word-break:break-word;width:50%;}.search-container>div{display:block;width:calc(100% - 37px);}#crate-search{width:100%;border-radius:4px;border:0;}#crate-search+.search-input{width:calc(100% + 71px);margin-left:-36px;}#theme-picker,#settings-menu{padding:5px;width:31px;height:31px;}#theme-picker{margin-top:-2px;}#settings-menu{top:7px;}}h3.notable{margin:0;margin-bottom:13px;font-size:19px;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px;border-radius:3px;box-shadow:inset 0 -1px 0;cursor:default;}.hidden-by-impl-hider,.hidden-by-usual-hider{display:none !important;}#implementations-list>h3>span.in-band{width:100%;}.table-display{width:100%;border:0;border-collapse:collapse;border-spacing:0;font-size:16px;}.table-display tr td:first-child{padding-right:0;}.table-display tr td:last-child{float:right;}.table-display .out-of-band{position:relative;font-size:19px;display:block;}#implementors-list>.impl-items .table-display .out-of-band{font-size:17px;}.table-display td:hover .anchor{display:block;top:2px;left:-5px;}#main>ul{padding-left:10px;}#main>ul>li{list-style:none;}.non-exhaustive{margin-bottom:1em;}div.children{padding-left:27px;display:none;}div.name{cursor:pointer;position:relative;margin-left:16px;}div.files>a{display:block;padding:0 3px;}div.files>a:hover,div.name:hover{background-color:#a14b4b;}div.name.expand+.children{display:block;}div.name::before{content:"\25B6";padding-left:4px;font-size:0.7em;position:absolute;left:-16px;top:4px;}div.name.expand::before{transform:rotate(90deg);left:-15px;top:2px;}.type-decl>pre>.toggle-wrapper.toggle-attributes.top-attr{margin-left:0 !important;}.type-decl>pre>.docblock.attributes.top-attr{margin-left:1.8em !important;}.type-decl>pre>.toggle-attributes{margin-left:2.2em;}.type-decl>pre>.docblock.attributes{margin-left:4em;} \ No newline at end of file + @font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular.woff2") format("woff2"),url("FiraSans-Regular.woff") format('woff');font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium.woff2") format("woff2"),url("FiraSans-Medium.woff") format('woff');font-display:swap;}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:400;src:local('Source Serif Pro'),url("SourceSerifPro-Regular.ttf.woff") format('woff');font-display:swap;}@font-face {font-family:'Source Serif Pro';font-style:italic;font-weight:400;src:local('Source Serif Pro Italic'),url("SourceSerifPro-It.ttf.woff") format('woff');font-display:swap;}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:700;src:local('Source Serif Pro Bold'),url("SourceSerifPro-Bold.ttf.woff") format('woff');font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular.woff") format('woff');font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold.woff") format('woff');font-display:swap;}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html{content:"";}@media (prefers-color-scheme:light){html{content:"light";}}@media (prefers-color-scheme:dark){html{content:"dark";}}body{font:16px/1.4 "Source Serif Pro",serif;margin:0;position:relative;padding:10px 15px 20px 15px;-webkit-font-feature-settings:"kern","liga";-moz-font-feature-settings:"kern","liga";font-feature-settings:"kern","liga";}h1{font-size:1.5em;}h2{font-size:1.4em;}h3{font-size:1.3em;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.notable),h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){font-weight:500;margin:20px 0 15px 0;padding-bottom:6px;}h1.fqn{border-bottom:1px dashed;margin-top:0;}h1.fqn>.in-band>a:hover{text-decoration:underline;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){border-bottom:1px solid;}h3.impl,h3.method,h4.method,h3.type,h4.type,h4.associatedconstant{flex-basis:100%;font-weight:600;margin-top:16px;margin-bottom:10px;position:relative;}h3.impl,h3.method,h3.type{padding-left:15px;}h1,h2,h3,h4,.sidebar,a.source,.search-input,.content table td:first-child>a,.collapse-toggle,div.item-list .out-of-band,#source-sidebar,#sidebar-toggle,#main>ul.docblock>li>a{font-family:"Fira Sans",Arial,sans-serif;}.content ul.crate a.crate{font-size:16px/1.6;font-family:"Fira Sans",Arial,sans-serif;}ol,ul{padding-left:25px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.6em;}p{margin:0 0 .6em 0;}summary{outline:none;}code,pre,a.test-arrow{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.1em;}.docblock pre code,.docblock-short pre code,.docblock code.spotlight{padding:0;padding-right:1ex;}.docblock code.spotlight :last-child{padding-bottom:0.6em;}pre{padding:14px;}.source .content pre{padding:20px;}img{max-width:100%;}li{position:relative;}.source .content{margin-top:50px;max-width:none;overflow:visible;margin-left:0px;min-width:70em;}nav.sub{font-size:16px;text-transform:uppercase;}.sidebar{width:200px;position:fixed;left:0;top:0;bottom:0;overflow:auto;}*{scrollbar-width:initial;}.sidebar{scrollbar-width:thin;}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;}.sidebar .block>ul>li{margin-right:-10px;}.content,nav{max-width:960px;}.hidden{display:none !important;}.logo-container{height:100px;width:100px;position:relative;margin:20px auto;display:block;margin-top:10px;}.logo-container>img{max-width:100px;max-height:100px;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;}.sidebar .location{border:1px solid;font-size:17px;margin:30px 10px 20px 10px;text-align:center;word-wrap:break-word;}.sidebar .version{font-size:15px;text-align:center;border-bottom:1px solid;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;}.location:empty{border:none;}.location a:first-child{font-weight:500;}.block{padding:0;margin-bottom:14px;}.block h2,.block h3{margin-top:0;margin-bottom:8px;text-align:center;}.block ul,.block li{margin:0 10px;padding:0;list-style:none;}.block a{display:block;text-overflow:ellipsis;overflow:hidden;line-height:15px;padding:7px 5px;font-size:14px;font-weight:300;transition:border 500ms ease-out;}.sidebar-title{border-top:1px solid;border-bottom:1px solid;text-align:center;font-size:17px;margin-bottom:5px;}.sidebar-links{margin-bottom:15px;}.sidebar-links>a{padding-left:10px;width:100%;}.sidebar-menu{display:none;}.content{padding:15px 0;}.source .content pre.rust{white-space:pre;overflow:auto;padding-left:0;}.rustdoc:not(.source) .example-wrap{display:inline-flex;margin-bottom:10px;}.example-wrap{position:relative;width:100%;}.example-wrap>pre.line-number{overflow:initial;border:1px solid;border-top-left-radius:5px;border-bottom-left-radius:5px;padding:13px 8px;text-align:right;}.rustdoc:not(.source) .example-wrap>pre.rust{width:100%;overflow-x:auto;}.rustdoc:not(.source) .example-wrap>pre{margin:0;}#search{margin-left:230px;position:relative;}#results{position:absolute;right:0;left:0;overflow:auto;}#results>table{width:100%;table-layout:fixed;margin-bottom:40px;}.content pre.line-numbers{float:left;border:none;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.line-numbers span{cursor:pointer;}.docblock-short{overflow-wrap:anywhere;}.docblock-short p{display:inline;}.docblock-short p{overflow:hidden;text-overflow:ellipsis;margin:0;}.docblock-short code{white-space:pre-wrap;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom:1px solid;}#main>.docblock h1{font-size:1.3em;}#main>.docblock h2{font-size:1.15em;}#main>.docblock h3,#main>.docblock h4,#main>.docblock h5{font-size:1em;}#main>h2+div,#main>h2+h3,#main>h3+div{display:none;flex-wrap:wrap;}.docblock h1{font-size:1em;}.docblock h2{font-size:0.95em;}.docblock h3,.docblock h4,.docblock h5{font-size:0.9em;}.docblock{margin-left:24px;position:relative;}.content .out-of-band{float:right;font-size:23px;margin:0px;padding:0px;font-weight:normal;}h3.impl>.out-of-band{font-size:21px;}h4.method>.out-of-band{font-size:19px;}h4>code,h3>code,.invisible>code{max-width:calc(100% - 41px);display:block;}.invisible{width:100%;display:inline-block;}.content .in-band{margin:0px;padding:0px;}.in-band>code{display:inline-block;}#main{position:relative;}#main>.since{top:inherit;font-family:"Fira Sans",Arial,sans-serif;}.content table:not(.table-display){border-spacing:0 5px;}.content td{vertical-align:top;}.content td:first-child{padding-right:20px;}.content td p:first-child{margin-top:0;}.content td h1,.content td h2{margin-left:0;font-size:1.1em;}.content tr:first-child td{border-top:0;}.docblock table{margin:.5em 0;width:calc(100% - 2px);border:1px dashed;}.docblock table td{padding:.5em;border:1px dashed;}.docblock table th{padding:.5em;text-align:left;border:1px solid;}.fields+table{margin-bottom:1em;}.content .item-list{list-style-type:none;padding:0;}.content .multi-column{-moz-column-count:5;-moz-column-gap:2.5em;-webkit-column-count:5;-webkit-column-gap:2.5em;column-count:5;column-gap:2.5em;}.content .multi-column li{width:100%;display:inline-block;}.content .method{font-size:1em;position:relative;}.content .method .where,.content .fn .where,.content .where.fmt-newline{display:block;font-size:0.8em;}.content .methods>div:not(.notable-traits){margin-left:40px;margin-bottom:15px;}.content .docblock>.impl-items{margin-left:20px;margin-top:-34px;}.content .docblock>.impl-items>h4{border-bottom:0;}.content .docblock>.impl-items .table-display{margin:0;}.content .docblock>.impl-items table td{padding:0;}.toggle-wrapper.marg-left>.collapse-toggle{left:-24px;}.content .docblock>.impl-items .table-display,.impl-items table td{border:none;}.content .item-info code{font-size:90%;}.content .item-info{position:relative;margin-left:33px;margin-top:-13px;}.sub-variant>div>.item-info{margin-top:initial;}.content .item-info::before{content:'⬑';font-size:25px;position:absolute;top:-6px;left:-19px;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{margin-left:20px;}.content .impl-items .docblock,.content .impl-items .item-info{margin-bottom:.6em;}.content .impl-items>.item-info{margin-left:40px;}.methods>.item-info,.content .impl-items>.item-info{margin-top:-8px;}.impl-items{flex-basis:100%;}#main>.item-info{margin-top:0;}nav:not(.sidebar){border-bottom:1px solid;padding-bottom:10px;margin-bottom:10px;}nav.main{padding:20px 0;text-align:center;}nav.main .current{border-top:1px solid;border-bottom:1px solid;}nav.main .separator{border:1px solid;display:inline-block;height:23px;margin:0 20px;}nav.sum{text-align:right;}nav.sub form{display:inline;}nav.sub,.content{margin-left:230px;}a{text-decoration:none;background:transparent;}.small-section-header:hover>.anchor{display:initial;}.in-band:hover>.anchor,.impl:hover>.anchor{display:inline-block;position:absolute;}.anchor{display:none;position:absolute;left:-7px;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-28px;padding-right:10px;}.anchor:before{content:'\2002\00a7\2002';}.docblock a:not(.srclink):not(.test-arrow):hover,.docblock-short a:not(.srclink):not(.test-arrow):hover,.item-info a{text-decoration:underline;}.invisible>.srclink,h4>code+.srclink,h3>code+.srclink{position:absolute;top:0;right:0;font-size:17px;font-weight:normal;}.block a.current.crate{font-weight:500;}.search-container{position:relative;}.search-container>div{display:inline-flex;width:calc(100% - 63px);}#crate-search{min-width:115px;margin-top:5px;padding:6px;padding-right:19px;flex:none;border:0;border-right:0;border-radius:4px 0 0 4px;outline:none;cursor:pointer;border-right:1px solid;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;text-overflow:"";background-repeat:no-repeat;background-color:transparent;background-size:20px;background-position:calc(100% - 1px) 56%;}.search-container>.top-button{position:absolute;right:0;top:10px;}.search-input{-moz-box-sizing:border-box !important;box-sizing:border-box !important;outline:none;border:none;border-radius:1px;margin-top:5px;padding:10px 16px;font-size:17px;transition:border-color 300ms ease;transition:border-radius 300ms ease-in-out;transition:box-shadow 300ms ease-in-out;width:100%;}#crate-search+.search-input{border-radius:0 1px 1px 0;width:calc(100% - 32px);}.search-input:focus{border-radius:2px;border:0;outline:0;}.search-results .desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;display:block;}.search-results a{display:block;}.content .search-results td:first-child{padding-right:0;width:50%;}.content .search-results td:first-child a{padding-right:10px;}.content .search-results td:first-child a:after{clear:both;content:"";display:block;}.content .search-results td:first-child a span{float:left;}tr.result span.primitive::after{content:' (primitive type)';font-style:italic;}tr.result span.keyword::after{content:' (keyword)';font-style:italic;}body.blur>:not(#help){filter:blur(8px);-webkit-filter:blur(8px);opacity:.7;}#help{width:100%;height:100vh;position:fixed;top:0;left:0;display:flex;justify-content:center;align-items:center;}#help>div{flex:0 0 auto;box-shadow:0 0 6px rgba(0,0,0,.2);width:550px;height:auto;border:1px solid;}#help dt{float:left;clear:left;display:block;margin-right:0.5rem;}#help>div>span{text-align:center;display:block;margin:10px 0;font-size:18px;border-bottom:1px solid #ccc;padding-bottom:4px;margin-bottom:6px;}#help dd{margin:5px 35px;}#help .infos{padding-left:0;}#help h1,#help h2{margin-top:0;}#help>div div{width:50%;float:left;padding:0 20px 20px 17px;;}.stab{display:table;border-width:1px;border-style:solid;padding:3px;margin-bottom:5px;font-size:90%;}.stab p{display:inline;}.stab summary{display:list-item;}.stab .emoji{font-size:1.5em;}.module-item .stab{border-radius:3px;display:inline-block;font-size:80%;line-height:1.2;margin-bottom:0;margin-right:.3em;padding:2px;vertical-align:text-bottom;}.module-item.unstable{opacity:0.65;}.since{font-weight:normal;font-size:initial;position:absolute;right:0;top:0;}.impl-items .since,.impl .since,.methods .since{flex-grow:0;padding-left:12px;padding-right:2px;position:initial;}.impl-items .srclink,.impl .srclink,.methods .srclink{flex-grow:0;font-size:17px;font-weight:normal;}.impl-items code,.impl code,.methods code{flex-grow:1;}.impl-items h4,h4.impl,h3.impl,.methods h3{display:flex;flex-basis:100%;font-size:16px;margin-bottom:12px;justify-content:space-between;}.variants_table{width:100%;}.variants_table tbody tr td:first-child{width:1%;}td.summary-column{width:100%;}.summary{padding-right:0px;}pre.rust .question-mark{font-weight:bold;}a.test-arrow{display:inline-block;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:130%;top:5px;right:5px;z-index:1;}a.test-arrow:hover{text-decoration:none;}.section-header:hover a:before{position:absolute;left:-25px;padding-right:10px;content:'\2002\00a7\2002';}.section-header:hover a{text-decoration:none;}.section-header a{color:inherit;}.collapse-toggle{font-weight:300;position:absolute;left:-23px;top:0;}h3>.collapse-toggle,h4>.collapse-toggle{font-size:0.8em;top:5px;}.toggle-wrapper>.collapse-toggle{left:-24px;margin-top:0px;}.toggle-wrapper{position:relative;margin-top:0;}.toggle-wrapper.collapsed{height:25px;transition:height .2s;margin-bottom:.6em;}.collapse-toggle>.inner{display:inline-block;width:1.2ch;text-align:center;}.collapse-toggle.hidden-default{position:relative;margin-left:20px;}.since+.srclink{display:table-cell;padding-left:10px;}.item-spacer{width:100%;height:12px;}.out-of-band>span.since{position:initial;font-size:20px;margin-right:5px;}.toggle-wrapper>.collapse-toggle{left:0;}.variant+.toggle-wrapper+.docblock>p{margin-top:5px;}.sub-variant,.sub-variant>h3{margin-top:1px !important;}#main>.sub-variant>h3{font-size:15px;margin-left:25px;margin-bottom:5px;}.sub-variant>div{margin-left:20px;margin-bottom:10px;}.sub-variant>div>span{display:block;position:relative;}.toggle-label{display:inline-block;margin-left:4px;margin-top:3px;}.enum>.toggle-wrapper+.docblock,.struct>.toggle-wrapper+.docblock{margin-left:30px;margin-bottom:20px;margin-top:5px;}.docblock>.section-header:first-child{margin-left:15px;margin-top:0;}.docblock>.section-header:first-child:hover>a:before{left:-10px;}.enum>.collapsed,.struct>.collapsed{margin-bottom:25px;}#main>.variant,#main>.structfield{display:block;}.attributes{display:block;margin-top:0px !important;margin-right:0px;margin-bottom:0px !important;margin-left:30px;}.toggle-attributes.collapsed{margin-bottom:0;}.impl-items>.toggle-attributes{margin-left:20px;}.impl-items .attributes{font-weight:500;}:target>code{opacity:1;}.information{position:absolute;left:-25px;margin-top:7px;z-index:1;}.tooltip{position:relative;display:inline-block;cursor:pointer;}.tooltip::after{display:none;text-align:center;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;font-size:16px;}.tooltip.ignore::after{content:"This example is not tested";}.tooltip.compile_fail::after{content:"This example deliberately fails to compile";}.tooltip.should_panic::after{content:"This example panics";}.tooltip.edition::after{content:"This code runs with edition " attr(data-edition);}.tooltip::before{content:" ";position:absolute;top:50%;left:16px;margin-top:-5px;border-width:5px;border-style:solid;display:none;}.tooltip:hover::before,.tooltip:hover::after{display:inline;}.tooltip.compile_fail,.tooltip.should_panic,.tooltip.ignore{font-weight:bold;font-size:20px;}.notable-traits-tooltip{display:inline-block;cursor:pointer;}.notable-traits:hover .notable-traits-tooltiptext,.notable-traits .notable-traits-tooltiptext.force-tooltip{display:inline-block;}.notable-traits .notable-traits-tooltiptext{display:none;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;z-index:10;font-size:16px;cursor:default;position:absolute;border:1px solid;}.notable-traits-tooltip::after{content:"\00a0\00a0\00a0";}.notable-traits .notable,.notable-traits .docblock{margin:0;}.notable-traits .docblock code.content{margin:0;padding:0;font-size:20px;}pre.rust.rust-example-rendered{position:relative;}pre.rust{tab-size:4;-moz-tab-size:4;}.search-failed{text-align:center;margin-top:20px;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#titles{height:35px;}#titles>button{float:left;width:33.3%;text-align:center;font-size:18px;cursor:pointer;border:0;border-top:2px solid;}#titles>button:not(:last-child){margin-right:1px;width:calc(33.3% - 1px);}#titles>button>div.count{display:inline-block;font-size:16px;}.notable-traits{cursor:pointer;z-index:2;margin-left:5px;}h4>.notable-traits{position:absolute;left:-44px;top:2px;}#all-types{text-align:center;border:1px solid;margin:0 10px;margin-bottom:10px;display:block;border-radius:7px;}#all-types>p{margin:5px 0;}#sidebar-toggle{position:fixed;top:30px;left:300px;z-index:10;padding:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;cursor:pointer;font-weight:bold;transition:left .5s;font-size:1.2em;border:1px solid;border-left:0;}#source-sidebar{position:fixed;top:0;bottom:0;left:0;width:300px;z-index:1;overflow:auto;transition:left .5s;border-right:1px solid;}#source-sidebar>.title{font-size:1.5em;text-align:center;border-bottom:1px solid;margin-bottom:6px;}.theme-picker{position:absolute;left:211px;top:19px;}.theme-picker button{outline:none;}#settings-menu,.help-button{position:absolute;top:10px;}#settings-menu{right:0;outline:none;}.help-button{right:30px;font-family:"Fira Sans",Arial,sans-serif;text-align:center;font-size:17px;}#theme-picker,#settings-menu,.help-button{padding:4px;width:27px;height:29px;border:1px solid;border-radius:3px;cursor:pointer;}#theme-choices{display:none;position:absolute;left:0;top:28px;border:1px solid;border-radius:3px;z-index:1;cursor:pointer;}#theme-choices>button{border:none;width:100%;padding:4px 8px;text-align:center;background:rgba(0,0,0,0);}#theme-choices>button:not(:first-child){border-top:1px solid;}@media (min-width:701px){.information:first-child>.tooltip{margin-top:16px;}}@media (max-width:700px){body{padding-top:0px;}.rustdoc>.sidebar{height:45px;min-height:40px;margin:0;margin-left:-15px;padding:0 15px;position:static;z-index:11;}.sidebar>.location{float:right;margin:0px;margin-top:2px;padding:3px 10px 1px 10px;min-height:39px;background:inherit;text-align:left;font-size:24px;}.sidebar .location:empty{padding:0;}.sidebar .logo-container{width:35px;height:35px;margin-top:5px;margin-bottom:5px;float:left;margin-left:50px;}.sidebar .logo-container>img{max-width:35px;max-height:35px;}.sidebar-menu{position:fixed;z-index:10;font-size:2rem;cursor:pointer;width:45px;left:0;text-align:center;display:block;border-bottom:1px solid;border-right:1px solid;height:45px;}.rustdoc.source>.sidebar>.sidebar-menu{display:none;}.sidebar-elems{position:fixed;z-index:1;left:0;top:45px;bottom:0;overflow-y:auto;border-right:1px solid;display:none;}.sidebar>.block.version{border-bottom:none;margin-top:12px;margin-bottom:0;}nav.sub{width:calc(100% - 32px);float:right;}.content{margin-left:0px;}#main,#search{margin-top:45px;padding:0;}.content .in-band{width:100%;}.content h4>.out-of-band{position:inherit;}.toggle-wrapper>.collapse-toggle{left:0px;}.toggle-wrapper{height:1.5em;}#search{margin-left:0;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{display:flex;}.anchor{display:none !important;}h1.fqn{overflow:initial;}.theme-picker{left:10px;top:54px;z-index:1;}h4>.notable-traits{position:absolute;left:-22px;top:24px;}#titles>button>div.count{float:left;width:100%;}#titles{height:50px;}.sidebar.mobile{position:fixed;width:100%;margin-left:0;background-color:rgba(0,0,0,0);height:100%;}.sidebar.mobile>div.version{overflow:hidden;max-height:33px;}.sidebar{width:calc(100% + 30px);}.show-it{display:block;width:246px;}.show-it>.block.items{margin:8px 0;}.show-it>.block.items>ul{margin:0;}.show-it>.block.items>ul>li{text-align:center;margin:2px 0;}.show-it>.block.items>ul>li>a{font-size:21px;}#sidebar-filler{position:fixed;left:45px;width:calc(100% - 45px);top:0;height:45px;z-index:-1;border-bottom:1px solid;}.collapse-toggle{left:-20px;}.impl>.collapse-toggle{left:-10px;}#all-types{margin:10px;}#sidebar-toggle{top:100px;width:30px;font-size:1.5rem;text-align:center;padding:0;}#source-sidebar{z-index:11;}#main>.line-numbers{margin-top:0;}.notable-traits .notable-traits-tooltiptext{left:0;top:100%;}.help-button{display:none;}.search-container>div{width:calc(100% - 32px);}}@media print{nav.sub,.content .out-of-band,.collapse-toggle{display:none;}}@media (max-width:464px){#titles,#titles>button{height:73px;}#main,#search{margin-top:100px;}#main>table:not(.table-display) td{word-break:break-word;width:50%;}.search-container>div{display:block;width:calc(100% - 37px);}#crate-search{width:100%;border-radius:4px;border:0;}#crate-search+.search-input{width:calc(100% + 71px);margin-left:-36px;}#theme-picker,#settings-menu{padding:5px;width:31px;height:31px;}#theme-picker{margin-top:-2px;}#settings-menu{top:7px;}.docblock{margin-left:12px;}}h3.notable{margin:0;margin-bottom:13px;font-size:19px;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px;border-radius:3px;box-shadow:inset 0 -1px 0;cursor:default;}.hidden-by-impl-hider,.hidden-by-usual-hider{display:none !important;}#implementations-list>h3>span.in-band{width:100%;}.table-display{width:100%;border:0;border-collapse:collapse;border-spacing:0;font-size:16px;}.table-display tr td:first-child{padding-right:0;}.table-display tr td:last-child{float:right;}.table-display .out-of-band{position:relative;font-size:19px;display:block;}#implementors-list>.impl-items .table-display .out-of-band{font-size:17px;}.table-display td:hover .anchor{display:block;top:2px;left:-5px;}#main>ul{padding-left:10px;}#main>ul>li{list-style:none;}.non-exhaustive{margin-bottom:1em;}div.children{padding-left:27px;display:none;}div.name{cursor:pointer;position:relative;margin-left:16px;}div.files>a{display:block;padding:0 3px;}div.files>a:hover,div.name:hover{background-color:#a14b4b;}div.name.expand+.children{display:block;}div.name::before{content:"\25B6";padding-left:4px;font-size:0.7em;position:absolute;left:-16px;top:4px;}div.name.expand::before{transform:rotate(90deg);left:-15px;top:2px;}.type-decl>pre>.toggle-wrapper.toggle-attributes.top-attr{margin-left:0 !important;}.type-decl>pre>.docblock.attributes.top-attr{margin-left:1.8em !important;}.type-decl>pre>.toggle-attributes{margin-left:2.2em;}.type-decl>pre>.docblock.attributes{margin-left:4em;} \ No newline at end of file diff --git a/search-index.js b/search-index.js index 6a25bc462..a5961e892 100644 --- a/search-index.js +++ b/search-index.js @@ -1,4 +1,10 @@ var searchIndex = JSON.parse('{\ -"actix_redis":{"doc":"Redis integration for Actix and session store for Actix …","i":[[4,"SameSite","actix_redis","The SameSite cookie attribute.",null,null],[13,"Strict","","The \\\"Strict\\\" SameSite attribute.",0,null],[13,"Lax","","The \\\"Lax\\\" SameSite attribute.",0,null],[13,"None","","The \\\"None\\\" SameSite attribute.",0,null],[4,"RespError","","",null,null],[13,"Internal","","A non-specific internal error that prevented an operation …",1,null],[13,"IO","","An IO error occurred",1,null],[13,"RESP","","A RESP parsing/serialising error occurred",1,null],[13,"Remote","","A remote error",1,null],[13,"Connection","","Error creating a connection, or an error with a …",1,null],[13,"Unexpected","","An unexpected error. In this context \\\"unexpected\\\" means …",1,null],[4,"RespValue","","A single RESP value, this owns the data that is …",null,null],[13,"Nil","","",2,null],[13,"Array","","Zero, one or more other RespValues.",2,null],[13,"BulkString","","A bulk string. In Redis terminology a string is a …",2,null],[13,"Error","","An error from the Redis server",2,null],[13,"Integer","","Redis documentation defines an integer as being a signed …",2,null],[13,"SimpleString","","",2,null],[3,"Command","","Command for send data to Redis",null,null],[12,"0","","",3,null],[3,"RedisActor","","Redis communication actor",null,null],[3,"RedisSession","","Use redis as session storage.",null,null],[4,"Error","","General purpose actix redis error",null,null],[13,"Redis","","",4,null],[13,"NotConnected","","Receiving message during reconnecting",4,null],[13,"Disconnected","","Cancel all waters when connection get dropped",4,null],[11,"from","","",0,[[]]],[11,"into","","",0,[[]]],[11,"to_owned","","",0,[[]]],[11,"clone_into","","",0,[[]]],[11,"to_string","","",0,[[],["string",3]]],[11,"borrow","","",0,[[]]],[11,"borrow_mut","","",0,[[]]],[11,"try_from","","",0,[[],["result",4]]],[11,"try_into","","",0,[[],["result",4]]],[11,"type_id","","",0,[[],["typeid",3]]],[11,"vzip","","",0,[[]]],[11,"equivalent","","",0,[[]]],[11,"get_hash","","",0,[[]]],[11,"from","","",1,[[]]],[11,"into","","",1,[[]]],[11,"to_string","","",1,[[],["string",3]]],[11,"borrow","","",1,[[]]],[11,"borrow_mut","","",1,[[]]],[11,"try_from","","",1,[[],["result",4]]],[11,"try_into","","",1,[[],["result",4]]],[11,"type_id","","",1,[[],["typeid",3]]],[11,"vzip","","",1,[[]]],[11,"from","","",2,[[]]],[11,"into","","",2,[[]]],[11,"to_owned","","",2,[[]]],[11,"clone_into","","",2,[[]]],[11,"borrow","","",2,[[]]],[11,"borrow_mut","","",2,[[]]],[11,"try_from","","",2,[[],["result",4]]],[11,"try_into","","",2,[[],["result",4]]],[11,"type_id","","",2,[[],["typeid",3]]],[11,"vzip","","",2,[[]]],[11,"equivalent","","",2,[[]]],[11,"from","","",3,[[]]],[11,"into","","",3,[[]]],[11,"borrow","","",3,[[]]],[11,"borrow_mut","","",3,[[]]],[11,"try_from","","",3,[[],["result",4]]],[11,"try_into","","",3,[[],["result",4]]],[11,"type_id","","",3,[[],["typeid",3]]],[11,"vzip","","",3,[[]]],[11,"from","","",5,[[]]],[11,"into","","",5,[[]]],[11,"borrow","","",5,[[]]],[11,"borrow_mut","","",5,[[]]],[11,"try_from","","",5,[[],["result",4]]],[11,"try_into","","",5,[[],["result",4]]],[11,"type_id","","",5,[[],["typeid",3]]],[11,"vzip","","",5,[[]]],[11,"from","","",6,[[]]],[11,"into","","",6,[[]]],[11,"borrow","","",6,[[]]],[11,"borrow_mut","","",6,[[]]],[11,"try_from","","",6,[[],["result",4]]],[11,"try_into","","",6,[[],["result",4]]],[11,"type_id","","",6,[[],["typeid",3]]],[11,"vzip","","",6,[[]]],[11,"from","","",4,[[]]],[11,"into","","",4,[[]]],[11,"to_string","","",4,[[],["string",3]]],[11,"borrow","","",4,[[]]],[11,"borrow_mut","","",4,[[]]],[11,"try_from","","",4,[[],["result",4]]],[11,"try_into","","",4,[[],["result",4]]],[11,"type_id","","",4,[[],["typeid",3]]],[11,"vzip","","",4,[[]]],[11,"from_resp_int","","",2,[[["respvalue",4]],[["result",4],["error",4],["respvalue",4]]]],[11,"fmt","","",1,[[["formatter",3]],[["result",4],["error",3]]]],[11,"from","","",2,[[["string",3]],["respvalue",4]]],[11,"from","","",2,[[],["respvalue",4]]],[11,"from","","",2,[[["string",3]],["respvalue",4]]],[11,"from","","",2,[[],["respvalue",4]]],[11,"from","","",2,[[["global",3],["vec",3]],["respvalue",4]]],[11,"from","","",2,[[["arc",3]],["respvalue",4]]],[11,"from","","",1,[[["trysenderror",3]],["error",4]]],[11,"from","","",1,[[["error",3]],["error",4]]],[11,"from","","",2,[[],["respvalue",4]]],[11,"source","","",1,[[],[["error",8],["option",4]]]],[11,"clone","","",2,[[],["respvalue",4]]],[11,"eq","","",2,[[["respvalue",4]]]],[11,"ne","","",2,[[["respvalue",4]]]],[11,"fmt","","",2,[[["formatter",3]],[["result",4],["error",3]]]],[11,"fmt","","",1,[[["formatter",3]],[["result",4],["error",3]]]],[11,"fmt","","",0,[[["formatter",3]],[["result",4],["error",3]]]],[11,"hash","","",0,[[]]],[11,"clone","","",0,[[],["samesite",4]]],[11,"eq","","",0,[[["samesite",4]]]],[11,"fmt","","",0,[[["formatter",3]],[["result",4],["error",3]]]],[11,"from","","",4,[[["error",4]],["error",4]]],[11,"fmt","","",3,[[["formatter",3]],["result",6]]],[11,"fmt","","",4,[[["formatter",3]],["result",6]]],[11,"fmt","","",4,[[["formatter",3]],["result",6]]],[11,"source","","",4,[[],[["option",4],["error",8]]]],[11,"started","","",5,[[["context",3]]]],[11,"restarting","","",5,[[]]],[11,"handle","","",5,[[["command",3]]]],[11,"handle","","",5,[[["respvalue",4],["resperror",4],["result",4]]]],[11,"error","","",5,[[["error",3]],["running",4]]],[11,"new_transform","","",6,[[]]],[11,"is_strict","","Returns true if self is SameSite::Strict and false …",0,[[]]],[11,"is_lax","","Returns true if self is SameSite::Lax and false otherwise.",0,[[]]],[11,"is_none","","Returns true if self is SameSite::None and false …",0,[[]]],[11,"append","","Convenience function for building dynamic Redis commands …",2,[[],["respvalue",4]]],[11,"push","","Push item to Resp array",2,[[]]],[11,"start","","Start new Supervisor with RedisActor.",5,[[["into",8],["string",3]],[["redisactor",3],["addr",3]]]],[11,"new","","Create new redis session backend",6,[[["into",8],["string",3]],["redissession",3]]],[11,"ttl","","Set time to live in seconds for session value.",6,[[]]],[11,"cookie_name","","Set custom cookie name for session ID.",6,[[]]],[11,"cookie_path","","Set custom cookie path.",6,[[]]],[11,"cookie_domain","","Set custom cookie domain.",6,[[]]],[11,"cookie_secure","","Set custom cookie secure.",6,[[]]],[11,"cookie_max_age","","Set custom cookie max-age.",6,[[]]],[11,"cookie_same_site","","Set custom cookie SameSite attribute.",6,[[["samesite",4]]]],[11,"cookie_http_only","","Set custom cookie HttpOnly policy.",6,[[]]],[11,"cache_keygen","","Set a custom cache key generation strategy, expecting …",6,[[["box",3],["fn",8]]]]],"p":[[4,"SameSite"],[4,"RespError"],[4,"RespValue"],[3,"Command"],[4,"Error"],[3,"RedisActor"],[3,"RedisSession"]]}\ +"actix_cors":{"doc":"Cross-Origin Resource Sharing (CORS) controls for Actix …","t":[3,4,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["Cors","CorsError","WildcardOrigin","MissingOrigin","MissingRequestMethod","BadRequestMethod","BadRequestHeaders","OriginNotAllowed","MethodNotAllowed","HeadersNotAllowed","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_owned","clone_into","to_string","borrow","borrow_mut","try_from","try_into","type_id","vzip","clone","default","fmt","fmt","fmt","new_transform","status_code","error_response","permissive","allow_any_origin","allowed_origin","allowed_origin_fn","allow_any_method","allowed_methods","allow_any_header","allowed_header","allowed_headers","expose_any_header","expose_headers","max_age","send_wildcard","supports_credentials","disable_vary_header","disable_preflight"],"q":["actix_cors","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Builder for CORS middleware.","Errors that can occur when processing CORS guarded …","Allowed origin argument must not be wildcard (*).","Request header Origin is required but was not provided.","Request header Access-Control-Request-Method is required …","Request header Access-Control-Request-Method has an …","Request header Access-Control-Request-Headers has an …","Origin is not allowed to make this request.","Request method is not allowed.","One or more request headers are not allowed.","","","","","","","","","","","","","","","","","","","","","A restrictive (security paranoid) set of defaults.","","","","","","","A very permissive set of default for quick development. …","Resets allowed origin list to a state where any origin is …","Add an origin that is allowed to make requests.","Determinate allowed origins by processing requests which …","Resets allowed methods list to all methods.","Set a list of methods which allowed origins can perform.","Resets allowed request header list to a state where any …","Add an allowed request header.","Set a list of request header field names which can be …","Resets exposed response header list to a state where any …","Set a list of headers which are safe to expose to the API …","Set a maximum time (in seconds) for which this CORS …","Set to use wildcard origins.","Allows users to make authenticated requests","Disable Vary header support.","Disable support for preflight requests."],"i":[0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],"f":[null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[],["corserror",4]],[[],["cors",3]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[],["statuscode",3]],[[],["httpresponse",3]],[[]],[[],["cors",3]],[[["str",15]],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]],[[],["cors",3]]],"p":[[4,"CorsError"],[3,"Cors"]]},\ +"actix_identity":{"doc":"Request identity service for Actix applications.","t":[3,11,11,11,8,10,8,16,16,10,10,3,11,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["Identity","identity","remember","forget","RequestIdentity","get_identity","IdentityPolicy","Future","ResponseFuture","from_request","to_response","IdentityService","new","CookieIdentityPolicy","new","path","name","domain","secure","max_age","max_age_time","http_only","same_site","visit_deadline","login_deadline","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from_request","to_response","clone","new_transform","from_request"],"q":["actix_identity","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["The extractor type to obtain your identity from a request.","Return the claimed identity of the user associated …","Remember identity.","This method is used to ‘forget’ the current identity …","Helper trait that allows to get Identity.","","Identity policy definition.","The return type of the middleware","The return type of the middleware","Parse the session from request and load data from a …","Write changes to response","Request identity middleware","Create new identity service with specified backend.","Use cookies for request identity storage.","Construct new CookieIdentityPolicy instance.","Sets the path field in the session cookie being built.","Sets the name field in the session cookie being built.","Sets the domain field in the session cookie being built.","Sets the secure field in the session cookie being built.","Sets the max-age field in the session cookie being built …","Sets the max-age field in the session cookie being built …","Sets the http_only field in the session cookie being …","Sets the same_site field in the session cookie being …","Accepts only users whose cookie has been seen before the …","Accepts only users which has been authenticated before …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,1,1,1,0,2,0,3,3,3,3,0,4,0,5,5,5,5,5,5,5,5,5,5,5,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,1,4,1],"f":[null,[[],[["string",3],["option",4]]],[[["string",3]]],[[]],null,[[],[["string",3],["option",4]]],null,null,null,[[["servicerequest",3]]],[[["string",3],["option",4],["bool",15],["serviceresponse",3]]],null,[[]],null,[[],["cookieidentitypolicy",3]],[[["into",8],["string",3]],["cookieidentitypolicy",3]],[[["into",8],["string",3]],["cookieidentitypolicy",3]],[[["into",8],["string",3]],["cookieidentitypolicy",3]],[[["bool",15]],["cookieidentitypolicy",3]],[[["i64",15]],["cookieidentitypolicy",3]],[[["duration",3]],["cookieidentitypolicy",3]],[[["bool",15]]],[[["samesite",4]]],[[["duration",3]],["cookieidentitypolicy",3]],[[["duration",3]],["cookieidentitypolicy",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[["servicerequest",3]]],[[["string",3],["option",4],["bool",15],["serviceresponse",3]]],[[],["identity",3]],[[]],[[["httprequest",3],["payload",4]]]],"p":[[3,"Identity"],[8,"RequestIdentity"],[8,"IdentityPolicy"],[3,"IdentityService"],[3,"CookieIdentityPolicy"]]},\ +"actix_protobuf":{"doc":"","t":[4,13,13,13,13,13,3,12,3,11,3,11,11,8,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["ProtoBufPayloadError","Overflow","ContentType","Serialize","Deserialize","Payload","ProtoBuf","0","ProtoBufConfig","limit","ProtoBufMessage","new","limit","ProtoBufResponseBuilder","protobuf","from","into","to_string","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_string","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","borrow","borrow_mut","try_from","try_into","type_id","into_future","try_poll","vzip","from","from","default","deref","deref_mut","fmt","fmt","fmt","fmt","poll","from_request","error_response","respond_to"],"q":["actix_protobuf","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["","Payload size is bigger than 256k","Content type error","Serialize error","Deserialize error","Payload error","","","","Change max size of payload. By default max size is 256Kb","","Create ProtoBufMessage for request.","Change max size of payload. By default max size is 256Kb","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,1,1,1,1,1,0,2,0,3,0,4,4,0,5,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,1,1,3,2,2,1,2,1,2,4,2,1,2],"f":[null,null,null,null,null,null,null,null,null,[[["usize",15]]],null,[[["httprequest",3],["payload",4]]],[[["usize",15]]],null,[[["message",8]],[["httpresponse",3],["error",3],["result",4]]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[["pin",3],["context",3]],["poll",4]],[[]],[[["payloaderror",4]],["protobufpayloaderror",4]],[[["protobufdecodeerror",3]],["protobufpayloaderror",4]],[[]],[[]],[[]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["context",3],["pin",3]],["poll",4]],[[["httprequest",3],["payload",4]]],[[],["httpresponse",3]],[[["httprequest",3]],["httpresponse",3]]],"p":[[4,"ProtoBufPayloadError"],[3,"ProtoBuf"],[3,"ProtoBufConfig"],[3,"ProtoBufMessage"],[8,"ProtoBufResponseBuilder"]]},\ +"actix_redis":{"doc":"Redis integration for Actix and session store for Actix …","t":[3,12,3,4,13,13,13,3,4,13,13,13,4,13,13,13,13,13,13,4,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["Command","0","RedisActor","SameSite","Strict","Lax","None","RedisSession","Error","Redis","NotConnected","Disconnected","RespError","Internal","IO","RESP","Remote","Connection","Unexpected","RespValue","Nil","Array","BulkString","Error","Integer","SimpleString","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_owned","clone_into","to_string","borrow","borrow_mut","try_from","try_into","type_id","vzip","equivalent","get_hash","from","into","to_string","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_string","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","equivalent","from_resp_int","fmt","clone","fmt","fmt","source","from","from","from","from","from","from","from","from","from","eq","ne","fmt","clone","fmt","hash","eq","from","fmt","fmt","fmt","source","started","restarting","handle","handle","error","new_transform","start","new","ttl","cookie_name","cookie_path","cookie_domain","cookie_secure","cookie_max_age","cookie_same_site","cookie_http_only","cache_keygen","is_strict","is_lax","is_none","append","push"],"q":["actix_redis","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Command for send data to Redis","","Redis communication actor","The SameSite cookie attribute.","The “Strict” SameSite attribute.","The “Lax” SameSite attribute.","The “None” SameSite attribute.","Use redis as session storage.","General purpose actix redis error","","Receiving message during reconnecting","Cancel all waters when connection get dropped","","A non-specific internal error that prevented an operation …","An IO error occurred","A RESP parsing/serialising error occurred","A remote error","Error creating a connection, or an error with a …","An unexpected error. In this context “unexpected” …","A single RESP value, this owns the data that is …","","Zero, one or more other RespValues.","A bulk string. In Redis terminology a string is a …","An error from the Redis server","Redis documentation defines an integer as being a signed …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Start new Supervisor with RedisActor.","Create new redis session backend","Set time to live in seconds for session value.","Set custom cookie name for session ID.","Set custom cookie path.","Set custom cookie domain.","Set custom cookie secure.","Set custom cookie max-age.","Set custom cookie SameSite attribute.","Set custom cookie HttpOnly policy.","Set a custom cache key generation strategy, expecting …","Returns true if self is SameSite::Strict and false …","Returns true if self is SameSite::Lax and false otherwise.","Returns true if self is SameSite::None and false …","Convenience function for building dynamic Redis commands …","Push item to Resp array"],"i":[0,1,0,0,2,2,2,0,0,3,3,3,0,4,4,4,4,4,4,0,5,5,5,5,5,5,1,1,1,1,1,1,1,1,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,4,5,5,5,2,2,2,2,2,3,1,3,3,3,6,6,6,6,6,7,6,7,7,7,7,7,7,7,7,7,7,2,2,2,5,5],"f":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[],["bool",15]],[[],["u64",15]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[],["bool",15]],[[["respvalue",4]],[["error",4],["respvalue",4],["result",4]]],[[["formatter",3]],[["result",4],["error",3]]],[[],["respvalue",4]],[[["formatter",3]],[["result",4],["error",3]]],[[["formatter",3]],[["result",4],["error",3]]],[[],[["option",4],["error",8]]],[[["vec",3],["u8",15],["global",3]],["respvalue",4]],[[["usize",15]],["respvalue",4]],[[["trysenderror",3]],["error",4]],[[["string",3]],["respvalue",4]],[[["str",15]],["respvalue",4]],[[["arc",3],["str",15]],["respvalue",4]],[[],["respvalue",4]],[[["error",3]],["error",4]],[[["string",3]],["respvalue",4]],[[["respvalue",4]],["bool",15]],[[["respvalue",4]],["bool",15]],[[["formatter",3]],[["result",4],["error",3]]],[[],["samesite",4]],[[["formatter",3]],[["result",4],["error",3]]],[[]],[[["samesite",4]],["bool",15]],[[["error",4]],["error",4]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[],[["option",4],["error",8]]],[[["context",3]]],[[]],[[["command",3]]],[[["respvalue",4],["result",4],["resperror",4]]],[[["error",3]],["running",4]],[[]],[[["string",3],["into",8]],[["addr",3],["redisactor",3]]],[[["string",3],["into",8]],["redissession",3]],[[["u32",15]]],[[["str",15]]],[[["str",15]]],[[["str",15]]],[[["bool",15]]],[[]],[[["samesite",4]]],[[["bool",15]]],[[["box",3],["fn",8]]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],[[],["respvalue",4]],[[]]],"p":[[3,"Command"],[4,"SameSite"],[4,"Error"],[4,"RespError"],[4,"RespValue"],[3,"RedisActor"],[3,"RedisSession"]]},\ +"actix_session":{"doc":"Sessions for Actix Web.","t":[3,3,8,10,4,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["CookieSession","Session","UserSession","get_session","SessionStatus","Changed","Purged","Renewed","Unchanged","get","set","remove","clear","purge","renew","set_session","get_changes","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","clone","default","eq","fmt","new_transform","from_request","signed","private","path","name","domain","lazy","secure","http_only","same_site","max_age","max_age_time","expires_in","expires_in_time"],"q":["actix_session","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Use cookies for session storage.","The high-level interface you use to modify session data.","Extraction of a [Session] object.","","","","","","","Get a value from the session.","Set a value from the session.","Remove value from the session.","Clear the session.","Removes session, both client and server side.","Renews the session key, assigning existing session state …","Adds the given key-value pairs to the session on the …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Construct new signed CookieSession instance.","Construct new private CookieSession instance.","Sets the path field in the session cookie being built.","Sets the name field in the session cookie being built.","Sets the domain field in the session cookie being built.","When true, prevents adding session cookies to responses …","Sets the secure field in the session cookie being built.","Sets the http_only field in the session cookie being …","Sets the same_site field in the session cookie being …","Sets the max-age field in the session cookie being built.","Sets the max-age field in the session cookie being built.","Sets the expires field in the session cookie being built.","Sets the expires field in the session cookie being built."],"i":[0,0,0,1,0,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4],"f":[null,null,null,[[],["session",3]],null,null,null,null,null,[[["str",15]],[["option",4],["error",3],["result",4]]],[[["serialize",8],["str",15]],[["error",3],["result",4]]],[[["str",15]]],[[]],[[]],[[]],[[["servicerequest",3]]],[[["serviceresponse",3]]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[],["sessionstatus",4]],[[],["sessionstatus",4]],[[["sessionstatus",4]],["bool",15]],[[["formatter",3]],["result",6]],[[]],[[["httprequest",3],["payload",4]]],[[],["cookiesession",3]],[[],["cookiesession",3]],[[["into",8],["string",3]],["cookiesession",3]],[[["into",8],["string",3]],["cookiesession",3]],[[["into",8],["string",3]],["cookiesession",3]],[[["bool",15]],["cookiesession",3]],[[["bool",15]],["cookiesession",3]],[[["bool",15]],["cookiesession",3]],[[["samesite",4]],["cookiesession",3]],[[["i64",15]],["cookiesession",3]],[[["duration",3]],["cookiesession",3]],[[["i64",15]],["cookiesession",3]],[[["duration",3]],["cookiesession",3]]],"p":[[8,"UserSession"],[4,"SessionStatus"],[3,"Session"],[3,"CookieSession"]]},\ +"actix_web_httpauth":{"doc":"HTTP authentication schemes for actix-web.","t":[0,0,3,11,3,11,11,0,4,13,13,13,3,11,11,3,11,8,16,10,3,8,16,16,10,0,0,4,13,13,13,13,13,13,3,3,3,8,10,0,11,0,3,0,3,3,4,13,13,13,8,10,3,12,0,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["extractors","basic","Config","realm","BasicAuth","user_id","password","bearer","Error","InvalidRequest","InvalidToken","InsufficientScope","Config","scope","realm","BearerAuth","token","AuthExtractorConfig","Inner","into_inner","AuthenticationError","AuthExtractor","Error","Future","from_service_request","headers","authorization","ParseError","Invalid","MissingScheme","MissingField","ToStrError","Base64DecodeError","Utf8Error","Authorization","Basic","Bearer","Scheme","parse","www_authenticate","status_code","basic","Basic","bearer","BearerBuilder","Bearer","Error","InvalidRequest","InvalidToken","InsufficientScope","Challenge","to_bytes","WwwAuthenticate","0","middleware","HttpAuthentication","with_fn","basic","bearer","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_owned","clone_into","to_string","borrow","borrow_mut","try_from","try_into","type_id","equivalent","get_hash","vzip","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_string","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_string","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","from","into","to_owned","clone_into","to_string","borrow","borrow_mut","try_from","try_into","type_id","try_into_header_pair","equivalent","get_hash","vzip","from","into","to_owned","clone_into","to_string","borrow","borrow_mut","try_from","try_into","type_id","equivalent","vzip","from","into","to_owned","clone_into","to_string","borrow","borrow_mut","try_from","try_into","type_id","equivalent","vzip","from","into","to_owned","clone_into","to_string","borrow","borrow_mut","try_from","try_into","type_id","equivalent","get_hash","vzip","from","into","borrow","borrow_mut","try_from","try_into","type_id","vzip","from","into","to_owned","clone_into","to_string","borrow","borrow_mut","try_from","try_into","type_id","equivalent","get_hash","vzip","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","try_into_header_pair","equivalent","get_hash","vzip","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","into_inner","into_inner","from_service_request","from_service_request","parse","parse","as_mut","as_ref","as_ref","as_ref","from","from","from","from","from","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","default","default","default","default","default","default","default","cmp","cmp","cmp","cmp","cmp","cmp","cmp","eq","ne","eq","ne","eq","ne","eq","ne","eq","ne","eq","eq","ne","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","hash","hash","hash","hash","hash","source","new_transform","from_request","from_request","error_response","status_code","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","name","parse","name","parse","with_error","with_error_description","with_error_uri","new","challenge_mut","status_code_mut","into_scheme","new","user_id","password","new","token","new","with_realm","scope","realm","error","error_description","error_uri","finish","build"],"q":["actix_web_httpauth","actix_web_httpauth::extractors","actix_web_httpauth::extractors::basic","","","","","actix_web_httpauth::extractors","actix_web_httpauth::extractors::bearer","","","","","","","","","actix_web_httpauth::extractors","","","","","","","","actix_web_httpauth","actix_web_httpauth::headers","actix_web_httpauth::headers::authorization","","","","","","","","","","","","actix_web_httpauth::headers","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::headers::www_authenticate::bearer","","","","","","actix_web_httpauth::headers::www_authenticate","","","","actix_web_httpauth","actix_web_httpauth::middleware","","","","actix_web_httpauth::extractors::basic","","","","","","","","","","","","","","","","","","","","actix_web_httpauth::extractors::bearer","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","actix_web_httpauth::extractors","","","","","","","","","actix_web_httpauth::headers::authorization","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","actix_web_httpauth::headers::www_authenticate::basic","","","","","","","","","","","","","actix_web_httpauth::headers::www_authenticate::bearer","","","","","","","","","","","","","","","","","","","","","actix_web_httpauth::headers::www_authenticate","","","","","","","","","","","","","actix_web_httpauth::middleware","","","","","","","","","","actix_web_httpauth::extractors::basic","actix_web_httpauth::extractors::bearer","actix_web_httpauth::extractors::basic","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::authorization","","","actix_web_httpauth::extractors::basic","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::authorization","actix_web_httpauth::extractors","actix_web_httpauth::headers::authorization","","","","actix_web_httpauth::extractors::basic","","actix_web_httpauth::extractors::bearer","","actix_web_httpauth::headers::authorization","","","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate::bearer","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::middleware","actix_web_httpauth::extractors::basic","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::authorization","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate::bearer","","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::headers::authorization","","","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate::bearer","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::headers::authorization","","","","","","actix_web_httpauth::headers::www_authenticate::basic","","actix_web_httpauth::headers::www_authenticate::bearer","","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::www_authenticate","","actix_web_httpauth::headers::authorization","","","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate::bearer","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::extractors::basic","","actix_web_httpauth::extractors::bearer","","actix_web_httpauth::extractors","actix_web_httpauth::headers::authorization","","","","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate::bearer","","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::middleware","actix_web_httpauth::extractors","actix_web_httpauth::headers::authorization","","","","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate::bearer","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::authorization","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate::bearer","actix_web_httpauth::extractors::bearer","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::headers::authorization","actix_web_httpauth::middleware","actix_web_httpauth::extractors::basic","actix_web_httpauth::extractors::bearer","actix_web_httpauth::extractors","","actix_web_httpauth::headers::authorization","","","actix_web_httpauth::headers::www_authenticate::basic","actix_web_httpauth::headers::www_authenticate::bearer","actix_web_httpauth::headers::www_authenticate","actix_web_httpauth::headers::authorization","","actix_web_httpauth::headers::www_authenticate","","actix_web_httpauth::extractors","","","","","","actix_web_httpauth::headers::authorization","","","","","","actix_web_httpauth::headers::www_authenticate::basic","","actix_web_httpauth::headers::www_authenticate::bearer","","","","","",""],"d":["Type-safe authentication information extractors","Extractor for the “Basic” HTTP Authentication Scheme","BasicAuth extractor configuration, used for …","Set challenge realm attribute.","Extractor for HTTP Basic auth.","Returns client’s user-ID.","Returns client’s password.","Extractor for the “Bearer” HTTP Authentication Scheme","Bearer authorization error types, described in RFC 6750","The request is missing a required parameter, includes an …","The access token provided is expired, revoked, malformed, …","The request requires higher privileges than provided by …","BearerAuth extractor configuration.","Set challenge scope attribute.","Set challenge realm attribute.","Extractor for HTTP Bearer auth","Returns bearer token provided by client.","Trait implemented for types that provides configuration …","Associated challenge type.","Convert the config instance into a HTTP challenge.","Authentication error returned by authentication …","Trait implemented by types that can extract HTTP …","The associated error which can be returned.","Future that resolves into extracted credentials type.","Parse the authentication credentials from the actix’ …","Typed HTTP headers","Authorization header and various auth schemes","Possible errors while parsing Authorization header.","Header value is malformed","Authentication scheme is missing","Required authentication field is missing","Unable to convert header into the str","Malformed base64 string","Malformed UTF-8 string","Authorization header, defined in RFC 7235","Credentials for Basic authentication scheme, defined in …","Credentials for Bearer authentication scheme, defined in …","Authentication scheme for Authorization header.","Try to parse the authentication scheme from the …","WWW-Authenticate header and various auth challenges","Returns HTTP status code suitable for current error type.","Challenge for the “Basic” HTTP Authentication Scheme","Challenge for WWW-Authenticate header with HTTP Basic …","Challenge for the “Bearer” HTTP Authentication Scheme","Builder for the Bearer challenge.","Challenge for WWW-Authenticate header with HTTP Bearer …","Bearer authorization error types, described in RFC 6750","The request is missing a required parameter, includes an …","The access token provided is expired, revoked, malformed, …","The request requires higher privileges than provided by …","Authentication challenge for WWW-Authenticate header.","Converts the challenge into a bytes suitable for HTTP …","WWW-Authenticate header, described in RFC 7235","","HTTP Authentication middleware.","Middleware for checking HTTP authentication.","Construct HttpAuthentication middleware with the provided …","Construct HttpAuthentication middleware for the HTTP “…","Construct HttpAuthentication middleware for the HTTP “…","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Attach Error to the current Authentication error.","Attach error description to the current Authentication …","Attach error URI to the current Authentication error.","Creates new authentication error from the provided …","Returns mutable reference to the inner challenge instance.","Returns mutable reference to the inner status code.","Consumes Authorization header and returns inner Scheme …","Creates Basic credentials with provided user_id and …","Returns client’s user-ID.","Returns client’s password if provided.","Creates new Bearer credentials with the token provided.","Gets reference to the credentials token.","Creates new Basic challenge with an empty realm field.","Creates new Basic challenge from the provided realm field …","Provides the scope attribute, as defined in RFC6749, …","Provides the realm attribute, as defined in RFC2617","Provides the error attribute, as defined in RFC6750, …","Provides the error_description attribute, as defined in …","Provides the error_uri attribute, as defined in RFC6750, …","Consumes the builder and returns built Bearer instance.","Creates the builder for Bearer challenge."],"i":[0,0,0,1,0,2,2,0,0,3,3,3,0,4,4,0,5,0,6,6,0,0,7,7,7,0,0,0,8,8,8,8,8,8,0,0,0,0,9,0,3,0,0,0,0,0,0,3,3,3,0,10,0,11,0,0,12,12,12,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,13,13,13,13,13,13,13,13,13,8,8,8,8,8,8,8,8,8,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,1,4,2,5,15,16,14,1,4,14,13,8,8,8,14,1,2,4,5,14,15,16,17,19,3,11,12,1,4,14,17,18,19,11,14,15,16,17,19,3,11,14,14,15,15,16,16,17,17,19,19,3,11,11,14,15,16,17,19,3,11,1,2,4,5,13,8,14,15,16,17,18,19,3,11,12,13,8,14,15,16,17,19,3,14,17,19,3,11,8,12,2,5,13,13,14,15,16,17,19,11,14,14,11,11,13,13,13,13,13,13,14,15,15,15,16,16,17,17,18,18,18,18,18,18,19],"f":[null,null,null,[[],["config",3]],null,[[],["cow",4]],[[],[["option",4],["cow",4]]],null,null,null,null,null,null,[[["cow",4],["into",8]],["config",3]],[[["cow",4],["into",8]],["config",3]],null,[[],["str",15]],null,null,[[]],null,null,null,null,[[["servicerequest",3]]],null,null,null,null,null,null,null,null,null,null,null,null,null,[[["headervalue",3]],[["result",4],["parseerror",4]]],null,[[],["statuscode",3]],null,null,null,null,null,null,null,null,null,null,[[],["bytes",3]],null,null,null,null,[[],["httpauthentication",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["bool",15]],[[],["u64",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["result",4]],[[],["bool",15]],[[],["u64",15]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["bool",15]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["bool",15]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["bool",15]],[[],["u64",15]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["bool",15]],[[],["u64",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["result",4]],[[],["bool",15]],[[],["u64",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[]],[[]],[[["servicerequest",3]]],[[["servicerequest",3]]],[[["headervalue",3]],[["result",4],["parseerror",4]]],[[["headervalue",3]],[["result",4],["parseerror",4]]],[[]],[[],["challenge",3]],[[],["bearer",3]],[[]],[[]],[[["tostrerror",3]]],[[["decodeerror",4]]],[[["utf8error",3]]],[[],["authorization",3]],[[],["config",3]],[[],["basicauth",3]],[[],["config",3]],[[],["bearerauth",3]],[[],["authorization",3]],[[],["basic",3]],[[],["bearer",3]],[[],["basic",3]],[[],["bearer",3]],[[],["error",4]],[[],["wwwauthenticate",3]],[[],["httpauthentication",3]],[[],["config",3]],[[],["config",3]],[[],["authorization",3]],[[],["basic",3]],[[],["bearerbuilder",3]],[[],["bearer",3]],[[],["wwwauthenticate",3]],[[["authorization",3]],["ordering",4]],[[["basic",3]],["ordering",4]],[[["bearer",3]],["ordering",4]],[[["basic",3]],["ordering",4]],[[["bearer",3]],["ordering",4]],[[["error",4]],["ordering",4]],[[["wwwauthenticate",3]],["ordering",4]],[[["authorization",3]],["bool",15]],[[["authorization",3]],["bool",15]],[[["basic",3]],["bool",15]],[[["basic",3]],["bool",15]],[[["bearer",3]],["bool",15]],[[["bearer",3]],["bool",15]],[[["basic",3]],["bool",15]],[[["basic",3]],["bool",15]],[[["bearer",3]],["bool",15]],[[["bearer",3]],["bool",15]],[[["error",4]],["bool",15]],[[["wwwauthenticate",3]],["bool",15]],[[["wwwauthenticate",3]],["bool",15]],[[["authorization",3]],[["ordering",4],["option",4]]],[[["basic",3]],[["ordering",4],["option",4]]],[[["bearer",3]],[["ordering",4],["option",4]]],[[["basic",3]],[["ordering",4],["option",4]]],[[["bearer",3]],[["ordering",4],["option",4]]],[[["error",4]],[["ordering",4],["option",4]]],[[["wwwauthenticate",3]],[["ordering",4],["option",4]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],[["result",4],["error",3]]],[[["formatter",3]],[["result",4],["error",3]]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[]],[[],[["option",4],["error",8]]],[[]],[[["httprequest",3],["payload",4]]],[[["httprequest",3],["payload",4]]],[[],["httpresponse",3]],[[],["statuscode",3]],[[],[["result",4],["headervalue",3]]],[[],[["result",4],["headervalue",3]]],[[],[["result",4],["headervalue",3]]],[[],[["result",4],["headervalue",3]]],[[],[["result",4],["headervalue",3]]],[[],[["result",4],["headervalue",3]]],[[],["headername",3]],[[],[["parseerror",4],["result",4]]],[[],["headername",3]],[[],[["parseerror",4],["result",4]]],[[["error",4]]],[[]],[[]],[[],["authenticationerror",3]],[[]],[[],["statuscode",3]],[[]],[[["option",4]],["basic",3]],[[],["cow",4]],[[],[["option",4],["cow",4]]],[[],["bearer",3]],[[],["cow",4]],[[],["basic",3]],[[],["basic",3]],[[]],[[]],[[["error",4]]],[[]],[[]],[[],["bearer",3]],[[],["bearerbuilder",3]]],"p":[[3,"Config"],[3,"BasicAuth"],[4,"Error"],[3,"Config"],[3,"BearerAuth"],[8,"AuthExtractorConfig"],[8,"AuthExtractor"],[4,"ParseError"],[8,"Scheme"],[8,"Challenge"],[3,"WwwAuthenticate"],[3,"HttpAuthentication"],[3,"AuthenticationError"],[3,"Authorization"],[3,"Basic"],[3,"Bearer"],[3,"Basic"],[3,"BearerBuilder"],[3,"Bearer"]]},\ +"prost_example":{"doc":"","t":[3,12,12,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["MyObj","number","name","index","main","from","into","to_owned","clone_into","borrow","borrow_mut","try_from","try_into","type_id","vzip","clone","default","eq","ne","fmt","encode_raw","merge_field","encoded_len","clear"],"q":["prost_example","","","","","","","","","","","","","","","","","","","","","","",""],"d":["","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"f":[null,null,null,[[["protobuf",3],["myobj",3]]],[[],["result",6]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],[[],["myobj",3]],[[]],[[["myobj",3]],["bool",15]],[[["myobj",3]],["bool",15]],[[["formatter",3]],["result",6]],[[]],[[["u32",15],["wiretype",4],["decodecontext",3]],[["decodeerror",3],["result",4]]],[[],["usize",15]],[[]]],"p":[[3,"MyObj"]]}\ }'); -addSearchOptions(searchIndex);initSearch(searchIndex); \ No newline at end of file +initSearch(searchIndex); \ No newline at end of file diff --git a/settings.html b/settings.html index 88efdca1e..21ac3c70c 100644 --- a/settings.html +++ b/settings.html @@ -1,6 +1,7 @@ -Rustdoc settings +Rustdoc settings -

Rustdoc settings

Theme preferences
Use system theme
Preferred dark theme
Preferred light theme
+

Rustdoc settings

Theme preferences
Use system theme
Preferred dark theme
Preferred light theme
Auto-hide item declarations
Auto-hide structs declaration
Auto-hide enums declaration
Auto-hide unions declaration
Auto-hide traits declaration
Auto-hide macros declaration
-
Auto-hide item attributes.
Auto-hide item methods' documentation
Auto-hide trait implementation documentation
Auto-hide implementors of a trait
Directly go to item in search if there is only one result
Show line numbers on code examples
Disable keyboard shortcuts
\ No newline at end of file +
Auto-hide item attributes.
Auto-hide item methods' documentation
Auto-hide trait implementation documentation
Auto-hide implementors of a trait
Directly go to item in search if there is only one result
Show line numbers on code examples
Disable keyboard shortcuts
+ \ No newline at end of file diff --git a/source-files.js b/source-files.js index 1019ec193..7a8f9e36a 100644 --- a/source-files.js +++ b/source-files.js @@ -1,3 +1,9 @@ var N = null;var sourcesIndex = {}; +sourcesIndex["actix_cors"] = {"name":"","files":["all_or_some.rs","builder.rs","error.rs","inner.rs","lib.rs","middleware.rs"]}; +sourcesIndex["actix_identity"] = {"name":"","files":["lib.rs"]}; +sourcesIndex["actix_protobuf"] = {"name":"","files":["lib.rs"]}; sourcesIndex["actix_redis"] = {"name":"","files":["lib.rs","redis.rs","session.rs"]}; +sourcesIndex["actix_session"] = {"name":"","files":["cookie.rs","lib.rs"]}; +sourcesIndex["actix_web_httpauth"] = {"name":"","dirs":[{"name":"extractors","files":["basic.rs","bearer.rs","config.rs","errors.rs","mod.rs"]},{"name":"headers","dirs":[{"name":"authorization","dirs":[{"name":"scheme","files":["basic.rs","bearer.rs","mod.rs"]}],"files":["errors.rs","header.rs","mod.rs"]},{"name":"www_authenticate","dirs":[{"name":"challenge","dirs":[{"name":"bearer","files":["builder.rs","challenge.rs","errors.rs","mod.rs"]}],"files":["basic.rs","mod.rs"]}],"files":["header.rs","mod.rs"]}],"files":["mod.rs"]}],"files":["lib.rs","middleware.rs","utils.rs"]}; +sourcesIndex["prost_example"] = {"name":"","files":["main.rs"]}; createSourceSidebar(); diff --git a/source-script.js b/source-script.js index de663ca5a..67f62a160 100644 --- a/source-script.js +++ b/source-script.js @@ -1 +1 @@ -function getCurrentFilePath(){var parts=window.location.pathname.split("/");var rootPathParts=window.rootPath.split("/");for(var i=0;i"){sidebar.style.left="";this.style.left="";child.innerText="<";updateLocalStorage("rustdoc-source-sidebar-show","true")}else{sidebar.style.left="-300px";this.style.left="0";child.innerText=">";updateLocalStorage("rustdoc-source-sidebar-show","false")}}function createSidebarToggle(){var sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";sidebarToggle.onclick=toggleSidebar;var inner1=document.createElement("div");inner1.style.position="relative";var inner2=document.createElement("div");inner2.style.paddingTop="3px";if(getCurrentValue("rustdoc-source-sidebar-show")==="true"){inner2.innerText="<"}else{inner2.innerText=">";sidebarToggle.style.left="0"}inner1.appendChild(inner2);sidebarToggle.appendChild(inner1);return sidebarToggle}function createSourceSidebar(){if(window.rootPath.endsWith("/")===false){window.rootPath+="/"}var main=document.getElementById("main");var sidebarToggle=createSidebarToggle();main.insertBefore(sidebarToggle,main.firstChild);var sidebar=document.createElement("div");sidebar.id="source-sidebar";if(getCurrentValue("rustdoc-source-sidebar-show")!=="true"){sidebar.style.left="-300px"}var currentFile=getCurrentFilePath();var hasFoundFile=false;var title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(function(key){sourcesIndex[key].name=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",currentFile,hasFoundFile)});main.insertBefore(sidebar,main.firstChild);var selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}} \ No newline at end of file +function getCurrentFilePath(){var parts=window.location.pathname.split("/");var rootPathParts=window.rootPath.split("/");for(var i=0,len=rootPathParts.length;i"){sidebar.style.left="";this.style.left="";child.innerText="<";updateLocalStorage("rustdoc-source-sidebar-show","true")}else{sidebar.style.left="-300px";this.style.left="0";child.innerText=">";updateLocalStorage("rustdoc-source-sidebar-show","false")}}function createSidebarToggle(){var sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";sidebarToggle.onclick=toggleSidebar;var inner1=document.createElement("div");inner1.style.position="relative";var inner2=document.createElement("div");inner2.style.paddingTop="3px";if(getCurrentValue("rustdoc-source-sidebar-show")==="true"){inner2.innerText="<"}else{inner2.innerText=">";sidebarToggle.style.left="0"}inner1.appendChild(inner2);sidebarToggle.appendChild(inner1);return sidebarToggle}function createSourceSidebar(){if(window.rootPath.endsWith("/")===false){window.rootPath+="/"}var main=document.getElementById("main");var sidebarToggle=createSidebarToggle();main.insertBefore(sidebarToggle,main.firstChild);var sidebar=document.createElement("div");sidebar.id="source-sidebar";if(getCurrentValue("rustdoc-source-sidebar-show")!=="true"){sidebar.style.left="-300px"}var currentFile=getCurrentFilePath();var hasFoundFile=false;var title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(function(key){sourcesIndex[key].name=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",currentFile,hasFoundFile)});main.insertBefore(sidebar,main.firstChild);var selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}} \ No newline at end of file diff --git a/src/actix_cors/all_or_some.rs.html b/src/actix_cors/all_or_some.rs.html new file mode 100644 index 000000000..ed0d09113 --- /dev/null +++ b/src/actix_cors/all_or_some.rs.html @@ -0,0 +1,115 @@ +all_or_some.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
+
+/// An enum signifying that some of type `T` is allowed, or `All` (anything is allowed).
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum AllOrSome<T> {
+    /// Everything is allowed. Usually equivalent to the `*` value.
+    All,
+
+    /// Only some of `T` is allowed
+    Some(T),
+}
+
+/// Default as `AllOrSome::All`.
+impl<T> Default for AllOrSome<T> {
+    fn default() -> Self {
+        AllOrSome::All
+    }
+}
+
+impl<T> AllOrSome<T> {
+    /// Returns whether this is an `All` variant.
+    pub fn is_all(&self) -> bool {
+        matches!(self, AllOrSome::All)
+    }
+
+    /// Returns whether this is a `Some` variant.
+    #[allow(dead_code)]
+    pub fn is_some(&self) -> bool {
+        !self.is_all()
+    }
+
+    /// Provides a shared reference to `T` if variant is `Some`.
+    pub fn as_ref(&self) -> Option<&T> {
+        match *self {
+            AllOrSome::All => None,
+            AllOrSome::Some(ref t) => Some(t),
+        }
+    }
+
+    /// Provides a mutable reference to `T` if variant is `Some`.
+    pub fn as_mut(&mut self) -> Option<&mut T> {
+        match *self {
+            AllOrSome::All => None,
+            AllOrSome::Some(ref mut t) => Some(t),
+        }
+    }
+}
+
+#[cfg(test)]
+#[test]
+fn tests() {
+    assert!(AllOrSome::<()>::All.is_all());
+    assert!(!AllOrSome::<()>::All.is_some());
+
+    assert!(!AllOrSome::Some(()).is_all());
+    assert!(AllOrSome::Some(()).is_some());
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_cors/builder.rs.html b/src/actix_cors/builder.rs.html new file mode 100644 index 000000000..074a39af7 --- /dev/null +++ b/src/actix_cors/builder.rs.html @@ -0,0 +1,1257 @@ +builder.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
+
+use std::{collections::HashSet, convert::TryInto, iter::FromIterator, rc::Rc};
+
+use actix_web::{
+    dev::{RequestHead, Service, ServiceRequest, ServiceResponse, Transform},
+    error::{Error, Result},
+    http::{self, header::HeaderName, Error as HttpError, HeaderValue, Method, Uri},
+    Either,
+};
+use futures_util::future::{self, Ready};
+use log::error;
+use once_cell::sync::Lazy;
+use tinyvec::tiny_vec;
+
+use crate::{AllOrSome, CorsError, CorsMiddleware, Inner, OriginFn};
+
+/// Convenience for getting mut refs to inner. Cleaner than `Rc::get_mut`.
+/// Additionally, always causes first error (if any) to be reported during initialization.
+fn cors<'a>(
+    inner: &'a mut Rc<Inner>,
+    err: &Option<Either<http::Error, CorsError>>,
+) -> Option<&'a mut Inner> {
+    if err.is_some() {
+        return None;
+    }
+
+    Rc::get_mut(inner)
+}
+
+static ALL_METHODS_SET: Lazy<HashSet<Method>> = Lazy::new(|| {
+    HashSet::from_iter(vec![
+        Method::GET,
+        Method::POST,
+        Method::PUT,
+        Method::DELETE,
+        Method::HEAD,
+        Method::OPTIONS,
+        Method::CONNECT,
+        Method::PATCH,
+        Method::TRACE,
+    ])
+});
+
+/// Builder for CORS middleware.
+///
+/// To construct a CORS middleware, call [`Cors::default()`] to create a blank, restrictive builder.
+/// Then use any of the builder methods to customize CORS behavior.
+///
+/// The alternative [`Cors::permissive()`] constructor is available for local development, allowing
+/// all origins and headers, etc. **The permissive constructor should not be used in production.**
+///
+/// # Errors
+/// Errors surface in the middleware initialization phase. This means that, if you have logs enabled
+/// in Actix Web (using `env_logger` or other crate that exposes logs from the `log` crate), error
+/// messages will outline what is wrong with the CORS configuration in the server logs and the
+/// server will fail to start up or serve requests.
+///
+/// # Example
+/// ```rust
+/// use actix_cors::Cors;
+/// use actix_web::http::header;
+///
+/// let cors = Cors::default()
+///     .allowed_origin("https://www.rust-lang.org")
+///     .allowed_methods(vec!["GET", "POST"])
+///     .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
+///     .allowed_header(header::CONTENT_TYPE)
+///     .max_age(3600);
+///
+/// // `cors` can now be used in `App::wrap`.
+/// ```
+#[derive(Debug)]
+pub struct Cors {
+    inner: Rc<Inner>,
+    error: Option<Either<http::Error, CorsError>>,
+}
+
+impl Cors {
+    /// A very permissive set of default for quick development. Not recommended for production use.
+    ///
+    /// *All* origins, methods, request headers and exposed headers allowed. Credentials supported.
+    /// Max age 1 hour. Does not send wildcard.
+    pub fn permissive() -> Self {
+        let inner = Inner {
+            allowed_origins: AllOrSome::All,
+            allowed_origins_fns: tiny_vec![],
+
+            allowed_methods: ALL_METHODS_SET.clone(),
+            allowed_methods_baked: None,
+
+            allowed_headers: AllOrSome::All,
+            allowed_headers_baked: None,
+
+            expose_headers: AllOrSome::All,
+            expose_headers_baked: None,
+            max_age: Some(3600),
+            preflight: true,
+            send_wildcard: false,
+            supports_credentials: true,
+            vary_header: true,
+        };
+
+        Cors {
+            inner: Rc::new(inner),
+            error: None,
+        }
+    }
+
+    /// Resets allowed origin list to a state where any origin is accepted.
+    ///
+    /// See [`Cors::allowed_origin`] for more info on allowed origins.
+    pub fn allow_any_origin(mut self) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.allowed_origins = AllOrSome::All;
+        }
+
+        self
+    }
+
+    /// Add an origin that is allowed to make requests.
+    ///
+    /// By default, requests from all origins are accepted by CORS logic. This method allows to
+    /// specify a finite set of origins to verify the value of the `Origin` request header.
+    ///
+    /// These are `origin-or-null` types in the [Fetch Standard].
+    ///
+    /// When this list is set, the client's `Origin` request header will be checked in a
+    /// case-sensitive manner.
+    ///
+    /// When all origins are allowed and `send_wildcard` is set, `*` will be sent in the
+    /// `Access-Control-Allow-Origin` response header. If `send_wildcard` is not set, the client's
+    /// `Origin` request header will be echoed back in the `Access-Control-Allow-Origin`
+    /// response header.
+    ///
+    /// If the origin of the request doesn't match any allowed origins and at least one
+    /// `allowed_origin_fn` function is set, these functions will be used to determinate
+    /// allowed origins.
+    ///
+    /// # Initialization Errors
+    /// - If supplied origin is not valid uri
+    /// - If supplied origin is a wildcard (`*`). [`Cors::send_wildcard`] should be used instead.
+    ///
+    /// [Fetch Standard]: https://fetch.spec.whatwg.org/#origin-header
+    pub fn allowed_origin(mut self, origin: &str) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            match TryInto::<Uri>::try_into(origin) {
+                Ok(_) if origin == "*" => {
+                    error!("Wildcard in `allowed_origin` is not allowed. Use `send_wildcard`.");
+                    self.error = Some(Either::Right(CorsError::WildcardOrigin));
+                }
+
+                Ok(_) => {
+                    if cors.allowed_origins.is_all() {
+                        cors.allowed_origins =
+                            AllOrSome::Some(HashSet::with_capacity(8));
+                    }
+
+                    if let Some(origins) = cors.allowed_origins.as_mut() {
+                        // any uri is a valid header value
+                        let hv = origin.try_into().unwrap();
+                        origins.insert(hv);
+                    }
+                }
+
+                Err(err) => {
+                    self.error = Some(Either::Left(err.into()));
+                }
+            }
+        }
+
+        self
+    }
+
+    /// Determinate allowed origins by processing requests which didn't match any origins specified
+    /// in the `allowed_origin`.
+    ///
+    /// The function will receive two parameters, the Origin header value, and the `RequestHead` of
+    /// each request, which can be used to determine whether to allow the request or not.
+    ///
+    /// If the function returns `true`, the client's `Origin` request header will be echoed back
+    /// into the `Access-Control-Allow-Origin` response header.
+    pub fn allowed_origin_fn<F>(mut self, f: F) -> Cors
+    where
+        F: (Fn(&HeaderValue, &RequestHead) -> bool) + 'static,
+    {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.allowed_origins_fns.push(OriginFn {
+                boxed_fn: Rc::new(f),
+            });
+        }
+
+        self
+    }
+
+    /// Resets allowed methods list to all methods.
+    ///
+    /// See [`Cors::allowed_methods`] for more info on allowed methods.
+    pub fn allow_any_method(mut self) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.allowed_methods = ALL_METHODS_SET.clone();
+        }
+
+        self
+    }
+
+    /// Set a list of methods which allowed origins can perform.
+    ///
+    /// These will be sent in the `Access-Control-Allow-Methods` response header as specified in
+    /// the [Fetch Standard CORS protocol].
+    ///
+    /// Defaults to `[GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE]`
+    ///
+    /// [Fetch Standard CORS protocol]: https://fetch.spec.whatwg.org/#http-cors-protocol
+    pub fn allowed_methods<U, M>(mut self, methods: U) -> Cors
+    where
+        U: IntoIterator<Item = M>,
+        M: TryInto<Method>,
+        <M as TryInto<Method>>::Error: Into<HttpError>,
+    {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            for m in methods {
+                match m.try_into() {
+                    Ok(method) => {
+                        cors.allowed_methods.insert(method);
+                    }
+
+                    Err(err) => {
+                        self.error = Some(Either::Left(err.into()));
+                        break;
+                    }
+                }
+            }
+        }
+
+        self
+    }
+
+    /// Resets allowed request header list to a state where any header is accepted.
+    ///
+    /// See [`Cors::allowed_headers`] for more info on allowed request headers.
+    pub fn allow_any_header(mut self) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.allowed_headers = AllOrSome::All;
+        }
+
+        self
+    }
+
+    /// Add an allowed request header.
+    ///
+    /// See [`Cors::allowed_headers`] for more info on allowed request headers.
+    pub fn allowed_header<H>(mut self, header: H) -> Cors
+    where
+        H: TryInto<HeaderName>,
+        <H as TryInto<HeaderName>>::Error: Into<HttpError>,
+    {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            match header.try_into() {
+                Ok(method) => {
+                    if cors.allowed_headers.is_all() {
+                        cors.allowed_headers =
+                            AllOrSome::Some(HashSet::with_capacity(8));
+                    }
+
+                    if let AllOrSome::Some(ref mut headers) = cors.allowed_headers {
+                        headers.insert(method);
+                    }
+                }
+
+                Err(err) => self.error = Some(Either::Left(err.into())),
+            }
+        }
+
+        self
+    }
+
+    /// Set a list of request header field names which can be used when this resource is accessed by
+    /// allowed origins.
+    ///
+    /// If `All` is set, whatever is requested by the client in `Access-Control-Request-Headers`
+    /// will be echoed back in the `Access-Control-Allow-Headers` header as specified in
+    /// the [Fetch Standard CORS protocol].
+    ///
+    /// Defaults to `All`.
+    ///
+    /// [Fetch Standard CORS protocol]: https://fetch.spec.whatwg.org/#http-cors-protocol
+    pub fn allowed_headers<U, H>(mut self, headers: U) -> Cors
+    where
+        U: IntoIterator<Item = H>,
+        H: TryInto<HeaderName>,
+        <H as TryInto<HeaderName>>::Error: Into<HttpError>,
+    {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            for h in headers {
+                match h.try_into() {
+                    Ok(method) => {
+                        if cors.allowed_headers.is_all() {
+                            cors.allowed_headers =
+                                AllOrSome::Some(HashSet::with_capacity(8));
+                        }
+
+                        if let AllOrSome::Some(ref mut headers) = cors.allowed_headers {
+                            headers.insert(method);
+                        }
+                    }
+                    Err(err) => {
+                        self.error = Some(Either::Left(err.into()));
+                        break;
+                    }
+                }
+            }
+        }
+
+        self
+    }
+
+    /// Resets exposed response header list to a state where any header is accepted.
+    ///
+    /// See [`Cors::expose_headers`] for more info on exposed response headers.
+    pub fn expose_any_header(mut self) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.expose_headers = AllOrSome::All;
+        }
+
+        self
+    }
+
+    /// Set a list of headers which are safe to expose to the API of a CORS API specification.
+    /// This corresponds to the `Access-Control-Expose-Headers` response header as specified in
+    /// the [Fetch Standard CORS protocol].
+    ///
+    /// This defaults to an empty set.
+    ///
+    /// [Fetch Standard CORS protocol]: https://fetch.spec.whatwg.org/#http-cors-protocol
+    pub fn expose_headers<U, H>(mut self, headers: U) -> Cors
+    where
+        U: IntoIterator<Item = H>,
+        H: TryInto<HeaderName>,
+        <H as TryInto<HeaderName>>::Error: Into<HttpError>,
+    {
+        for h in headers {
+            match h.try_into() {
+                Ok(header) => {
+                    if let Some(cors) = cors(&mut self.inner, &self.error) {
+                        if cors.expose_headers.is_all() {
+                            cors.expose_headers =
+                                AllOrSome::Some(HashSet::with_capacity(8));
+                        }
+                        if let AllOrSome::Some(ref mut headers) = cors.expose_headers {
+                            headers.insert(header);
+                        }
+                    }
+                }
+                Err(err) => {
+                    self.error = Some(Either::Left(err.into()));
+                    break;
+                }
+            }
+        }
+
+        self
+    }
+
+    /// Set a maximum time (in seconds) for which this CORS request maybe cached.
+    /// This value is set as the `Access-Control-Max-Age` header as specified in
+    /// the [Fetch Standard CORS protocol].
+    ///
+    /// Pass a number (of seconds) or use None to disable sending max age header.
+    ///
+    /// [Fetch Standard CORS protocol]: https://fetch.spec.whatwg.org/#http-cors-protocol
+    pub fn max_age(mut self, max_age: impl Into<Option<usize>>) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.max_age = max_age.into()
+        }
+
+        self
+    }
+
+    /// Set to use wildcard origins.
+    ///
+    /// If send wildcard is set and the `allowed_origins` parameter is `All`, a wildcard
+    /// `Access-Control-Allow-Origin` response header is sent, rather than the request’s
+    /// `Origin` header.
+    ///
+    /// This **CANNOT** be used in conjunction with `allowed_origins` set to `All` and
+    /// `allow_credentials` set to `true`. Depending on the mode of usage, this will either result
+    /// in an `CorsError::CredentialsWithWildcardOrigin` error during actix launch or runtime.
+    ///
+    /// Defaults to `false`.
+    pub fn send_wildcard(mut self) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.send_wildcard = true
+        }
+
+        self
+    }
+
+    /// Allows users to make authenticated requests
+    ///
+    /// If true, injects the `Access-Control-Allow-Credentials` header in responses. This allows
+    /// cookies and credentials to be submitted across domains as specified in
+    /// the [Fetch Standard CORS protocol].
+    ///
+    /// This option cannot be used in conjunction with an `allowed_origin` set to `All` and
+    /// `send_wildcards` set to `true`.
+    ///
+    /// Defaults to `false`.
+    ///
+    /// A server initialization error will occur if credentials are allowed, but the Origin is set
+    /// to send wildcards (`*`); this is not allowed by the CORS protocol.
+    ///
+    /// [Fetch Standard CORS protocol]: https://fetch.spec.whatwg.org/#http-cors-protocol
+    pub fn supports_credentials(mut self) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.supports_credentials = true
+        }
+
+        self
+    }
+
+    /// Disable `Vary` header support.
+    ///
+    /// When enabled the header `Vary: Origin` will be returned as per the Fetch Standard
+    /// implementation guidelines.
+    ///
+    /// Setting this header when the `Access-Control-Allow-Origin` is dynamically generated
+    /// (eg. when there is more than one allowed origin, and an Origin other than '*' is returned)
+    /// informs CDNs and other caches that the CORS headers are dynamic, and cannot be cached.
+    ///
+    /// By default, `Vary` header support is enabled.
+    pub fn disable_vary_header(mut self) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.vary_header = false
+        }
+
+        self
+    }
+
+    /// Disable support for preflight requests.
+    ///
+    /// When enabled CORS middleware automatically handles `OPTIONS` requests.
+    /// This is useful for application level middleware.
+    ///
+    /// By default *preflight* support is enabled.
+    pub fn disable_preflight(mut self) -> Cors {
+        if let Some(cors) = cors(&mut self.inner, &self.error) {
+            cors.preflight = false
+        }
+
+        self
+    }
+}
+
+impl Default for Cors {
+    /// A restrictive (security paranoid) set of defaults.
+    ///
+    /// *No* allowed origins, methods, request headers or exposed headers. Credentials
+    /// not supported. No max age (will use browser's default).
+    fn default() -> Cors {
+        let inner = Inner {
+            allowed_origins: AllOrSome::Some(HashSet::with_capacity(8)),
+            allowed_origins_fns: tiny_vec![],
+
+            allowed_methods: HashSet::with_capacity(8),
+            allowed_methods_baked: None,
+
+            allowed_headers: AllOrSome::Some(HashSet::with_capacity(8)),
+            allowed_headers_baked: None,
+
+            expose_headers: AllOrSome::Some(HashSet::with_capacity(8)),
+            expose_headers_baked: None,
+
+            max_age: None,
+            preflight: true,
+            send_wildcard: false,
+            supports_credentials: false,
+            vary_header: true,
+        };
+
+        Cors {
+            inner: Rc::new(inner),
+            error: None,
+        }
+    }
+}
+
+impl<S, B> Transform<S, ServiceRequest> for Cors
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    S::Future: 'static,
+    B: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type InitError = ();
+    type Transform = CorsMiddleware<S>;
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        if let Some(ref err) = self.error {
+            match err {
+                Either::Left(err) => error!("{}", err),
+                Either::Right(err) => error!("{}", err),
+            }
+
+            return future::err(());
+        }
+
+        let mut inner = Rc::clone(&self.inner);
+
+        if inner.supports_credentials
+            && inner.send_wildcard
+            && inner.allowed_origins.is_all()
+        {
+            error!("Illegal combination of CORS options: credentials can not be supported when all \
+                    origins are allowed and `send_wildcard` is enabled.");
+            return future::err(());
+        }
+
+        // bake allowed headers value if Some and not empty
+        match inner.allowed_headers.as_ref() {
+            Some(header_set) if !header_set.is_empty() => {
+                let allowed_headers_str = intersperse_header_values(header_set);
+                Rc::make_mut(&mut inner).allowed_headers_baked =
+                    Some(allowed_headers_str);
+            }
+            _ => {}
+        }
+
+        // bake allowed methods value if not empty
+        if !inner.allowed_methods.is_empty() {
+            let allowed_methods_str = intersperse_header_values(&inner.allowed_methods);
+            Rc::make_mut(&mut inner).allowed_methods_baked = Some(allowed_methods_str);
+        }
+
+        // bake exposed headers value if Some and not empty
+        match inner.expose_headers.as_ref() {
+            Some(header_set) if !header_set.is_empty() => {
+                let expose_headers_str = intersperse_header_values(header_set);
+                Rc::make_mut(&mut inner).expose_headers_baked = Some(expose_headers_str);
+            }
+            _ => {}
+        }
+
+        future::ok(CorsMiddleware { service, inner })
+    }
+}
+
+/// Only call when values are guaranteed to be valid header values and set is not empty.
+fn intersperse_header_values<T>(val_set: &HashSet<T>) -> HeaderValue
+where
+    T: AsRef<str>,
+{
+    val_set
+        .iter()
+        .fold(String::with_capacity(32), |mut acc, val| {
+            acc.push_str(", ");
+            acc.push_str(val.as_ref());
+            acc
+        })
+        // set is not empty so string will always have leading ", " to trim
+        [2..]
+        .try_into()
+        // all method names are valid header values
+        .unwrap()
+}
+
+#[cfg(test)]
+mod test {
+    use std::convert::{Infallible, TryInto};
+
+    use actix_web::{
+        dev::Transform,
+        http::{HeaderName, StatusCode},
+        test::{self, TestRequest},
+    };
+
+    use super::*;
+
+    #[test]
+    fn illegal_allow_credentials() {
+        // using the permissive defaults (all origins allowed) and adding send_wildcard
+        // and supports_credentials should error on construction
+
+        assert!(Cors::permissive()
+            .supports_credentials()
+            .send_wildcard()
+            .new_transform(test::ok_service())
+            .into_inner()
+            .is_err());
+    }
+
+    #[actix_rt::test]
+    async fn restrictive_defaults() {
+        let cors = Cors::default()
+            .new_transform(test::ok_service())
+            .await
+            .unwrap();
+
+        let req = TestRequest::default()
+            .insert_header(("Origin", "https://www.example.com"))
+            .to_srv_request();
+
+        let resp = test::call_service(&cors, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[actix_rt::test]
+    async fn allowed_header_try_from() {
+        let _cors = Cors::default().allowed_header("Content-Type");
+    }
+
+    #[actix_rt::test]
+    async fn allowed_header_try_into() {
+        struct ContentType;
+
+        impl TryInto<HeaderName> for ContentType {
+            type Error = Infallible;
+
+            fn try_into(self) -> Result<HeaderName, Self::Error> {
+                Ok(HeaderName::from_static("content-type"))
+            }
+        }
+
+        let _cors = Cors::default().allowed_header(ContentType);
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_cors/error.rs.html b/src/actix_cors/error.rs.html new file mode 100644 index 000000000..0c8f304de --- /dev/null +++ b/src/actix_cors/error.rs.html @@ -0,0 +1,117 @@ +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
+
+use actix_web::{http::StatusCode, HttpResponse, ResponseError};
+
+use derive_more::{Display, Error};
+
+/// Errors that can occur when processing CORS guarded requests.
+#[derive(Debug, Clone, Display, Error)]
+#[non_exhaustive]
+pub enum CorsError {
+    /// Allowed origin argument must not be wildcard (`*`).
+    #[display(fmt = "`allowed_origin` argument must not be wildcard (`*`).")]
+    WildcardOrigin,
+
+    /// Request header `Origin` is required but was not provided.
+    #[display(fmt = "Request header `Origin` is required but was not provided.")]
+    MissingOrigin,
+
+    /// Request header `Access-Control-Request-Method` is required but is missing.
+    #[display(
+        fmt = "Request header `Access-Control-Request-Method` is required but is missing."
+    )]
+    MissingRequestMethod,
+
+    /// Request header `Access-Control-Request-Method` has an invalid value.
+    #[display(
+        fmt = "Request header `Access-Control-Request-Method` has an invalid value."
+    )]
+    BadRequestMethod,
+
+    /// Request header `Access-Control-Request-Headers` has an invalid value.
+    #[display(
+        fmt = "Request header `Access-Control-Request-Headers` has an invalid value."
+    )]
+    BadRequestHeaders,
+
+    /// Origin is not allowed to make this request.
+    #[display(fmt = "Origin is not allowed to make this request.")]
+    OriginNotAllowed,
+
+    /// Request method is not allowed.
+    #[display(fmt = "Requested method is not allowed.")]
+    MethodNotAllowed,
+
+    /// One or more request headers are not allowed.
+    #[display(fmt = "One or more request headers are not allowed.")]
+    HeadersNotAllowed,
+}
+
+impl ResponseError for CorsError {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+
+    fn error_response(&self) -> HttpResponse {
+        HttpResponse::with_body(StatusCode::BAD_REQUEST, self.to_string().into())
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_cors/inner.rs.html b/src/actix_cors/inner.rs.html new file mode 100644 index 000000000..32fdac18a --- /dev/null +++ b/src/actix_cors/inner.rs.html @@ -0,0 +1,681 @@ +inner.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
+
+use std::{collections::HashSet, convert::TryFrom, convert::TryInto, fmt, rc::Rc};
+
+use actix_web::{
+    dev::RequestHead,
+    error::Result,
+    http::{
+        header::{self, HeaderName, HeaderValue},
+        Method,
+    },
+};
+use once_cell::sync::Lazy;
+use tinyvec::TinyVec;
+
+use crate::{AllOrSome, CorsError};
+
+#[derive(Clone)]
+pub(crate) struct OriginFn {
+    pub(crate) boxed_fn: Rc<dyn Fn(&HeaderValue, &RequestHead) -> bool>,
+}
+
+impl Default for OriginFn {
+    /// Dummy default for use in tiny_vec. Do not use.
+    fn default() -> Self {
+        let boxed_fn: Rc<dyn Fn(&_, &_) -> _> = Rc::new(|_origin, _req_head| false);
+        Self { boxed_fn }
+    }
+}
+
+impl fmt::Debug for OriginFn {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("origin_fn")
+    }
+}
+
+/// Try to parse header value as HTTP method.
+fn header_value_try_into_method(hdr: &HeaderValue) -> Option<Method> {
+    hdr.to_str()
+        .ok()
+        .and_then(|meth| Method::try_from(meth).ok())
+}
+
+#[derive(Debug, Clone)]
+pub(crate) struct Inner {
+    pub(crate) allowed_origins: AllOrSome<HashSet<HeaderValue>>,
+    pub(crate) allowed_origins_fns: TinyVec<[OriginFn; 4]>,
+
+    pub(crate) allowed_methods: HashSet<Method>,
+    pub(crate) allowed_methods_baked: Option<HeaderValue>,
+
+    pub(crate) allowed_headers: AllOrSome<HashSet<HeaderName>>,
+    pub(crate) allowed_headers_baked: Option<HeaderValue>,
+
+    /// `All` will echo back `Access-Control-Request-Header` list.
+    pub(crate) expose_headers: AllOrSome<HashSet<HeaderName>>,
+    pub(crate) expose_headers_baked: Option<HeaderValue>,
+
+    pub(crate) max_age: Option<usize>,
+    pub(crate) preflight: bool,
+    pub(crate) send_wildcard: bool,
+    pub(crate) supports_credentials: bool,
+    pub(crate) vary_header: bool,
+}
+
+static EMPTY_ORIGIN_SET: Lazy<HashSet<HeaderValue>> = Lazy::new(HashSet::new);
+
+impl Inner {
+    pub(crate) fn validate_origin(&self, req: &RequestHead) -> Result<(), CorsError> {
+        // return early if all origins are allowed or get ref to allowed origins set
+        #[allow(clippy::mutable_key_type)]
+        let allowed_origins = match &self.allowed_origins {
+            AllOrSome::All if self.allowed_origins_fns.is_empty() => return Ok(()),
+            AllOrSome::Some(allowed_origins) => allowed_origins,
+            // only function origin validators are defined
+            _ => &EMPTY_ORIGIN_SET,
+        };
+
+        // get origin header and try to parse as string
+        match req.headers().get(header::ORIGIN) {
+            // origin header exists and is a string
+            Some(origin) => {
+                if allowed_origins.contains(origin)
+                    || self.validate_origin_fns(origin, req)
+                {
+                    Ok(())
+                } else {
+                    Err(CorsError::OriginNotAllowed)
+                }
+            }
+
+            // origin header is missing
+            // note: with our implementation, the origin header is required for OPTIONS request or
+            // else this would be unreachable
+            None => Err(CorsError::MissingOrigin),
+        }
+    }
+
+    /// Accepts origin if _ANY_ functions return true. Only called when Origin exists.
+    fn validate_origin_fns(&self, origin: &HeaderValue, req: &RequestHead) -> bool {
+        self.allowed_origins_fns
+            .iter()
+            .any(|origin_fn| (origin_fn.boxed_fn)(origin, req))
+    }
+
+    /// Only called if origin exists and always after it's validated.
+    pub(crate) fn access_control_allow_origin(
+        &self,
+        req: &RequestHead,
+    ) -> Option<HeaderValue> {
+        let origin = req.headers().get(header::ORIGIN);
+
+        match self.allowed_origins {
+            AllOrSome::All => {
+                if self.send_wildcard {
+                    Some(HeaderValue::from_static("*"))
+                } else {
+                    // see note below about why `.cloned()` is correct
+                    origin.cloned()
+                }
+            }
+
+            AllOrSome::Some(_) => {
+                // since origin (if it exists) is known to be allowed if this method is called
+                // then cloning the option is all that is required to be used as an echoed back
+                // header value (or omitted if None)
+                origin.cloned()
+            }
+        }
+    }
+
+    /// Use in preflight checks and therefore operates on header list in
+    /// `Access-Control-Request-Headers` not the actual header set.
+    pub(crate) fn validate_allowed_method(
+        &self,
+        req: &RequestHead,
+    ) -> Result<(), CorsError> {
+        // extract access control header and try to parse as method
+        let request_method = req
+            .headers()
+            .get(header::ACCESS_CONTROL_REQUEST_METHOD)
+            .map(header_value_try_into_method);
+
+        match request_method {
+            // method valid and allowed
+            Some(Some(method)) if self.allowed_methods.contains(&method) => Ok(()),
+
+            // method valid but not allowed
+            Some(Some(_)) => Err(CorsError::MethodNotAllowed),
+
+            // method invalid
+            Some(_) => Err(CorsError::BadRequestMethod),
+
+            // method missing
+            None => Err(CorsError::MissingRequestMethod),
+        }
+    }
+
+    pub(crate) fn validate_allowed_headers(
+        &self,
+        req: &RequestHead,
+    ) -> Result<(), CorsError> {
+        // return early if all headers are allowed or get ref to allowed origins set
+        #[allow(clippy::mutable_key_type)]
+        let allowed_headers = match &self.allowed_headers {
+            AllOrSome::All => return Ok(()),
+            AllOrSome::Some(allowed_headers) => allowed_headers,
+        };
+
+        // extract access control header as string
+        // header format should be comma separated header names
+        let request_headers = req
+            .headers()
+            .get(header::ACCESS_CONTROL_REQUEST_HEADERS)
+            .map(|hdr| hdr.to_str());
+
+        match request_headers {
+            // header list is valid string
+            Some(Ok(headers)) => {
+                // the set is ephemeral we take care not to mutate the
+                // inserted keys so this lint exception is acceptable
+                #[allow(clippy::mutable_key_type)]
+                let mut request_headers = HashSet::with_capacity(8);
+
+                // try to convert each header name in the comma-separated list
+                for hdr in headers.split(',') {
+                    match hdr.trim().try_into() {
+                        Ok(hdr) => request_headers.insert(hdr),
+                        Err(_) => return Err(CorsError::BadRequestHeaders),
+                    };
+                }
+
+                // header list must contain 1 or more header name
+                if request_headers.is_empty() {
+                    return Err(CorsError::BadRequestHeaders);
+                }
+
+                // request header list must be a subset of allowed headers
+                if !request_headers.is_subset(allowed_headers) {
+                    return Err(CorsError::HeadersNotAllowed);
+                }
+
+                Ok(())
+            }
+
+            // header list is not a string
+            Some(Err(_)) => Err(CorsError::BadRequestHeaders),
+
+            // header list missing
+            None => Ok(()),
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use std::rc::Rc;
+
+    use actix_web::{
+        dev::Transform,
+        http::{header, HeaderValue, Method, StatusCode},
+        test::{self, TestRequest},
+    };
+
+    use crate::Cors;
+
+    fn val_as_str(val: &HeaderValue) -> &str {
+        val.to_str().unwrap()
+    }
+
+    #[actix_rt::test]
+    async fn test_validate_not_allowed_origin() {
+        let cors = Cors::default()
+            .allowed_origin("https://www.example.com")
+            .new_transform(test::ok_service())
+            .await
+            .unwrap();
+
+        let req = TestRequest::get()
+            .insert_header((header::ORIGIN, "https://www.unknown.com"))
+            .insert_header((header::ACCESS_CONTROL_REQUEST_HEADERS, "DNT"))
+            .to_srv_request();
+
+        assert!(cors.inner.validate_origin(req.head()).is_err());
+        assert!(cors.inner.validate_allowed_method(req.head()).is_err());
+        assert!(cors.inner.validate_allowed_headers(req.head()).is_err());
+    }
+
+    #[actix_rt::test]
+    async fn test_preflight() {
+        let mut cors = Cors::default()
+            .allow_any_origin()
+            .send_wildcard()
+            .max_age(3600)
+            .allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST])
+            .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
+            .allowed_header(header::CONTENT_TYPE)
+            .new_transform(test::ok_service())
+            .await
+            .unwrap();
+
+        let req = TestRequest::default()
+            .method(Method::OPTIONS)
+            .insert_header(("Origin", "https://www.example.com"))
+            .insert_header((header::ACCESS_CONTROL_REQUEST_HEADERS, "X-Not-Allowed"))
+            .to_srv_request();
+
+        assert!(cors.inner.validate_allowed_method(req.head()).is_err());
+        assert!(cors.inner.validate_allowed_headers(req.head()).is_err());
+        let resp = test::call_service(&cors, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::default()
+            .method(Method::OPTIONS)
+            .insert_header(("Origin", "https://www.example.com"))
+            .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "put"))
+            .to_srv_request();
+
+        assert!(cors.inner.validate_allowed_method(req.head()).is_err());
+        assert!(cors.inner.validate_allowed_headers(req.head()).is_ok());
+
+        let req = TestRequest::default()
+            .method(Method::OPTIONS)
+            .insert_header(("Origin", "https://www.example.com"))
+            .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "POST"))
+            .insert_header((
+                header::ACCESS_CONTROL_REQUEST_HEADERS,
+                "AUTHORIZATION,ACCEPT",
+            ))
+            .to_srv_request();
+
+        let resp = test::call_service(&cors, req).await;
+        assert_eq!(
+            Some(&b"*"[..]),
+            resp.headers()
+                .get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
+                .map(HeaderValue::as_bytes)
+        );
+        assert_eq!(
+            Some(&b"3600"[..]),
+            resp.headers()
+                .get(header::ACCESS_CONTROL_MAX_AGE)
+                .map(HeaderValue::as_bytes)
+        );
+
+        let hdr = resp
+            .headers()
+            .get(header::ACCESS_CONTROL_ALLOW_HEADERS)
+            .map(val_as_str)
+            .unwrap();
+        assert!(hdr.contains("authorization"));
+        assert!(hdr.contains("accept"));
+        assert!(hdr.contains("content-type"));
+
+        let methods = resp
+            .headers()
+            .get(header::ACCESS_CONTROL_ALLOW_METHODS)
+            .unwrap()
+            .to_str()
+            .unwrap();
+        assert!(methods.contains("POST"));
+        assert!(methods.contains("GET"));
+        assert!(methods.contains("OPTIONS"));
+
+        Rc::get_mut(&mut cors.inner).unwrap().preflight = false;
+
+        let req = TestRequest::default()
+            .method(Method::OPTIONS)
+            .insert_header(("Origin", "https://www.example.com"))
+            .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "POST"))
+            .insert_header((
+                header::ACCESS_CONTROL_REQUEST_HEADERS,
+                "AUTHORIZATION,ACCEPT",
+            ))
+            .to_srv_request();
+
+        let resp = test::call_service(&cors, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_cors/lib.rs.html b/src/actix_cors/lib.rs.html new file mode 100644 index 000000000..1b5b64efe --- /dev/null +++ b/src/actix_cors/lib.rs.html @@ -0,0 +1,125 @@ +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
+
+//! Cross-Origin Resource Sharing (CORS) controls for Actix Web.
+//!
+//! This middleware can be applied to both applications and resources. Once built, a
+//! [`Cors`] builder can be used as an argument for Actix Web's `App::wrap()`,
+//! `Scope::wrap()`, or `Resource::wrap()` methods.
+//!
+//! This CORS middleware automatically handles `OPTIONS` preflight requests.
+//!
+//! # Example
+//! ```rust,no_run
+//! use actix_cors::Cors;
+//! use actix_web::{get, http, web, App, HttpRequest, HttpResponse, HttpServer};
+//!
+//! #[get("/index.html")]
+//! async fn index(req: HttpRequest) -> &'static str {
+//!     "<p>Hello World!</p>"
+//! }
+//!
+//! #[actix_web::main]
+//! async fn main() -> std::io::Result<()> {
+//!     HttpServer::new(|| {
+//!         let cors = Cors::default()
+//!               .allowed_origin("https://www.rust-lang.org/")
+//!               .allowed_origin_fn(|origin, _req_head| {
+//!                   origin.as_bytes().ends_with(b".rust-lang.org")
+//!               })
+//!               .allowed_methods(vec!["GET", "POST"])
+//!               .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
+//!               .allowed_header(http::header::CONTENT_TYPE)
+//!               .max_age(3600);
+//!
+//!         App::new()
+//!             .wrap(cors)
+//!             .service(index)
+//!     })
+//!     .bind(("127.0.0.1", 8080))?
+//!     .run()
+//!     .await;
+//!
+//!     Ok(())
+//! }
+//! ```
+
+#![forbid(unsafe_code)]
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(missing_docs, missing_debug_implementations)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+
+mod all_or_some;
+mod builder;
+mod error;
+mod inner;
+mod middleware;
+
+use all_or_some::AllOrSome;
+pub use builder::Cors;
+pub use error::CorsError;
+use inner::{Inner, OriginFn};
+pub use middleware::CorsMiddleware;
+
+
+ \ No newline at end of file diff --git a/src/actix_cors/middleware.rs.html b/src/actix_cors/middleware.rs.html new file mode 100644 index 000000000..5841a977b --- /dev/null +++ b/src/actix_cors/middleware.rs.html @@ -0,0 +1,439 @@ +middleware.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
+
+use std::{convert::TryInto, rc::Rc};
+
+use actix_web::{
+    dev::{Service, ServiceRequest, ServiceResponse},
+    error::{Error, Result},
+    http::{
+        header::{self, HeaderValue},
+        Method,
+    },
+    HttpResponse,
+};
+use futures_util::future::{ok, Either, FutureExt as _, LocalBoxFuture, Ready};
+use log::debug;
+
+use crate::Inner;
+
+/// Service wrapper for Cross-Origin Resource Sharing support.
+///
+/// This struct contains the settings for CORS requests to be validated and for responses to
+/// be generated.
+#[doc(hidden)]
+#[derive(Debug, Clone)]
+pub struct CorsMiddleware<S> {
+    pub(crate) service: S,
+    pub(crate) inner: Rc<Inner>,
+}
+
+impl<S> CorsMiddleware<S> {
+    fn handle_preflight<B>(inner: &Inner, req: ServiceRequest) -> ServiceResponse<B> {
+        if let Err(err) = inner
+            .validate_origin(req.head())
+            .and_then(|_| inner.validate_allowed_method(req.head()))
+            .and_then(|_| inner.validate_allowed_headers(req.head()))
+        {
+            return req.error_response(err);
+        }
+
+        let mut res = HttpResponse::Ok();
+
+        if let Some(origin) = inner.access_control_allow_origin(req.head()) {
+            res.insert_header((header::ACCESS_CONTROL_ALLOW_ORIGIN, origin));
+        }
+
+        if let Some(ref allowed_methods) = inner.allowed_methods_baked {
+            res.insert_header((
+                header::ACCESS_CONTROL_ALLOW_METHODS,
+                allowed_methods.clone(),
+            ));
+        }
+
+        if let Some(ref headers) = inner.allowed_headers_baked {
+            res.insert_header((header::ACCESS_CONTROL_ALLOW_HEADERS, headers.clone()));
+        } else if let Some(headers) =
+            req.headers().get(header::ACCESS_CONTROL_REQUEST_HEADERS)
+        {
+            // all headers allowed, return
+            res.insert_header((header::ACCESS_CONTROL_ALLOW_HEADERS, headers.clone()));
+        }
+
+        if inner.supports_credentials {
+            res.insert_header((
+                header::ACCESS_CONTROL_ALLOW_CREDENTIALS,
+                HeaderValue::from_static("true"),
+            ));
+        }
+
+        if let Some(max_age) = inner.max_age {
+            res.insert_header((header::ACCESS_CONTROL_MAX_AGE, max_age.to_string()));
+        }
+
+        let res = res.finish();
+        let res = res.into_body();
+        req.into_response(res)
+    }
+
+    fn augment_response<B>(
+        inner: &Inner,
+        mut res: ServiceResponse<B>,
+    ) -> ServiceResponse<B> {
+        if let Some(origin) = inner.access_control_allow_origin(res.request().head()) {
+            res.headers_mut()
+                .insert(header::ACCESS_CONTROL_ALLOW_ORIGIN, origin);
+        };
+
+        if let Some(ref expose) = inner.expose_headers_baked {
+            res.headers_mut()
+                .insert(header::ACCESS_CONTROL_EXPOSE_HEADERS, expose.clone());
+        }
+
+        if inner.supports_credentials {
+            res.headers_mut().insert(
+                header::ACCESS_CONTROL_ALLOW_CREDENTIALS,
+                HeaderValue::from_static("true"),
+            );
+        }
+
+        if inner.vary_header {
+            let value = match res.headers_mut().get(header::VARY) {
+                Some(hdr) => {
+                    let mut val: Vec<u8> = Vec::with_capacity(hdr.len() + 8);
+                    val.extend(hdr.as_bytes());
+                    val.extend(b", Origin");
+                    val.try_into().unwrap()
+                }
+                None => HeaderValue::from_static("Origin"),
+            };
+
+            res.headers_mut().insert(header::VARY, value);
+        }
+
+        res
+    }
+}
+
+type CorsMiddlewareServiceFuture<B> = Either<
+    Ready<Result<ServiceResponse<B>, Error>>,
+    LocalBoxFuture<'static, Result<ServiceResponse<B>, Error>>,
+>;
+
+impl<S, B> Service<ServiceRequest> for CorsMiddleware<S>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    S::Future: 'static,
+    B: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type Future = CorsMiddlewareServiceFuture<B>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        if self.inner.preflight && req.method() == Method::OPTIONS {
+            let inner = Rc::clone(&self.inner);
+            let res = Self::handle_preflight(&inner, req);
+            Either::Left(ok(res))
+        } else {
+            let origin = req.headers().get(header::ORIGIN).cloned();
+
+            if origin.is_some() {
+                // Only check requests with a origin header.
+                if let Err(err) = self.inner.validate_origin(req.head()) {
+                    debug!("origin validation failed; inner service is not called");
+                    return Either::Left(ok(req.error_response(err)));
+                }
+            }
+
+            let inner = Rc::clone(&self.inner);
+            let fut = self.service.call(req);
+
+            let res = async move {
+                let res = fut.await;
+
+                if origin.is_some() {
+                    let res = res?;
+                    Ok(Self::augment_response(&inner, res))
+                } else {
+                    res
+                }
+            }
+            .boxed_local();
+
+            Either::Right(res)
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_web::{
+        dev::Transform,
+        test::{self, TestRequest},
+    };
+
+    use super::*;
+    use crate::Cors;
+
+    #[actix_rt::test]
+    async fn test_options_no_origin() {
+        // Tests case where allowed_origins is All but there are validate functions to run incase.
+        // In this case, origins are only allowed when the DNT header is sent.
+
+        let cors = Cors::default()
+            .allow_any_origin()
+            .allowed_origin_fn(|origin, req_head| {
+                assert_eq!(&origin, req_head.headers.get(header::ORIGIN).unwrap());
+
+                req_head.headers().contains_key(header::DNT)
+            })
+            .new_transform(test::ok_service())
+            .await
+            .unwrap();
+
+        let req = TestRequest::get()
+            .insert_header((header::ORIGIN, "http://example.com"))
+            .to_srv_request();
+        let res = cors.call(req).await.unwrap();
+        assert_eq!(
+            None,
+            res.headers()
+                .get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
+                .map(HeaderValue::as_bytes)
+        );
+
+        let req = TestRequest::get()
+            .insert_header((header::ORIGIN, "http://example.com"))
+            .insert_header((header::DNT, "1"))
+            .to_srv_request();
+        let res = cors.call(req).await.unwrap();
+        assert_eq!(
+            Some(&b"http://example.com"[..]),
+            res.headers()
+                .get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
+                .map(HeaderValue::as_bytes)
+        );
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_identity/lib.rs.html b/src/actix_identity/lib.rs.html new file mode 100644 index 000000000..8d59c549e --- /dev/null +++ b/src/actix_identity/lib.rs.html @@ -0,0 +1,2291 @@ +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
+ 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
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+
+//! Request identity service for Actix applications.
+//!
+//! [**IdentityService**](struct.IdentityService.html) middleware can be
+//! used with different policies types to store identity information.
+//!
+//! By default, only cookie identity policy is implemented. Other backend
+//! implementations can be added separately.
+//!
+//! [**CookieIdentityPolicy**](struct.CookieIdentityPolicy.html)
+//! uses cookies as identity storage.
+//!
+//! To access current request identity
+//! [**Identity**](struct.Identity.html) extractor should be used.
+//!
+//! ```
+//! use actix_web::*;
+//! use actix_identity::{Identity, CookieIdentityPolicy, IdentityService};
+//!
+//! async fn index(id: Identity) -> String {
+//!     // access request identity
+//!     if let Some(id) = id.identity() {
+//!         format!("Welcome! {}", id)
+//!     } else {
+//!         "Welcome Anonymous!".to_owned()
+//!     }
+//! }
+//!
+//! async fn login(id: Identity) -> HttpResponse {
+//!     id.remember("User1".to_owned()); // <- remember identity
+//!     HttpResponse::Ok().finish()
+//! }
+//!
+//! async fn logout(id: Identity) -> HttpResponse {
+//!     id.forget();                      // <- remove identity
+//!     HttpResponse::Ok().finish()
+//! }
+//!
+//! fn main() {
+//!     let app = App::new().wrap(IdentityService::new(
+//!         // <- create identity middleware
+//!         CookieIdentityPolicy::new(&[0; 32])    // <- create cookie identity policy
+//!               .name("auth-cookie")
+//!               .secure(false)))
+//!         .service(web::resource("/index.html").to(index))
+//!         .service(web::resource("/login.html").to(login))
+//!         .service(web::resource("/logout.html").to(logout));
+//! }
+//! ```
+
+#![deny(rust_2018_idioms)]
+
+use std::{future::Future, rc::Rc, time::SystemTime};
+
+use actix_service::{Service, Transform};
+use futures_util::future::{ok, FutureExt, LocalBoxFuture, Ready};
+use serde::{Deserialize, Serialize};
+use time::Duration;
+
+use actix_web::cookie::{Cookie, CookieJar, Key, SameSite};
+use actix_web::dev::{Extensions, Payload, ServiceRequest, ServiceResponse};
+use actix_web::error::{Error, Result};
+use actix_web::http::header::{self, HeaderValue};
+use actix_web::{FromRequest, HttpMessage, HttpRequest};
+
+/// The extractor type to obtain your identity from a request.
+///
+/// ```rust
+/// use actix_web::*;
+/// use actix_identity::Identity;
+///
+/// fn index(id: Identity) -> Result<String> {
+///     // access request identity
+///     if let Some(id) = id.identity() {
+///         Ok(format!("Welcome! {}", id))
+///     } else {
+///         Ok("Welcome Anonymous!".to_owned())
+///     }
+/// }
+///
+/// fn login(id: Identity) -> HttpResponse {
+///     id.remember("User1".to_owned()); // <- remember identity
+///     HttpResponse::Ok().finish()
+/// }
+///
+/// fn logout(id: Identity) -> HttpResponse {
+///     id.forget(); // <- remove identity
+///     HttpResponse::Ok().finish()
+/// }
+/// # fn main() {}
+/// ```
+#[derive(Clone)]
+pub struct Identity(HttpRequest);
+
+impl Identity {
+    /// Return the claimed identity of the user associated request or
+    /// ``None`` if no identity can be found associated with the request.
+    pub fn identity(&self) -> Option<String> {
+        Identity::get_identity(&self.0.extensions())
+    }
+
+    /// Remember identity.
+    pub fn remember(&self, identity: String) {
+        if let Some(id) = self.0.extensions_mut().get_mut::<IdentityItem>() {
+            id.id = Some(identity);
+            id.changed = true;
+        }
+    }
+
+    /// This method is used to 'forget' the current identity on subsequent
+    /// requests.
+    pub fn forget(&self) {
+        if let Some(id) = self.0.extensions_mut().get_mut::<IdentityItem>() {
+            id.id = None;
+            id.changed = true;
+        }
+    }
+
+    fn get_identity(extensions: &Extensions) -> Option<String> {
+        if let Some(id) = extensions.get::<IdentityItem>() {
+            id.id.clone()
+        } else {
+            None
+        }
+    }
+}
+
+struct IdentityItem {
+    id: Option<String>,
+    changed: bool,
+}
+
+/// Helper trait that allows to get Identity.
+///
+/// It could be used in middleware but identity policy must be set before any other middleware that needs identity
+/// RequestIdentity is implemented both for `ServiceRequest` and `HttpRequest`.
+pub trait RequestIdentity {
+    fn get_identity(&self) -> Option<String>;
+}
+
+impl<T> RequestIdentity for T
+where
+    T: HttpMessage,
+{
+    fn get_identity(&self) -> Option<String> {
+        Identity::get_identity(&self.extensions())
+    }
+}
+
+/// Extractor implementation for Identity type.
+///
+/// ```rust
+/// # use actix_web::*;
+/// use actix_identity::Identity;
+///
+/// fn index(id: Identity) -> String {
+///     // access request identity
+///     if let Some(id) = id.identity() {
+///         format!("Welcome! {}", id)
+///     } else {
+///         "Welcome Anonymous!".to_owned()
+///     }
+/// }
+/// # fn main() {}
+/// ```
+impl FromRequest for Identity {
+    type Config = ();
+    type Error = Error;
+    type Future = Ready<Result<Identity, Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        ok(Identity(req.clone()))
+    }
+}
+
+/// Identity policy definition.
+pub trait IdentityPolicy: Sized + 'static {
+    /// The return type of the middleware
+    type Future: Future<Output = Result<Option<String>, Error>>;
+
+    /// The return type of the middleware
+    type ResponseFuture: Future<Output = Result<(), Error>>;
+
+    /// Parse the session from request and load data from a service identity.
+    fn from_request(&self, request: &mut ServiceRequest) -> Self::Future;
+
+    /// Write changes to response
+    fn to_response<B>(
+        &self,
+        identity: Option<String>,
+        changed: bool,
+        response: &mut ServiceResponse<B>,
+    ) -> Self::ResponseFuture;
+}
+
+/// Request identity middleware
+///
+/// ```rust
+/// use actix_web::App;
+/// use actix_identity::{CookieIdentityPolicy, IdentityService};
+///
+/// let app = App::new().wrap(IdentityService::new(
+///     // <- create identity middleware
+///     CookieIdentityPolicy::new(&[0; 32])    // <- create cookie session backend
+///           .name("auth-cookie")
+///           .secure(false),
+/// ));
+/// ```
+pub struct IdentityService<T> {
+    backend: Rc<T>,
+}
+
+impl<T> IdentityService<T> {
+    /// Create new identity service with specified backend.
+    pub fn new(backend: T) -> Self {
+        IdentityService {
+            backend: Rc::new(backend),
+        }
+    }
+}
+
+impl<S, T, B> Transform<S, ServiceRequest> for IdentityService<T>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
+    S::Future: 'static,
+    T: IdentityPolicy,
+    B: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type InitError = ();
+    type Transform = IdentityServiceMiddleware<S, T>;
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        ok(IdentityServiceMiddleware {
+            backend: self.backend.clone(),
+            service: Rc::new(service),
+        })
+    }
+}
+
+#[doc(hidden)]
+pub struct IdentityServiceMiddleware<S, T> {
+    service: Rc<S>,
+    backend: Rc<T>,
+}
+
+impl<S, T> Clone for IdentityServiceMiddleware<S, T> {
+    fn clone(&self) -> Self {
+        Self {
+            backend: Rc::clone(&self.backend),
+            service: Rc::clone(&self.service),
+        }
+    }
+}
+
+impl<S, T, B> Service<ServiceRequest> for IdentityServiceMiddleware<S, T>
+where
+    B: 'static,
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
+    S::Future: 'static,
+    T: IdentityPolicy,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, mut req: ServiceRequest) -> Self::Future {
+        let srv = Rc::clone(&self.service);
+        let backend = Rc::clone(&self.backend);
+        let fut = self.backend.from_request(&mut req);
+
+        async move {
+            match fut.await {
+                Ok(id) => {
+                    req.extensions_mut()
+                        .insert(IdentityItem { id, changed: false });
+
+                    let mut res = srv.call(req).await?;
+                    let id = res.request().extensions_mut().remove::<IdentityItem>();
+
+                    if let Some(id) = id {
+                        match backend.to_response(id.id, id.changed, &mut res).await {
+                            Ok(_) => Ok(res),
+                            Err(e) => Ok(res.error_response(e)),
+                        }
+                    } else {
+                        Ok(res)
+                    }
+                }
+                Err(err) => Ok(req.error_response(err)),
+            }
+        }
+        .boxed_local()
+    }
+}
+
+struct CookieIdentityInner {
+    key: Key,
+    key_v2: Key,
+    name: String,
+    path: String,
+    domain: Option<String>,
+    secure: bool,
+    max_age: Option<Duration>,
+    http_only: Option<bool>,
+    same_site: Option<SameSite>,
+    visit_deadline: Option<Duration>,
+    login_deadline: Option<Duration>,
+}
+
+#[derive(Deserialize, Serialize, Debug)]
+struct CookieValue {
+    identity: String,
+
+    #[serde(skip_serializing_if = "Option::is_none")]
+    login_timestamp: Option<SystemTime>,
+
+    #[serde(skip_serializing_if = "Option::is_none")]
+    visit_timestamp: Option<SystemTime>,
+}
+
+#[derive(Debug)]
+struct CookieIdentityExtension {
+    login_timestamp: Option<SystemTime>,
+}
+
+impl CookieIdentityInner {
+    fn new(key: &[u8]) -> CookieIdentityInner {
+        let key_v2: Vec<u8> = key.iter().chain([1, 0, 0, 0].iter()).cloned().collect();
+        CookieIdentityInner {
+            key: Key::derive_from(key),
+            key_v2: Key::derive_from(&key_v2),
+            name: "actix-identity".to_owned(),
+            path: "/".to_owned(),
+            domain: None,
+            secure: true,
+            max_age: None,
+            http_only: None,
+            same_site: None,
+            visit_deadline: None,
+            login_deadline: None,
+        }
+    }
+
+    fn set_cookie<B>(
+        &self,
+        resp: &mut ServiceResponse<B>,
+        value: Option<CookieValue>,
+    ) -> Result<()> {
+        let add_cookie = value.is_some();
+        let val = value.map(|val| {
+            if !self.legacy_supported() {
+                serde_json::to_string(&val)
+            } else {
+                Ok(val.identity)
+            }
+        });
+        let mut cookie =
+            Cookie::new(self.name.clone(), val.unwrap_or_else(|| Ok(String::new()))?);
+        cookie.set_path(self.path.clone());
+        cookie.set_secure(self.secure);
+        cookie.set_http_only(true);
+
+        if let Some(ref domain) = self.domain {
+            cookie.set_domain(domain.clone());
+        }
+
+        if let Some(max_age) = self.max_age {
+            cookie.set_max_age(max_age);
+        }
+
+        if let Some(http_only) = self.http_only {
+            cookie.set_http_only(http_only);
+        }
+
+        if let Some(same_site) = self.same_site {
+            cookie.set_same_site(same_site);
+        }
+
+        let mut jar = CookieJar::new();
+        let key = if self.legacy_supported() {
+            &self.key
+        } else {
+            &self.key_v2
+        };
+        if add_cookie {
+            jar.private(&key).add(cookie);
+        } else {
+            jar.add_original(cookie.clone());
+            jar.private(&key).remove(cookie);
+        }
+        for cookie in jar.delta() {
+            let val = HeaderValue::from_str(&cookie.to_string())?;
+            resp.headers_mut().append(header::SET_COOKIE, val);
+        }
+        Ok(())
+    }
+
+    fn load(&self, req: &ServiceRequest) -> Option<CookieValue> {
+        let cookie = req.cookie(&self.name)?;
+        let mut jar = CookieJar::new();
+        jar.add_original(cookie.clone());
+        let res = if self.legacy_supported() {
+            jar.private(&self.key).get(&self.name).map(|n| CookieValue {
+                identity: n.value().to_string(),
+                login_timestamp: None,
+                visit_timestamp: None,
+            })
+        } else {
+            None
+        };
+        res.or_else(|| {
+            jar.private(&self.key_v2)
+                .get(&self.name)
+                .and_then(|c| self.parse(c))
+        })
+    }
+
+    fn parse(&self, cookie: Cookie<'_>) -> Option<CookieValue> {
+        let value: CookieValue = serde_json::from_str(cookie.value()).ok()?;
+        let now = SystemTime::now();
+        if let Some(visit_deadline) = self.visit_deadline {
+            if now.duration_since(value.visit_timestamp?).ok()? > visit_deadline {
+                return None;
+            }
+        }
+        if let Some(login_deadline) = self.login_deadline {
+            if now.duration_since(value.login_timestamp?).ok()? > login_deadline {
+                return None;
+            }
+        }
+        Some(value)
+    }
+
+    fn legacy_supported(&self) -> bool {
+        self.visit_deadline.is_none() && self.login_deadline.is_none()
+    }
+
+    fn always_update_cookie(&self) -> bool {
+        self.visit_deadline.is_some()
+    }
+
+    fn requires_oob_data(&self) -> bool {
+        self.login_deadline.is_some()
+    }
+}
+
+/// Use cookies for request identity storage.
+///
+/// The constructors take a key as an argument.
+/// This is the private key for cookie - when this value is changed,
+/// all identities are lost. The constructors will panic if the key is less
+/// than 32 bytes in length.
+///
+/// # Example
+///
+/// ```rust
+/// use actix_web::App;
+/// use actix_identity::{CookieIdentityPolicy, IdentityService};
+///
+/// let app = App::new().wrap(IdentityService::new(
+///     // <- create identity middleware
+///     CookieIdentityPolicy::new(&[0; 32])  // <- construct cookie policy
+///            .domain("www.rust-lang.org")
+///            .name("actix_auth")
+///            .path("/")
+///            .secure(true),
+/// ));
+/// ```
+pub struct CookieIdentityPolicy(Rc<CookieIdentityInner>);
+
+impl CookieIdentityPolicy {
+    /// Construct new `CookieIdentityPolicy` instance.
+    ///
+    /// Panics if key length is less than 32 bytes.
+    pub fn new(key: &[u8]) -> CookieIdentityPolicy {
+        CookieIdentityPolicy(Rc::new(CookieIdentityInner::new(key)))
+    }
+
+    /// Sets the `path` field in the session cookie being built.
+    pub fn path<S: Into<String>>(mut self, value: S) -> CookieIdentityPolicy {
+        Rc::get_mut(&mut self.0).unwrap().path = value.into();
+        self
+    }
+
+    /// Sets the `name` field in the session cookie being built.
+    pub fn name<S: Into<String>>(mut self, value: S) -> CookieIdentityPolicy {
+        Rc::get_mut(&mut self.0).unwrap().name = value.into();
+        self
+    }
+
+    /// Sets the `domain` field in the session cookie being built.
+    pub fn domain<S: Into<String>>(mut self, value: S) -> CookieIdentityPolicy {
+        Rc::get_mut(&mut self.0).unwrap().domain = Some(value.into());
+        self
+    }
+
+    /// Sets the `secure` field in the session cookie being built.
+    ///
+    /// If the `secure` field is set, a cookie will only be transmitted when the
+    /// connection is secure - i.e. `https`
+    pub fn secure(mut self, value: bool) -> CookieIdentityPolicy {
+        Rc::get_mut(&mut self.0).unwrap().secure = value;
+        self
+    }
+
+    /// Sets the `max-age` field in the session cookie being built with given number of seconds.
+    pub fn max_age(self, seconds: i64) -> CookieIdentityPolicy {
+        self.max_age_time(Duration::seconds(seconds))
+    }
+
+    /// Sets the `max-age` field in the session cookie being built with `time::Duration`.
+    pub fn max_age_time(mut self, value: Duration) -> CookieIdentityPolicy {
+        Rc::get_mut(&mut self.0).unwrap().max_age = Some(value);
+        self
+    }
+
+    /// Sets the `http_only` field in the session cookie being built.
+    pub fn http_only(mut self, http_only: bool) -> Self {
+        Rc::get_mut(&mut self.0).unwrap().http_only = Some(http_only);
+        self
+    }
+
+    /// Sets the `same_site` field in the session cookie being built.
+    pub fn same_site(mut self, same_site: SameSite) -> Self {
+        Rc::get_mut(&mut self.0).unwrap().same_site = Some(same_site);
+        self
+    }
+
+    /// Accepts only users whose cookie has been seen before the given deadline
+    ///
+    /// By default visit deadline is disabled.
+    pub fn visit_deadline(mut self, value: Duration) -> CookieIdentityPolicy {
+        Rc::get_mut(&mut self.0).unwrap().visit_deadline = Some(value);
+        self
+    }
+
+    /// Accepts only users which has been authenticated before the given deadline
+    ///
+    /// By default login deadline is disabled.
+    pub fn login_deadline(mut self, value: Duration) -> CookieIdentityPolicy {
+        Rc::get_mut(&mut self.0).unwrap().login_deadline = Some(value);
+        self
+    }
+}
+
+impl IdentityPolicy for CookieIdentityPolicy {
+    type Future = Ready<Result<Option<String>, Error>>;
+    type ResponseFuture = Ready<Result<(), Error>>;
+
+    fn from_request(&self, req: &mut ServiceRequest) -> Self::Future {
+        ok(self.0.load(req).map(
+            |CookieValue {
+                 identity,
+                 login_timestamp,
+                 ..
+             }| {
+                if self.0.requires_oob_data() {
+                    req.extensions_mut()
+                        .insert(CookieIdentityExtension { login_timestamp });
+                }
+                identity
+            },
+        ))
+    }
+
+    fn to_response<B>(
+        &self,
+        id: Option<String>,
+        changed: bool,
+        res: &mut ServiceResponse<B>,
+    ) -> Self::ResponseFuture {
+        let _ = if changed {
+            let login_timestamp = SystemTime::now();
+            self.0.set_cookie(
+                res,
+                id.map(|identity| CookieValue {
+                    identity,
+                    login_timestamp: self.0.login_deadline.map(|_| login_timestamp),
+                    visit_timestamp: self.0.visit_deadline.map(|_| login_timestamp),
+                }),
+            )
+        } else if self.0.always_update_cookie() && id.is_some() {
+            let visit_timestamp = SystemTime::now();
+            let login_timestamp = if self.0.requires_oob_data() {
+                let CookieIdentityExtension {
+                    login_timestamp: lt,
+                } = res.request().extensions_mut().remove().unwrap();
+                lt
+            } else {
+                None
+            };
+            self.0.set_cookie(
+                res,
+                Some(CookieValue {
+                    identity: id.unwrap(),
+                    login_timestamp,
+                    visit_timestamp: self.0.visit_deadline.map(|_| visit_timestamp),
+                }),
+            )
+        } else {
+            Ok(())
+        };
+        ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::borrow::Borrow;
+
+    use super::*;
+    use actix_service::into_service;
+    use actix_web::http::StatusCode;
+    use actix_web::test::{self, TestRequest};
+    use actix_web::{error, web, App, Error, HttpResponse};
+
+    const COOKIE_KEY_MASTER: [u8; 32] = [0; 32];
+    const COOKIE_NAME: &str = "actix_auth";
+    const COOKIE_LOGIN: &str = "test";
+
+    #[actix_rt::test]
+    async fn test_identity() {
+        let srv = test::init_service(
+            App::new()
+                .wrap(IdentityService::new(
+                    CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
+                        .domain("www.rust-lang.org")
+                        .name(COOKIE_NAME)
+                        .path("/")
+                        .secure(true),
+                ))
+                .service(web::resource("/index").to(|id: Identity| {
+                    if id.identity().is_some() {
+                        HttpResponse::Created()
+                    } else {
+                        HttpResponse::Ok()
+                    }
+                }))
+                .service(web::resource("/login").to(|id: Identity| {
+                    id.remember(COOKIE_LOGIN.to_string());
+                    HttpResponse::Ok()
+                }))
+                .service(web::resource("/logout").to(|id: Identity| {
+                    if id.identity().is_some() {
+                        id.forget();
+                        HttpResponse::Ok()
+                    } else {
+                        HttpResponse::BadRequest()
+                    }
+                })),
+        )
+        .await;
+        let resp =
+            test::call_service(&srv, TestRequest::with_uri("/index").to_request()).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let resp =
+            test::call_service(&srv, TestRequest::with_uri("/login").to_request()).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        let c = resp.response().cookies().next().unwrap().to_owned();
+
+        let resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/index")
+                .cookie(c.clone())
+                .to_request(),
+        )
+        .await;
+        assert_eq!(resp.status(), StatusCode::CREATED);
+
+        let resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/logout")
+                .cookie(c.clone())
+                .to_request(),
+        )
+        .await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert!(resp.headers().contains_key(header::SET_COOKIE))
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_max_age_time() {
+        let duration = Duration::days(1);
+        let srv = test::init_service(
+            App::new()
+                .wrap(IdentityService::new(
+                    CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
+                        .domain("www.rust-lang.org")
+                        .name(COOKIE_NAME)
+                        .path("/")
+                        .max_age_time(duration)
+                        .secure(true),
+                ))
+                .service(web::resource("/login").to(|id: Identity| {
+                    id.remember("test".to_string());
+                    HttpResponse::Ok()
+                })),
+        )
+        .await;
+        let resp =
+            test::call_service(&srv, TestRequest::with_uri("/login").to_request()).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert!(resp.headers().contains_key(header::SET_COOKIE));
+        let c = resp.response().cookies().next().unwrap().to_owned();
+        assert_eq!(duration, c.max_age().unwrap());
+    }
+
+    #[actix_rt::test]
+    async fn test_http_only_same_site() {
+        let srv = test::init_service(
+            App::new()
+                .wrap(IdentityService::new(
+                    CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
+                        .domain("www.rust-lang.org")
+                        .name(COOKIE_NAME)
+                        .path("/")
+                        .http_only(true)
+                        .same_site(SameSite::None),
+                ))
+                .service(web::resource("/login").to(|id: Identity| {
+                    id.remember("test".to_string());
+                    HttpResponse::Ok()
+                })),
+        )
+        .await;
+
+        let resp =
+            test::call_service(&srv, TestRequest::with_uri("/login").to_request()).await;
+
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert!(resp.headers().contains_key(header::SET_COOKIE));
+
+        let c = resp.response().cookies().next().unwrap().to_owned();
+        assert!(c.http_only().unwrap());
+        assert_eq!(SameSite::None, c.same_site().unwrap());
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_max_age() {
+        let seconds = 60;
+        let srv = test::init_service(
+            App::new()
+                .wrap(IdentityService::new(
+                    CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
+                        .domain("www.rust-lang.org")
+                        .name(COOKIE_NAME)
+                        .path("/")
+                        .max_age(seconds)
+                        .secure(true),
+                ))
+                .service(web::resource("/login").to(|id: Identity| {
+                    id.remember("test".to_string());
+                    HttpResponse::Ok()
+                })),
+        )
+        .await;
+        let resp =
+            test::call_service(&srv, TestRequest::with_uri("/login").to_request()).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert!(resp.headers().contains_key(header::SET_COOKIE));
+        let c = resp.response().cookies().next().unwrap().to_owned();
+        assert_eq!(Duration::seconds(seconds as i64), c.max_age().unwrap());
+    }
+
+    async fn create_identity_server<
+        F: Fn(CookieIdentityPolicy) -> CookieIdentityPolicy + Sync + Send + Clone + 'static,
+    >(
+        f: F,
+    ) -> impl actix_service::Service<
+        actix_http::Request,
+        Response = ServiceResponse<actix_web::body::Body>,
+        Error = Error,
+    > {
+        test::init_service(
+            App::new()
+                .wrap(IdentityService::new(f(CookieIdentityPolicy::new(
+                    &COOKIE_KEY_MASTER,
+                )
+                .secure(false)
+                .name(COOKIE_NAME))))
+                .service(web::resource("/").to(|id: Identity| async move {
+                    let identity = id.identity();
+                    if identity.is_none() {
+                        id.remember(COOKIE_LOGIN.to_string())
+                    }
+                    web::Json(identity)
+                })),
+        )
+        .await
+    }
+
+    fn legacy_login_cookie(identity: &'static str) -> Cookie<'static> {
+        let mut jar = CookieJar::new();
+        jar.private(&Key::derive_from(&COOKIE_KEY_MASTER))
+            .add(Cookie::new(COOKIE_NAME, identity));
+        jar.get(COOKIE_NAME).unwrap().clone()
+    }
+
+    fn login_cookie(
+        identity: &'static str,
+        login_timestamp: Option<SystemTime>,
+        visit_timestamp: Option<SystemTime>,
+    ) -> Cookie<'static> {
+        let mut jar = CookieJar::new();
+        let key: Vec<u8> = COOKIE_KEY_MASTER
+            .iter()
+            .chain([1, 0, 0, 0].iter())
+            .copied()
+            .collect();
+        jar.private(&Key::derive_from(&key)).add(Cookie::new(
+            COOKIE_NAME,
+            serde_json::to_string(&CookieValue {
+                identity: identity.to_string(),
+                login_timestamp,
+                visit_timestamp,
+            })
+            .unwrap(),
+        ));
+        jar.get(COOKIE_NAME).unwrap().clone()
+    }
+
+    async fn assert_logged_in(response: ServiceResponse, identity: Option<&str>) {
+        let bytes = test::read_body(response).await;
+        let resp: Option<String> = serde_json::from_slice(&bytes[..]).unwrap();
+        assert_eq!(resp.as_ref().map(|s| s.borrow()), identity);
+    }
+
+    fn assert_legacy_login_cookie(response: &mut ServiceResponse, identity: &str) {
+        let mut cookies = CookieJar::new();
+        for cookie in response.headers().get_all(header::SET_COOKIE) {
+            cookies.add(Cookie::parse(cookie.to_str().unwrap().to_string()).unwrap());
+        }
+        let cookie = cookies
+            .private(&Key::derive_from(&COOKIE_KEY_MASTER))
+            .get(COOKIE_NAME)
+            .unwrap();
+        assert_eq!(cookie.value(), identity);
+    }
+
+    #[allow(clippy::enum_variant_names)]
+    enum LoginTimestampCheck {
+        NoTimestamp,
+        NewTimestamp,
+        OldTimestamp(SystemTime),
+    }
+
+    #[allow(clippy::enum_variant_names)]
+    enum VisitTimeStampCheck {
+        NoTimestamp,
+        NewTimestamp,
+    }
+
+    fn assert_login_cookie(
+        response: &mut ServiceResponse,
+        identity: &str,
+        login_timestamp: LoginTimestampCheck,
+        visit_timestamp: VisitTimeStampCheck,
+    ) {
+        let mut cookies = CookieJar::new();
+        for cookie in response.headers().get_all(header::SET_COOKIE) {
+            cookies.add(Cookie::parse(cookie.to_str().unwrap().to_string()).unwrap());
+        }
+        let key: Vec<u8> = COOKIE_KEY_MASTER
+            .iter()
+            .chain([1, 0, 0, 0].iter())
+            .copied()
+            .collect();
+        let cookie = cookies
+            .private(&Key::derive_from(&key))
+            .get(COOKIE_NAME)
+            .unwrap();
+        let cv: CookieValue = serde_json::from_str(cookie.value()).unwrap();
+        assert_eq!(cv.identity, identity);
+        let now = SystemTime::now();
+        let t30sec_ago = now - Duration::seconds(30);
+        match login_timestamp {
+            LoginTimestampCheck::NoTimestamp => assert_eq!(cv.login_timestamp, None),
+            LoginTimestampCheck::NewTimestamp => assert!(
+                t30sec_ago <= cv.login_timestamp.unwrap()
+                    && cv.login_timestamp.unwrap() <= now
+            ),
+            LoginTimestampCheck::OldTimestamp(old_timestamp) => {
+                assert_eq!(cv.login_timestamp, Some(old_timestamp))
+            }
+        }
+        match visit_timestamp {
+            VisitTimeStampCheck::NoTimestamp => assert_eq!(cv.visit_timestamp, None),
+            VisitTimeStampCheck::NewTimestamp => assert!(
+                t30sec_ago <= cv.visit_timestamp.unwrap()
+                    && cv.visit_timestamp.unwrap() <= now
+            ),
+        }
+    }
+
+    fn assert_no_login_cookie(response: &mut ServiceResponse) {
+        let mut cookies = CookieJar::new();
+        for cookie in response.headers().get_all(header::SET_COOKIE) {
+            cookies.add(Cookie::parse(cookie.to_str().unwrap().to_string()).unwrap());
+        }
+        assert!(cookies.get(COOKIE_NAME).is_none());
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_legacy_cookie_is_set() {
+        let srv = create_identity_server(|c| c).await;
+        let mut resp =
+            test::call_service(&srv, TestRequest::with_uri("/").to_request()).await;
+        assert_legacy_login_cookie(&mut resp, COOKIE_LOGIN);
+        assert_logged_in(resp, None).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_legacy_cookie_works() {
+        let srv = create_identity_server(|c| c).await;
+        let cookie = legacy_login_cookie(COOKIE_LOGIN);
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_no_login_cookie(&mut resp);
+        assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_legacy_cookie_rejected_if_visit_timestamp_needed() {
+        let srv = create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
+        let cookie = legacy_login_cookie(COOKIE_LOGIN);
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_login_cookie(
+            &mut resp,
+            COOKIE_LOGIN,
+            LoginTimestampCheck::NoTimestamp,
+            VisitTimeStampCheck::NewTimestamp,
+        );
+        assert_logged_in(resp, None).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_legacy_cookie_rejected_if_login_timestamp_needed() {
+        let srv = create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
+        let cookie = legacy_login_cookie(COOKIE_LOGIN);
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_login_cookie(
+            &mut resp,
+            COOKIE_LOGIN,
+            LoginTimestampCheck::NewTimestamp,
+            VisitTimeStampCheck::NoTimestamp,
+        );
+        assert_logged_in(resp, None).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_cookie_rejected_if_login_timestamp_needed() {
+        let srv = create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
+        let cookie = login_cookie(COOKIE_LOGIN, None, Some(SystemTime::now()));
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_login_cookie(
+            &mut resp,
+            COOKIE_LOGIN,
+            LoginTimestampCheck::NewTimestamp,
+            VisitTimeStampCheck::NoTimestamp,
+        );
+        assert_logged_in(resp, None).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_cookie_rejected_if_visit_timestamp_needed() {
+        let srv = create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
+        let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_login_cookie(
+            &mut resp,
+            COOKIE_LOGIN,
+            LoginTimestampCheck::NoTimestamp,
+            VisitTimeStampCheck::NewTimestamp,
+        );
+        assert_logged_in(resp, None).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_cookie_rejected_if_login_timestamp_too_old() {
+        let srv = create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
+        let cookie = login_cookie(
+            COOKIE_LOGIN,
+            Some(SystemTime::now() - Duration::days(180)),
+            None,
+        );
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_login_cookie(
+            &mut resp,
+            COOKIE_LOGIN,
+            LoginTimestampCheck::NewTimestamp,
+            VisitTimeStampCheck::NoTimestamp,
+        );
+        assert_logged_in(resp, None).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_cookie_rejected_if_visit_timestamp_too_old() {
+        let srv = create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
+        let cookie = login_cookie(
+            COOKIE_LOGIN,
+            None,
+            Some(SystemTime::now() - Duration::days(180)),
+        );
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_login_cookie(
+            &mut resp,
+            COOKIE_LOGIN,
+            LoginTimestampCheck::NoTimestamp,
+            VisitTimeStampCheck::NewTimestamp,
+        );
+        assert_logged_in(resp, None).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_identity_cookie_not_updated_on_login_deadline() {
+        let srv = create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
+        let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_no_login_cookie(&mut resp);
+        assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
+    }
+
+    // https://github.com/actix/actix-web/issues/1263
+    #[actix_rt::test]
+    async fn test_identity_cookie_updated_on_visit_deadline() {
+        let srv = create_identity_server(|c| {
+            c.visit_deadline(Duration::days(90))
+                .login_deadline(Duration::days(90))
+        })
+        .await;
+        let timestamp = SystemTime::now() - Duration::days(1);
+        let cookie = login_cookie(COOKIE_LOGIN, Some(timestamp), Some(timestamp));
+        let mut resp = test::call_service(
+            &srv,
+            TestRequest::with_uri("/")
+                .cookie(cookie.clone())
+                .to_request(),
+        )
+        .await;
+        assert_login_cookie(
+            &mut resp,
+            COOKIE_LOGIN,
+            LoginTimestampCheck::OldTimestamp(timestamp),
+            VisitTimeStampCheck::NewTimestamp,
+        );
+        assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_borrowed_mut_error() {
+        use futures_util::future::{lazy, ok, Ready};
+
+        struct Ident;
+        impl IdentityPolicy for Ident {
+            type Future = Ready<Result<Option<String>, Error>>;
+            type ResponseFuture = Ready<Result<(), Error>>;
+
+            fn from_request(&self, _: &mut ServiceRequest) -> Self::Future {
+                ok(Some("test".to_string()))
+            }
+
+            fn to_response<B>(
+                &self,
+                _: Option<String>,
+                _: bool,
+                _: &mut ServiceResponse<B>,
+            ) -> Self::ResponseFuture {
+                ok(())
+            }
+        }
+
+        let srv = IdentityServiceMiddleware {
+            backend: Rc::new(Ident),
+            service: Rc::new(into_service(|_: ServiceRequest| async move {
+                actix_rt::time::sleep(std::time::Duration::from_secs(100)).await;
+                Err::<ServiceResponse, _>(error::ErrorBadRequest("error"))
+            })),
+        };
+
+        let srv2 = srv.clone();
+        let req = TestRequest::default().to_srv_request();
+        actix_rt::spawn(async move {
+            let _ = srv2.call(req).await;
+        });
+        actix_rt::time::sleep(std::time::Duration::from_millis(50)).await;
+
+        let _ = lazy(|cx| srv.poll_ready(cx)).await;
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_protobuf/lib.rs.html b/src/actix_protobuf/lib.rs.html new file mode 100644 index 000000000..0b7181547 --- /dev/null +++ b/src/actix_protobuf/lib.rs.html @@ -0,0 +1,655 @@ +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
+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
+
+#![deny(rust_2018_idioms)]
+
+use derive_more::Display;
+use std::fmt;
+use std::future::Future;
+use std::ops::{Deref, DerefMut};
+use std::pin::Pin;
+use std::task;
+use std::task::Poll;
+
+use prost::DecodeError as ProtoBufDecodeError;
+use prost::EncodeError as ProtoBufEncodeError;
+use prost::Message;
+
+use actix_web::dev::{HttpResponseBuilder, Payload};
+use actix_web::error::{Error, PayloadError, ResponseError};
+use actix_web::http::header::{CONTENT_LENGTH, CONTENT_TYPE};
+use actix_web::web::BytesMut;
+use actix_web::{FromRequest, HttpMessage, HttpRequest, HttpResponse, Responder};
+use futures_util::future::{FutureExt, LocalBoxFuture};
+use futures_util::StreamExt;
+
+#[derive(Debug, Display)]
+pub enum ProtoBufPayloadError {
+    /// Payload size is bigger than 256k
+    #[display(fmt = "Payload size is bigger than 256k")]
+    Overflow,
+    /// Content type error
+    #[display(fmt = "Content type error")]
+    ContentType,
+    /// Serialize error
+    #[display(fmt = "ProtoBuf serialize error: {}", _0)]
+    Serialize(ProtoBufEncodeError),
+    /// Deserialize error
+    #[display(fmt = "ProtoBuf deserialize error: {}", _0)]
+    Deserialize(ProtoBufDecodeError),
+    /// Payload error
+    #[display(fmt = "Error that occur during reading payload: {}", _0)]
+    Payload(PayloadError),
+}
+
+impl ResponseError for ProtoBufPayloadError {
+    fn error_response(&self) -> HttpResponse {
+        match *self {
+            ProtoBufPayloadError::Overflow => HttpResponse::PayloadTooLarge().into(),
+            _ => HttpResponse::BadRequest().into(),
+        }
+    }
+}
+
+impl From<PayloadError> for ProtoBufPayloadError {
+    fn from(err: PayloadError) -> ProtoBufPayloadError {
+        ProtoBufPayloadError::Payload(err)
+    }
+}
+
+impl From<ProtoBufDecodeError> for ProtoBufPayloadError {
+    fn from(err: ProtoBufDecodeError) -> ProtoBufPayloadError {
+        ProtoBufPayloadError::Deserialize(err)
+    }
+}
+
+pub struct ProtoBuf<T: Message>(pub T);
+
+impl<T: Message> Deref for ProtoBuf<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T: Message> DerefMut for ProtoBuf<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.0
+    }
+}
+
+impl<T: Message> fmt::Debug for ProtoBuf<T>
+where
+    T: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "ProtoBuf: {:?}", self.0)
+    }
+}
+
+impl<T: Message> fmt::Display for ProtoBuf<T>
+where
+    T: fmt::Display,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.0, f)
+    }
+}
+
+pub struct ProtoBufConfig {
+    limit: usize,
+}
+
+impl ProtoBufConfig {
+    /// Change max size of payload. By default max size is 256Kb
+    pub fn limit(&mut self, limit: usize) -> &mut Self {
+        self.limit = limit;
+        self
+    }
+}
+
+impl Default for ProtoBufConfig {
+    fn default() -> Self {
+        ProtoBufConfig { limit: 262_144 }
+    }
+}
+
+impl<T> FromRequest for ProtoBuf<T>
+where
+    T: Message + Default + 'static,
+{
+    type Config = ProtoBufConfig;
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self, Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
+        let limit = req
+            .app_data::<ProtoBufConfig>()
+            .map(|c| c.limit)
+            .unwrap_or(262_144);
+        ProtoBufMessage::new(req, payload)
+            .limit(limit)
+            .map(move |res| match res {
+                Err(e) => Err(e.into()),
+                Ok(item) => Ok(ProtoBuf(item)),
+            })
+            .boxed_local()
+    }
+}
+
+impl<T: Message + Default> Responder for ProtoBuf<T> {
+    fn respond_to(self, _: &HttpRequest) -> HttpResponse {
+        let mut buf = Vec::new();
+        match self.0.encode(&mut buf) {
+            Ok(()) => HttpResponse::Ok()
+                .content_type("application/protobuf")
+                .body(buf),
+            Err(err) => HttpResponse::from_error(Error::from(
+                ProtoBufPayloadError::Serialize(err),
+            )),
+        }
+    }
+}
+
+pub struct ProtoBufMessage<T: Message + Default> {
+    limit: usize,
+    length: Option<usize>,
+    stream: Option<Payload>,
+    err: Option<ProtoBufPayloadError>,
+    fut: Option<LocalBoxFuture<'static, Result<T, ProtoBufPayloadError>>>,
+}
+
+impl<T: Message + Default> ProtoBufMessage<T> {
+    /// Create `ProtoBufMessage` for request.
+    pub fn new(req: &HttpRequest, payload: &mut Payload) -> Self {
+        if req.content_type() != "application/protobuf" {
+            return ProtoBufMessage {
+                limit: 262_144,
+                length: None,
+                stream: None,
+                fut: None,
+                err: Some(ProtoBufPayloadError::ContentType),
+            };
+        }
+
+        let mut len = None;
+        if let Some(l) = req.headers().get(CONTENT_LENGTH) {
+            if let Ok(s) = l.to_str() {
+                if let Ok(l) = s.parse::<usize>() {
+                    len = Some(l)
+                }
+            }
+        }
+
+        ProtoBufMessage {
+            limit: 262_144,
+            length: len,
+            stream: Some(payload.take()),
+            fut: None,
+            err: None,
+        }
+    }
+
+    /// Change max size of payload. By default max size is 256Kb
+    pub fn limit(mut self, limit: usize) -> Self {
+        self.limit = limit;
+        self
+    }
+}
+
+impl<T: Message + Default + 'static> Future for ProtoBufMessage<T> {
+    type Output = Result<T, ProtoBufPayloadError>;
+
+    fn poll(
+        mut self: Pin<&mut Self>,
+        task: &mut task::Context<'_>,
+    ) -> Poll<Self::Output> {
+        if let Some(ref mut fut) = self.fut {
+            return Pin::new(fut).poll(task);
+        }
+
+        if let Some(err) = self.err.take() {
+            return Poll::Ready(Err(err));
+        }
+
+        let limit = self.limit;
+        if let Some(len) = self.length.take() {
+            if len > limit {
+                return Poll::Ready(Err(ProtoBufPayloadError::Overflow));
+            }
+        }
+
+        let mut stream = self
+            .stream
+            .take()
+            .expect("ProtoBufMessage could not be used second time");
+
+        self.fut = Some(
+            async move {
+                let mut body = BytesMut::with_capacity(8192);
+
+                while let Some(item) = stream.next().await {
+                    let chunk = item?;
+                    if (body.len() + chunk.len()) > limit {
+                        return Err(ProtoBufPayloadError::Overflow);
+                    } else {
+                        body.extend_from_slice(&chunk);
+                    }
+                }
+
+                Ok(<T>::decode(&mut body)?)
+            }
+            .boxed_local(),
+        );
+        self.poll(task)
+    }
+}
+
+pub trait ProtoBufResponseBuilder {
+    fn protobuf<T: Message>(&mut self, value: T) -> Result<HttpResponse, Error>;
+}
+
+impl ProtoBufResponseBuilder for HttpResponseBuilder {
+    fn protobuf<T: Message>(&mut self, value: T) -> Result<HttpResponse, Error> {
+        self.insert_header((CONTENT_TYPE, "application/protobuf"));
+
+        let mut body = Vec::new();
+        value
+            .encode(&mut body)
+            .map_err(ProtoBufPayloadError::Serialize)?;
+        Ok(self.body(body))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use actix_web::http::header;
+    use actix_web::test::TestRequest;
+
+    impl PartialEq for ProtoBufPayloadError {
+        fn eq(&self, other: &ProtoBufPayloadError) -> bool {
+            match *self {
+                ProtoBufPayloadError::Overflow => {
+                    matches!(*other, ProtoBufPayloadError::Overflow)
+                }
+                ProtoBufPayloadError::ContentType => {
+                    matches!(*other, ProtoBufPayloadError::ContentType)
+                }
+                _ => false,
+            }
+        }
+    }
+
+    #[derive(Clone, PartialEq, Message)]
+    pub struct MyObject {
+        #[prost(int32, tag = "1")]
+        pub number: i32,
+        #[prost(string, tag = "2")]
+        pub name: String,
+    }
+
+    #[actix_rt::test]
+    async fn test_protobuf() {
+        let protobuf = ProtoBuf(MyObject {
+            number: 9,
+            name: "test".to_owned(),
+        });
+        let req = TestRequest::default().to_http_request();
+        let resp = protobuf.respond_to(&req).await.unwrap();
+        let ct = resp.headers().get(header::CONTENT_TYPE).unwrap();
+        assert_eq!(ct, "application/protobuf");
+    }
+
+    #[actix_rt::test]
+    async fn test_protobuf_message() {
+        let (req, mut pl) = TestRequest::default().to_http_parts();
+        let protobuf = ProtoBufMessage::<MyObject>::new(&req, &mut pl).await;
+        assert_eq!(protobuf.err().unwrap(), ProtoBufPayloadError::ContentType);
+
+        let (req, mut pl) = TestRequest::get()
+            .insert_header((header::CONTENT_TYPE, "application/text"))
+            .to_http_parts();
+        let protobuf = ProtoBufMessage::<MyObject>::new(&req, &mut pl).await;
+        assert_eq!(protobuf.err().unwrap(), ProtoBufPayloadError::ContentType);
+
+        let (req, mut pl) = TestRequest::get()
+            .insert_header((header::CONTENT_TYPE, "application/protobuf"))
+            .insert_header((header::CONTENT_LENGTH, "10000"))
+            .to_http_parts();
+        let protobuf = ProtoBufMessage::<MyObject>::new(&req, &mut pl)
+            .limit(100)
+            .await;
+        assert_eq!(protobuf.err().unwrap(), ProtoBufPayloadError::Overflow);
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_redis/lib.rs.html b/src/actix_redis/lib.rs.html index 5d22db3a6..e34d5b6fb 100644 --- a/src/actix_redis/lib.rs.html +++ b/src/actix_redis/lib.rs.html @@ -1,7 +1,7 @@ -lib.rs - source +lib.rs - source -
 1
+
 1
  2
  3
  4
@@ -73,4 +73,5 @@
 pub use redis_async::error::Error as RespError;
 pub use redis_async::resp::RespValue;
 
-
\ No newline at end of file +
+ \ No newline at end of file diff --git a/src/actix_redis/redis.rs.html b/src/actix_redis/redis.rs.html index 5dccfc256..ee4c892a4 100644 --- a/src/actix_redis/redis.rs.html +++ b/src/actix_redis/redis.rs.html @@ -1,7 +1,7 @@ -redis.rs - source +redis.rs - source -
  1
+
  1
   2
   3
   4
@@ -285,4 +285,5 @@
     }
 }
 
-
\ No newline at end of file +
+ \ No newline at end of file diff --git a/src/actix_redis/session.rs.html b/src/actix_redis/session.rs.html index 6ebcfd1a2..5a2baab47 100644 --- a/src/actix_redis/session.rs.html +++ b/src/actix_redis/session.rs.html @@ -1,7 +1,7 @@ -session.rs - source +session.rs - source -
  1
+
  1
   2
   3
   4
@@ -1415,4 +1415,5 @@
     }
 }
 
-
\ No newline at end of file +
+ \ No newline at end of file diff --git a/src/actix_session/cookie.rs.html b/src/actix_session/cookie.rs.html new file mode 100644 index 000000000..ad71e5076 --- /dev/null +++ b/src/actix_session/cookie.rs.html @@ -0,0 +1,1107 @@ +cookie.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
+
+//! Cookie based sessions. See docs for [`CookieSession`].
+
+use std::{collections::HashMap, rc::Rc};
+
+use actix_service::{Service, Transform};
+use actix_web::cookie::{Cookie, CookieJar, Key, SameSite};
+use actix_web::dev::{ServiceRequest, ServiceResponse};
+use actix_web::http::{header::SET_COOKIE, HeaderValue};
+use actix_web::{Error, HttpMessage, ResponseError};
+use derive_more::Display;
+use futures_util::future::{ok, FutureExt, LocalBoxFuture, Ready};
+use serde_json::error::Error as JsonError;
+use time::{Duration, OffsetDateTime};
+
+use crate::{Session, SessionStatus};
+
+/// Errors that can occur during handling cookie session
+#[derive(Debug, Display)]
+pub enum CookieSessionError {
+    /// Size of the serialized session is greater than 4000 bytes.
+    #[display(fmt = "Size of the serialized session is greater than 4000 bytes.")]
+    Overflow,
+
+    /// Fail to serialize session.
+    #[display(fmt = "Fail to serialize session")]
+    Serialize(JsonError),
+}
+
+impl ResponseError for CookieSessionError {}
+
+enum CookieSecurity {
+    Signed,
+    Private,
+}
+
+struct CookieSessionInner {
+    key: Key,
+    security: CookieSecurity,
+    name: String,
+    path: String,
+    domain: Option<String>,
+    lazy: bool,
+    secure: bool,
+    http_only: bool,
+    max_age: Option<Duration>,
+    expires_in: Option<Duration>,
+    same_site: Option<SameSite>,
+}
+
+impl CookieSessionInner {
+    fn new(key: &[u8], security: CookieSecurity) -> CookieSessionInner {
+        CookieSessionInner {
+            security,
+            key: Key::derive_from(key),
+            name: "actix-session".to_owned(),
+            path: "/".to_owned(),
+            domain: None,
+            lazy: false,
+            secure: true,
+            http_only: true,
+            max_age: None,
+            expires_in: None,
+            same_site: None,
+        }
+    }
+
+    fn set_cookie<B>(
+        &self,
+        res: &mut ServiceResponse<B>,
+        state: impl Iterator<Item = (String, String)>,
+    ) -> Result<(), Error> {
+        let state: HashMap<String, String> = state.collect();
+
+        if self.lazy && state.is_empty() {
+            return Ok(());
+        }
+
+        let value =
+            serde_json::to_string(&state).map_err(CookieSessionError::Serialize)?;
+        if value.len() > 4064 {
+            return Err(CookieSessionError::Overflow.into());
+        }
+
+        let mut cookie = Cookie::new(self.name.clone(), value);
+        cookie.set_path(self.path.clone());
+        cookie.set_secure(self.secure);
+        cookie.set_http_only(self.http_only);
+
+        if let Some(ref domain) = self.domain {
+            cookie.set_domain(domain.clone());
+        }
+
+        if let Some(expires_in) = self.expires_in {
+            cookie.set_expires(OffsetDateTime::now_utc() + expires_in);
+        }
+
+        if let Some(max_age) = self.max_age {
+            cookie.set_max_age(max_age);
+        }
+
+        if let Some(same_site) = self.same_site {
+            cookie.set_same_site(same_site);
+        }
+
+        let mut jar = CookieJar::new();
+
+        match self.security {
+            CookieSecurity::Signed => jar.signed(&self.key).add(cookie),
+            CookieSecurity::Private => jar.private(&self.key).add(cookie),
+        }
+
+        for cookie in jar.delta() {
+            let val = HeaderValue::from_str(&cookie.encoded().to_string())?;
+            res.headers_mut().append(SET_COOKIE, val);
+        }
+
+        Ok(())
+    }
+
+    /// invalidates session cookie
+    fn remove_cookie<B>(&self, res: &mut ServiceResponse<B>) -> Result<(), Error> {
+        let mut cookie = Cookie::named(self.name.clone());
+        cookie.set_path(self.path.clone());
+        cookie.set_value("");
+        cookie.set_max_age(Duration::zero());
+        cookie.set_expires(OffsetDateTime::now_utc() - Duration::days(365));
+
+        let val = HeaderValue::from_str(&cookie.to_string())?;
+        res.headers_mut().append(SET_COOKIE, val);
+
+        Ok(())
+    }
+
+    fn load(&self, req: &ServiceRequest) -> (bool, HashMap<String, String>) {
+        if let Ok(cookies) = req.cookies() {
+            for cookie in cookies.iter() {
+                if cookie.name() == self.name {
+                    let mut jar = CookieJar::new();
+                    jar.add_original(cookie.clone());
+
+                    let cookie_opt = match self.security {
+                        CookieSecurity::Signed => jar.signed(&self.key).get(&self.name),
+                        CookieSecurity::Private => {
+                            jar.private(&self.key).get(&self.name)
+                        }
+                    };
+                    if let Some(cookie) = cookie_opt {
+                        if let Ok(val) = serde_json::from_str(cookie.value()) {
+                            return (false, val);
+                        }
+                    }
+                }
+            }
+        }
+        (true, HashMap::new())
+    }
+}
+
+/// Use cookies for session storage.
+///
+/// `CookieSession` creates sessions which are limited to storing
+/// fewer than 4000 bytes of data (as the payload must fit into a single
+/// cookie). An Internal Server Error is generated if the session contains more
+/// than 4000 bytes.
+///
+/// A cookie may have a security policy of *signed* or *private*. Each has a
+/// respective `CookieSession` constructor.
+///
+/// A *signed* cookie is stored on the client as plaintext alongside
+/// a signature such that the cookie may be viewed but not modified by the
+/// client.
+///
+/// A *private* cookie is stored on the client as encrypted text
+/// such that it may neither be viewed nor modified by the client.
+///
+/// The constructors take a key as an argument.
+/// This is the private key for cookie session - when this value is changed,
+/// all session data is lost. The constructors will panic if the key is less
+/// than 32 bytes in length.
+///
+/// The backend relies on `cookie` crate to create and read cookies.
+/// By default all cookies are percent encoded, but certain symbols may
+/// cause troubles when reading cookie, if they are not properly percent encoded.
+///
+/// # Examples
+/// ```
+/// use actix_session::CookieSession;
+/// use actix_web::{web, App, HttpResponse, HttpServer};
+///
+/// let app = App::new().wrap(
+///     CookieSession::signed(&[0; 32])
+///         .domain("www.rust-lang.org")
+///         .name("actix_session")
+///         .path("/")
+///         .secure(true))
+///     .service(web::resource("/").to(|| HttpResponse::Ok()));
+/// ```
+pub struct CookieSession(Rc<CookieSessionInner>);
+
+impl CookieSession {
+    /// Construct new *signed* `CookieSession` instance.
+    ///
+    /// Panics if key length is less than 32 bytes.
+    pub fn signed(key: &[u8]) -> CookieSession {
+        CookieSession(Rc::new(CookieSessionInner::new(
+            key,
+            CookieSecurity::Signed,
+        )))
+    }
+
+    /// Construct new *private* `CookieSession` instance.
+    ///
+    /// Panics if key length is less than 32 bytes.
+    pub fn private(key: &[u8]) -> CookieSession {
+        CookieSession(Rc::new(CookieSessionInner::new(
+            key,
+            CookieSecurity::Private,
+        )))
+    }
+
+    /// Sets the `path` field in the session cookie being built.
+    pub fn path<S: Into<String>>(mut self, value: S) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().path = value.into();
+        self
+    }
+
+    /// Sets the `name` field in the session cookie being built.
+    pub fn name<S: Into<String>>(mut self, value: S) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().name = value.into();
+        self
+    }
+
+    /// Sets the `domain` field in the session cookie being built.
+    pub fn domain<S: Into<String>>(mut self, value: S) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().domain = Some(value.into());
+        self
+    }
+
+    /// When true, prevents adding session cookies to responses until
+    /// the session contains data. Default is `false`.
+    ///
+    /// Useful when trying to comply with laws that require consent for setting cookies.
+    pub fn lazy(mut self, value: bool) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().lazy = value;
+        self
+    }
+
+    /// Sets the `secure` field in the session cookie being built.
+    ///
+    /// If the `secure` field is set, a cookie will only be transmitted when the
+    /// connection is secure - i.e. `https`
+    pub fn secure(mut self, value: bool) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().secure = value;
+        self
+    }
+
+    /// Sets the `http_only` field in the session cookie being built.
+    pub fn http_only(mut self, value: bool) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().http_only = value;
+        self
+    }
+
+    /// Sets the `same_site` field in the session cookie being built.
+    pub fn same_site(mut self, value: SameSite) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().same_site = Some(value);
+        self
+    }
+
+    /// Sets the `max-age` field in the session cookie being built.
+    pub fn max_age(self, seconds: i64) -> CookieSession {
+        self.max_age_time(Duration::seconds(seconds))
+    }
+
+    /// Sets the `max-age` field in the session cookie being built.
+    pub fn max_age_time(mut self, value: time::Duration) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().max_age = Some(value);
+        self
+    }
+
+    /// Sets the `expires` field in the session cookie being built.
+    pub fn expires_in(self, seconds: i64) -> CookieSession {
+        self.expires_in_time(Duration::seconds(seconds))
+    }
+
+    /// Sets the `expires` field in the session cookie being built.
+    pub fn expires_in_time(mut self, value: Duration) -> CookieSession {
+        Rc::get_mut(&mut self.0).unwrap().expires_in = Some(value);
+        self
+    }
+}
+
+impl<S, B: 'static> Transform<S, ServiceRequest> for CookieSession
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>>,
+    S::Future: 'static,
+    S::Error: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = S::Error;
+    type InitError = ();
+    type Transform = CookieSessionMiddleware<S>;
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        ok(CookieSessionMiddleware {
+            service,
+            inner: self.0.clone(),
+        })
+    }
+}
+
+/// Cookie session middleware
+pub struct CookieSessionMiddleware<S> {
+    service: S,
+    inner: Rc<CookieSessionInner>,
+}
+
+impl<S, B: 'static> Service<ServiceRequest> for CookieSessionMiddleware<S>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>>,
+    S::Future: 'static,
+    S::Error: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = S::Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    actix_service::forward_ready!(service);
+
+    /// On first request, a new session cookie is returned in response, regardless
+    /// of whether any session state is set.  With subsequent requests, if the
+    /// session state changes, then set-cookie is returned in response.  As
+    /// a user logs out, call session.purge() to set SessionStatus accordingly
+    /// and this will trigger removal of the session cookie in the response.
+    fn call(&self, mut req: ServiceRequest) -> Self::Future {
+        let inner = self.inner.clone();
+        let (is_new, state) = self.inner.load(&req);
+        let prolong_expiration = self.inner.expires_in.is_some();
+        Session::set_session(state, &mut req);
+
+        let fut = self.service.call(req);
+
+        async move {
+            fut.await.map(|mut res| {
+                match Session::get_changes(&mut res) {
+                    (SessionStatus::Changed, Some(state))
+                    | (SessionStatus::Renewed, Some(state)) => {
+                        res.checked_expr(|res| inner.set_cookie(res, state))
+                    }
+                    (SessionStatus::Unchanged, Some(state)) if prolong_expiration => {
+                        res.checked_expr(|res| inner.set_cookie(res, state))
+                    }
+                    (SessionStatus::Unchanged, _) =>
+                    // set a new session cookie upon first request (new client)
+                    {
+                        if is_new {
+                            let state: HashMap<String, String> = HashMap::new();
+                            res.checked_expr(|res| {
+                                inner.set_cookie(res, state.into_iter())
+                            })
+                        } else {
+                            res
+                        }
+                    }
+                    (SessionStatus::Purged, _) => {
+                        let _ = inner.remove_cookie(&mut res);
+                        res
+                    }
+                    _ => res,
+                }
+            })
+        }
+        .boxed_local()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use actix_web::web::Bytes;
+    use actix_web::{test, web, App};
+
+    #[actix_rt::test]
+    async fn cookie_session() {
+        let app = test::init_service(
+            App::new()
+                .wrap(CookieSession::signed(&[0; 32]).secure(false))
+                .service(web::resource("/").to(|ses: Session| async move {
+                    let _ = ses.set("counter", 100);
+                    "test"
+                })),
+        )
+        .await;
+
+        let request = test::TestRequest::get().to_request();
+        let response = app.call(request).await.unwrap();
+        assert!(response
+            .response()
+            .cookies()
+            .any(|c| c.name() == "actix-session"));
+    }
+
+    #[actix_rt::test]
+    async fn private_cookie() {
+        let app = test::init_service(
+            App::new()
+                .wrap(CookieSession::private(&[0; 32]).secure(false))
+                .service(web::resource("/").to(|ses: Session| async move {
+                    let _ = ses.set("counter", 100);
+                    "test"
+                })),
+        )
+        .await;
+
+        let request = test::TestRequest::get().to_request();
+        let response = app.call(request).await.unwrap();
+        assert!(response
+            .response()
+            .cookies()
+            .any(|c| c.name() == "actix-session"));
+    }
+
+    #[actix_rt::test]
+    async fn lazy_cookie() {
+        let app = test::init_service(
+            App::new()
+                .wrap(CookieSession::signed(&[0; 32]).secure(false).lazy(true))
+                .service(web::resource("/count").to(|ses: Session| async move {
+                    let _ = ses.set("counter", 100);
+                    "counting"
+                }))
+                .service(web::resource("/").to(|_ses: Session| async move { "test" })),
+        )
+        .await;
+
+        let request = test::TestRequest::get().to_request();
+        let response = app.call(request).await.unwrap();
+        assert!(response.response().cookies().count() == 0);
+
+        let request = test::TestRequest::with_uri("/count").to_request();
+        let response = app.call(request).await.unwrap();
+
+        assert!(response
+            .response()
+            .cookies()
+            .any(|c| c.name() == "actix-session"));
+    }
+
+    #[actix_rt::test]
+    async fn cookie_session_extractor() {
+        let app = test::init_service(
+            App::new()
+                .wrap(CookieSession::signed(&[0; 32]).secure(false))
+                .service(web::resource("/").to(|ses: Session| async move {
+                    let _ = ses.set("counter", 100);
+                    "test"
+                })),
+        )
+        .await;
+
+        let request = test::TestRequest::get().to_request();
+        let response = app.call(request).await.unwrap();
+        assert!(response
+            .response()
+            .cookies()
+            .any(|c| c.name() == "actix-session"));
+    }
+
+    #[actix_rt::test]
+    async fn basics() {
+        let app = test::init_service(
+            App::new()
+                .wrap(
+                    CookieSession::signed(&[0; 32])
+                        .path("/test/")
+                        .name("actix-test")
+                        .domain("localhost")
+                        .http_only(true)
+                        .same_site(SameSite::Lax)
+                        .max_age(100),
+                )
+                .service(web::resource("/").to(|ses: Session| async move {
+                    let _ = ses.set("counter", 100);
+                    "test"
+                }))
+                .service(web::resource("/test/").to(|ses: Session| async move {
+                    let val: usize = ses.get("counter").unwrap().unwrap();
+                    format!("counter: {}", val)
+                })),
+        )
+        .await;
+
+        let request = test::TestRequest::get().to_request();
+        let response = app.call(request).await.unwrap();
+        let cookie = response
+            .response()
+            .cookies()
+            .find(|c| c.name() == "actix-test")
+            .unwrap()
+            .clone();
+        assert_eq!(cookie.path().unwrap(), "/test/");
+
+        let request = test::TestRequest::with_uri("/test/")
+            .cookie(cookie)
+            .to_request();
+        let body = test::read_response(&app, request).await;
+        assert_eq!(body, Bytes::from_static(b"counter: 100"));
+    }
+
+    #[actix_rt::test]
+    async fn prolong_expiration() {
+        let app = test::init_service(
+            App::new()
+                .wrap(CookieSession::signed(&[0; 32]).secure(false).expires_in(60))
+                .service(web::resource("/").to(|ses: Session| async move {
+                    let _ = ses.set("counter", 100);
+                    "test"
+                }))
+                .service(
+                    web::resource("/test/")
+                        .to(|| async move { "no-changes-in-session" }),
+                ),
+        )
+        .await;
+
+        let request = test::TestRequest::get().to_request();
+        let response = app.call(request).await.unwrap();
+        let expires_1 = response
+            .response()
+            .cookies()
+            .find(|c| c.name() == "actix-session")
+            .expect("Cookie is set")
+            .expires()
+            .expect("Expiration is set");
+
+        actix_rt::time::sleep(std::time::Duration::from_secs(1)).await;
+
+        let request = test::TestRequest::with_uri("/test/").to_request();
+        let response = app.call(request).await.unwrap();
+        let expires_2 = response
+            .response()
+            .cookies()
+            .find(|c| c.name() == "actix-session")
+            .expect("Cookie is set")
+            .expires()
+            .expect("Expiration is set");
+
+        assert!(expires_2 - expires_1 >= Duration::seconds(1));
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_session/lib.rs.html b/src/actix_session/lib.rs.html new file mode 100644 index 000000000..0ab345162 --- /dev/null +++ b/src/actix_session/lib.rs.html @@ -0,0 +1,671 @@ +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
+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
+
+//! Sessions for Actix Web.
+//!
+//! Provides a general solution for session management. Session middleware could provide different
+//! implementations which could be accessed via general session API.
+//!
+//! This crate provides a general solution for session management and includes a cookie backend.
+//! Other backend implementations can be built to use persistent or key-value stores, for example.
+//!
+//! In general, some session middleware, such as a [`CookieSession`] is initialized and applied.
+//! To access session data, the [`Session`] extractor must be used. This extractor allows reading
+//! modifying session data.
+//!
+//! ```no_run
+//! use actix_web::{web, App, HttpServer, HttpResponse, Error};
+//! use actix_session::{Session, CookieSession};
+//!
+//! fn index(session: Session) -> Result<&'static str, Error> {
+//!     // access session data
+//!     if let Some(count) = session.get::<i32>("counter")? {
+//!         println!("SESSION value: {}", count);
+//!         session.set("counter", count + 1)?;
+//!     } else {
+//!         session.set("counter", 1)?;
+//!     }
+//!
+//!     Ok("Welcome!")
+//! }
+//!
+//! #[actix_rt::main]
+//! async fn main() -> std::io::Result<()> {
+//!     HttpServer::new(
+//!         || App::new()
+//!             // create cookie based session middleware
+//!             .wrap(CookieSession::signed(&[0; 32]).secure(false))
+//!             .default_service(web::to(|| HttpResponse::Ok())))
+//!         .bind(("127.0.0.1", 8080))?
+//!         .run()
+//!         .await
+//! }
+//! ```
+
+#![deny(rust_2018_idioms)]
+
+use std::{cell::RefCell, collections::HashMap, rc::Rc};
+
+use actix_web::dev::{
+    Extensions, Payload, RequestHead, ServiceRequest, ServiceResponse,
+};
+use actix_web::{Error, FromRequest, HttpMessage, HttpRequest};
+use futures_util::future::{ok, Ready};
+use serde::{de::DeserializeOwned, Serialize};
+
+#[cfg(feature = "cookie-session")]
+mod cookie;
+#[cfg(feature = "cookie-session")]
+pub use crate::cookie::CookieSession;
+
+/// The high-level interface you use to modify session data.
+///
+/// Session object is obtained with [`UserSession::get_session`]. The [`UserSession`] trait is
+/// implemented for `HttpRequest`, `ServiceRequest`, and `RequestHead`.
+///
+/// ```
+/// use actix_session::Session;
+/// use actix_web::Result;
+///
+/// async fn index(session: Session) -> Result<&'static str> {
+///     // access session data
+///     if let Some(count) = session.get::<i32>("counter")? {
+///         session.set("counter", count + 1)?;
+///     } else {
+///         session.set("counter", 1)?;
+///     }
+///
+///     Ok("Welcome!")
+/// }
+/// ```
+pub struct Session(Rc<RefCell<SessionInner>>);
+
+/// Extraction of a [`Session`] object.
+pub trait UserSession {
+    fn get_session(&self) -> Session;
+}
+
+impl UserSession for HttpRequest {
+    fn get_session(&self) -> Session {
+        Session::get_session(&mut *self.extensions_mut())
+    }
+}
+
+impl UserSession for ServiceRequest {
+    fn get_session(&self) -> Session {
+        Session::get_session(&mut *self.extensions_mut())
+    }
+}
+
+impl UserSession for RequestHead {
+    fn get_session(&self) -> Session {
+        Session::get_session(&mut *self.extensions_mut())
+    }
+}
+
+#[derive(PartialEq, Clone, Debug)]
+pub enum SessionStatus {
+    Changed,
+    Purged,
+    Renewed,
+    Unchanged,
+}
+impl Default for SessionStatus {
+    fn default() -> SessionStatus {
+        SessionStatus::Unchanged
+    }
+}
+
+#[derive(Default)]
+struct SessionInner {
+    state: HashMap<String, String>,
+    pub status: SessionStatus,
+}
+
+impl Session {
+    /// Get a `value` from the session.
+    pub fn get<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>, Error> {
+        if let Some(s) = self.0.borrow().state.get(key) {
+            Ok(Some(serde_json::from_str(s)?))
+        } else {
+            Ok(None)
+        }
+    }
+
+    /// Set a `value` from the session.
+    pub fn set<T: Serialize>(&self, key: &str, value: T) -> Result<(), Error> {
+        let mut inner = self.0.borrow_mut();
+        if inner.status != SessionStatus::Purged {
+            inner.status = SessionStatus::Changed;
+            inner
+                .state
+                .insert(key.to_owned(), serde_json::to_string(&value)?);
+        }
+        Ok(())
+    }
+
+    /// Remove value from the session.
+    pub fn remove(&self, key: &str) {
+        let mut inner = self.0.borrow_mut();
+        if inner.status != SessionStatus::Purged {
+            inner.status = SessionStatus::Changed;
+            inner.state.remove(key);
+        }
+    }
+
+    /// Clear the session.
+    pub fn clear(&self) {
+        let mut inner = self.0.borrow_mut();
+        if inner.status != SessionStatus::Purged {
+            inner.status = SessionStatus::Changed;
+            inner.state.clear()
+        }
+    }
+
+    /// Removes session, both client and server side.
+    pub fn purge(&self) {
+        let mut inner = self.0.borrow_mut();
+        inner.status = SessionStatus::Purged;
+        inner.state.clear();
+    }
+
+    /// Renews the session key, assigning existing session state to new key.
+    pub fn renew(&self) {
+        let mut inner = self.0.borrow_mut();
+        if inner.status != SessionStatus::Purged {
+            inner.status = SessionStatus::Renewed;
+        }
+    }
+
+    /// Adds the given key-value pairs to the session on the request.
+    ///
+    /// Values that match keys already existing on the session will be overwritten. Values should
+    /// already be JSON serialized.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_session::Session;
+    /// # use actix_web::test;
+    /// let mut req = test::TestRequest::default().to_srv_request();
+    ///
+    /// Session::set_session(
+    ///     vec![("counter".to_string(), serde_json::to_string(&0).unwrap())],
+    ///     &mut req,
+    /// );
+    /// ```
+    pub fn set_session(
+        data: impl IntoIterator<Item = (String, String)>,
+        req: &mut ServiceRequest,
+    ) {
+        let session = Session::get_session(&mut *req.extensions_mut());
+        let mut inner = session.0.borrow_mut();
+        inner.state.extend(data);
+    }
+
+    pub fn get_changes<B>(
+        res: &mut ServiceResponse<B>,
+    ) -> (
+        SessionStatus,
+        Option<impl Iterator<Item = (String, String)>>,
+    ) {
+        if let Some(s_impl) = res
+            .request()
+            .extensions()
+            .get::<Rc<RefCell<SessionInner>>>()
+        {
+            let state =
+                std::mem::replace(&mut s_impl.borrow_mut().state, HashMap::new());
+            (s_impl.borrow().status.clone(), Some(state.into_iter()))
+        } else {
+            (SessionStatus::Unchanged, None)
+        }
+    }
+
+    fn get_session(extensions: &mut Extensions) -> Session {
+        if let Some(s_impl) = extensions.get::<Rc<RefCell<SessionInner>>>() {
+            return Session(Rc::clone(&s_impl));
+        }
+        let inner = Rc::new(RefCell::new(SessionInner::default()));
+        extensions.insert(inner.clone());
+        Session(inner)
+    }
+}
+
+/// Extractor implementation for Session type.
+///
+/// ```rust
+/// # use actix_web::*;
+/// use actix_session::Session;
+///
+/// fn index(session: Session) -> Result<&'static str> {
+///     // access session data
+///     if let Some(count) = session.get::<i32>("counter")? {
+///         session.set("counter", count + 1)?;
+///     } else {
+///         session.set("counter", 1)?;
+///     }
+///
+///     Ok("Welcome!")
+/// }
+/// # fn main() {}
+/// ```
+impl FromRequest for Session {
+    type Error = Error;
+    type Future = Ready<Result<Session, Error>>;
+    type Config = ();
+
+    #[inline]
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        ok(Session::get_session(&mut *req.extensions_mut()))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_web::{test, HttpResponse};
+
+    use super::*;
+
+    #[test]
+    fn session() {
+        let mut req = test::TestRequest::default().to_srv_request();
+
+        Session::set_session(
+            vec![("key".to_string(), serde_json::to_string("value").unwrap())],
+            &mut req,
+        );
+        let session = Session::get_session(&mut *req.extensions_mut());
+        let res = session.get::<String>("key").unwrap();
+        assert_eq!(res, Some("value".to_string()));
+
+        session.set("key2", "value2".to_string()).unwrap();
+        session.remove("key");
+
+        let mut res = req.into_response(HttpResponse::Ok().finish());
+        let (_status, state) = Session::get_changes(&mut res);
+        let changes: Vec<_> = state.unwrap().collect();
+        assert_eq!(changes, [("key2".to_string(), "\"value2\"".to_string())]);
+    }
+
+    #[test]
+    fn get_session() {
+        let mut req = test::TestRequest::default().to_srv_request();
+
+        Session::set_session(
+            vec![("key".to_string(), serde_json::to_string(&true).unwrap())],
+            &mut req,
+        );
+
+        let session = req.get_session();
+        let res = session.get("key").unwrap();
+        assert_eq!(res, Some(true));
+    }
+
+    #[test]
+    fn get_session_from_request_head() {
+        let mut req = test::TestRequest::default().to_srv_request();
+
+        Session::set_session(
+            vec![("key".to_string(), serde_json::to_string(&10).unwrap())],
+            &mut req,
+        );
+
+        let session = req.head_mut().get_session();
+        let res = session.get::<u32>("key").unwrap();
+        assert_eq!(res, Some(10));
+    }
+
+    #[test]
+    fn purge_session() {
+        let req = test::TestRequest::default().to_srv_request();
+        let session = Session::get_session(&mut *req.extensions_mut());
+        assert_eq!(session.0.borrow().status, SessionStatus::Unchanged);
+        session.purge();
+        assert_eq!(session.0.borrow().status, SessionStatus::Purged);
+    }
+
+    #[test]
+    fn renew_session() {
+        let req = test::TestRequest::default().to_srv_request();
+        let session = Session::get_session(&mut *req.extensions_mut());
+        assert_eq!(session.0.borrow().status, SessionStatus::Unchanged);
+        session.renew();
+        assert_eq!(session.0.borrow().status, SessionStatus::Renewed);
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/extractors/basic.rs.html b/src/actix_web_httpauth/extractors/basic.rs.html new file mode 100644 index 000000000..356af3bf4 --- /dev/null +++ b/src/actix_web_httpauth/extractors/basic.rs.html @@ -0,0 +1,311 @@ +basic.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
+
+//! Extractor for the "Basic" HTTP Authentication Scheme
+
+use std::borrow::Cow;
+
+use actix_web::dev::{Payload, ServiceRequest};
+use actix_web::http::header::Header;
+use actix_web::{FromRequest, HttpRequest};
+use futures_util::future::{ready, Ready};
+
+use super::config::AuthExtractorConfig;
+use super::errors::AuthenticationError;
+use super::AuthExtractor;
+use crate::headers::authorization::{Authorization, Basic};
+use crate::headers::www_authenticate::basic::Basic as Challenge;
+
+/// [`BasicAuth`] extractor configuration,
+/// used for [`WWW-Authenticate`] header later.
+///
+/// [`BasicAuth`]: ./struct.BasicAuth.html
+/// [`WWW-Authenticate`]:
+/// ../../headers/www_authenticate/struct.WwwAuthenticate.html
+#[derive(Debug, Clone, Default)]
+pub struct Config(Challenge);
+
+impl Config {
+    /// Set challenge `realm` attribute.
+    ///
+    /// The "realm" attribute indicates the scope of protection in the manner
+    /// described in HTTP/1.1 [RFC2617](https://tools.ietf.org/html/rfc2617#section-1.2).
+    pub fn realm<T>(mut self, value: T) -> Config
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        self.0.realm = Some(value.into());
+        self
+    }
+}
+
+impl AsRef<Challenge> for Config {
+    fn as_ref(&self) -> &Challenge {
+        &self.0
+    }
+}
+
+impl AuthExtractorConfig for Config {
+    type Inner = Challenge;
+
+    fn into_inner(self) -> Self::Inner {
+        self.0
+    }
+}
+
+// Needs `fn main` to display complete example.
+#[allow(clippy::needless_doctest_main)]
+/// Extractor for HTTP Basic auth.
+///
+/// # Example
+///
+/// ```
+/// use actix_web::Result;
+/// use actix_web_httpauth::extractors::basic::BasicAuth;
+///
+/// async fn index(auth: BasicAuth) -> String {
+///     format!("Hello, {}!", auth.user_id())
+/// }
+/// ```
+///
+/// If authentication fails, this extractor fetches the [`Config`] instance
+/// from the [app data] in order to properly form the `WWW-Authenticate`
+/// response header.
+///
+/// ## Example
+///
+/// ```
+/// use actix_web::{web, App};
+/// use actix_web_httpauth::extractors::basic::{BasicAuth, Config};
+///
+/// async fn index(auth: BasicAuth) -> String {
+///     format!("Hello, {}!", auth.user_id())
+/// }
+///
+/// fn main() {
+///     let app = App::new()
+///         .data(Config::default().realm("Restricted area"))
+///         .service(web::resource("/index.html").route(web::get().to(index)));
+/// }
+/// ```
+///
+/// [`Config`]: ./struct.Config.html
+/// [app data]: https://docs.rs/actix-web/1.0.0-beta.5/actix_web/struct.App.html#method.data
+#[derive(Debug, Clone)]
+pub struct BasicAuth(Basic);
+
+impl BasicAuth {
+    /// Returns client's user-ID.
+    pub fn user_id(&self) -> &Cow<'static, str> {
+        &self.0.user_id()
+    }
+
+    /// Returns client's password.
+    pub fn password(&self) -> Option<&Cow<'static, str>> {
+        self.0.password()
+    }
+}
+
+impl FromRequest for BasicAuth {
+    type Future = Ready<Result<Self, Self::Error>>;
+    type Config = Config;
+    type Error = AuthenticationError<Challenge>;
+
+    fn from_request(
+        req: &HttpRequest,
+        _: &mut Payload,
+    ) -> <Self as FromRequest>::Future {
+        ready(
+            Authorization::<Basic>::parse(req)
+                .map(|auth| BasicAuth(auth.into_scheme()))
+                .map_err(|_| {
+                    // TODO: debug! the original error
+                    let challenge = req
+                        .app_data::<Self::Config>()
+                        .map(|config| config.0.clone())
+                        // TODO: Add trace! about `Default::default` call
+                        .unwrap_or_else(Default::default);
+
+                    AuthenticationError::new(challenge)
+                }),
+        )
+    }
+}
+
+impl AuthExtractor for BasicAuth {
+    type Error = AuthenticationError<Challenge>;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    fn from_service_request(req: &ServiceRequest) -> Self::Future {
+        ready(
+            Authorization::<Basic>::parse(req)
+                .map(|auth| BasicAuth(auth.into_scheme()))
+                .map_err(|_| {
+                    // TODO: debug! the original error
+                    let challenge = req
+                        .app_data::<Config>()
+                        .map(|config| config.0.clone())
+                        // TODO: Add trace! about `Default::default` call
+                        .unwrap_or_else(Default::default);
+
+                    AuthenticationError::new(challenge)
+                }),
+        )
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/extractors/bearer.rs.html b/src/actix_web_httpauth/extractors/bearer.rs.html new file mode 100644 index 000000000..661e3355d --- /dev/null +++ b/src/actix_web_httpauth/extractors/bearer.rs.html @@ -0,0 +1,367 @@ +bearer.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
+
+//! Extractor for the "Bearer" HTTP Authentication Scheme
+
+use std::borrow::Cow;
+use std::default::Default;
+
+use actix_web::dev::{Payload, ServiceRequest};
+use actix_web::http::header::Header;
+use actix_web::{FromRequest, HttpRequest};
+use futures_util::future::{ready, Ready};
+
+use super::config::AuthExtractorConfig;
+use super::errors::AuthenticationError;
+use super::AuthExtractor;
+use crate::headers::authorization;
+use crate::headers::www_authenticate::bearer;
+pub use crate::headers::www_authenticate::bearer::Error;
+
+/// [BearerAuth](./struct/BearerAuth.html) extractor configuration.
+#[derive(Debug, Clone, Default)]
+pub struct Config(bearer::Bearer);
+
+impl Config {
+    /// Set challenge `scope` attribute.
+    ///
+    /// The `"scope"` attribute is a space-delimited list of case-sensitive
+    /// scope values indicating the required scope of the access token for
+    /// accessing the requested resource.
+    pub fn scope<T: Into<Cow<'static, str>>>(mut self, value: T) -> Config {
+        self.0.scope = Some(value.into());
+        self
+    }
+
+    /// Set challenge `realm` attribute.
+    ///
+    /// The "realm" attribute indicates the scope of protection in the manner
+    /// described in HTTP/1.1 [RFC2617](https://tools.ietf.org/html/rfc2617#section-1.2).
+    pub fn realm<T: Into<Cow<'static, str>>>(mut self, value: T) -> Config {
+        self.0.realm = Some(value.into());
+        self
+    }
+}
+
+impl AsRef<bearer::Bearer> for Config {
+    fn as_ref(&self) -> &bearer::Bearer {
+        &self.0
+    }
+}
+
+impl AuthExtractorConfig for Config {
+    type Inner = bearer::Bearer;
+
+    fn into_inner(self) -> Self::Inner {
+        self.0
+    }
+}
+
+// Needs `fn main` to display complete example.
+#[allow(clippy::needless_doctest_main)]
+/// Extractor for HTTP Bearer auth
+///
+/// # Example
+///
+/// ```
+/// use actix_web_httpauth::extractors::bearer::BearerAuth;
+///
+/// async fn index(auth: BearerAuth) -> String {
+///     format!("Hello, user with token {}!", auth.token())
+/// }
+/// ```
+///
+/// If authentication fails, this extractor fetches the [`Config`] instance
+/// from the [app data] in order to properly form the `WWW-Authenticate`
+/// response header.
+///
+/// ## Example
+///
+/// ```
+/// use actix_web::{web, App};
+/// use actix_web_httpauth::extractors::bearer::{BearerAuth, Config};
+///
+/// async fn index(auth: BearerAuth) -> String {
+///     format!("Hello, {}!", auth.token())
+/// }
+///
+/// fn main() {
+///     let app = App::new()
+///         .data(
+///             Config::default()
+///                 .realm("Restricted area")
+///                 .scope("email photo"),
+///         )
+///         .service(web::resource("/index.html").route(web::get().to(index)));
+/// }
+/// ```
+#[derive(Debug, Clone)]
+pub struct BearerAuth(authorization::Bearer);
+
+impl BearerAuth {
+    /// Returns bearer token provided by client.
+    pub fn token(&self) -> &str {
+        self.0.token()
+    }
+}
+
+impl FromRequest for BearerAuth {
+    type Config = Config;
+    type Future = Ready<Result<Self, Self::Error>>;
+    type Error = AuthenticationError<bearer::Bearer>;
+
+    fn from_request(
+        req: &HttpRequest,
+        _payload: &mut Payload,
+    ) -> <Self as FromRequest>::Future {
+        ready(
+            authorization::Authorization::<authorization::Bearer>::parse(req)
+                .map(|auth| BearerAuth(auth.into_scheme()))
+                .map_err(|_| {
+                    let bearer = req
+                        .app_data::<Self::Config>()
+                        .map(|config| config.0.clone())
+                        .unwrap_or_else(Default::default);
+
+                    AuthenticationError::new(bearer)
+                }),
+        )
+    }
+}
+
+impl AuthExtractor for BearerAuth {
+    type Future = Ready<Result<Self, Self::Error>>;
+    type Error = AuthenticationError<bearer::Bearer>;
+
+    fn from_service_request(req: &ServiceRequest) -> Self::Future {
+        ready(
+            authorization::Authorization::<authorization::Bearer>::parse(req)
+                .map(|auth| BearerAuth(auth.into_scheme()))
+                .map_err(|_| {
+                    let bearer = req
+                        .app_data::<Config>()
+                        .map(|config| config.0.clone())
+                        .unwrap_or_else(Default::default);
+
+                    AuthenticationError::new(bearer)
+                }),
+        )
+    }
+}
+
+/// Extended error customization for HTTP `Bearer` auth.
+impl AuthenticationError<bearer::Bearer> {
+    /// Attach `Error` to the current Authentication error.
+    ///
+    /// Error status code will be changed to the one provided by the `kind`
+    /// Error.
+    pub fn with_error(mut self, kind: Error) -> Self {
+        *self.status_code_mut() = kind.status_code();
+        self.challenge_mut().error = Some(kind);
+        self
+    }
+
+    /// Attach error description to the current Authentication error.
+    pub fn with_error_description<T>(mut self, desc: T) -> Self
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        self.challenge_mut().error_description = Some(desc.into());
+        self
+    }
+
+    /// Attach error URI to the current Authentication error.
+    ///
+    /// It is up to implementor to provide properly formed absolute URI.
+    pub fn with_error_uri<T>(mut self, uri: T) -> Self
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        self.challenge_mut().error_uri = Some(uri.into());
+        self
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/extractors/config.rs.html b/src/actix_web_httpauth/extractors/config.rs.html new file mode 100644 index 000000000..929e48da8 --- /dev/null +++ b/src/actix_web_httpauth/extractors/config.rs.html @@ -0,0 +1,53 @@ +config.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
+
+use super::AuthenticationError;
+use crate::headers::www_authenticate::Challenge;
+
+/// Trait implemented for types that provides configuration
+/// for the authentication [extractors].
+///
+/// [extractors]: ./trait.AuthExtractor.html
+pub trait AuthExtractorConfig {
+    /// Associated challenge type.
+    type Inner: Challenge;
+
+    /// Convert the config instance into a HTTP challenge.
+    fn into_inner(self) -> Self::Inner;
+}
+
+impl<T> From<T> for AuthenticationError<<T as AuthExtractorConfig>::Inner>
+where
+    T: AuthExtractorConfig,
+{
+    fn from(config: T) -> Self {
+        AuthenticationError::new(config.into_inner())
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/extractors/errors.rs.html b/src/actix_web_httpauth/extractors/errors.rs.html new file mode 100644 index 000000000..ef7d6cf43 --- /dev/null +++ b/src/actix_web_httpauth/extractors/errors.rs.html @@ -0,0 +1,171 @@ +errors.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
+
+use std::error::Error;
+use std::fmt;
+
+use actix_web::http::StatusCode;
+use actix_web::{HttpResponse, ResponseError};
+
+use crate::headers::www_authenticate::Challenge;
+use crate::headers::www_authenticate::WwwAuthenticate;
+
+/// Authentication error returned by authentication extractors.
+///
+/// Different extractors may extend `AuthenticationError` implementation
+/// in order to provide access to inner challenge fields.
+#[derive(Debug)]
+pub struct AuthenticationError<C: Challenge> {
+    challenge: C,
+    status_code: StatusCode,
+}
+
+impl<C: Challenge> AuthenticationError<C> {
+    /// Creates new authentication error from the provided `challenge`.
+    ///
+    /// By default returned error will resolve into the `HTTP 401` status code.
+    pub fn new(challenge: C) -> AuthenticationError<C> {
+        AuthenticationError {
+            challenge,
+            status_code: StatusCode::UNAUTHORIZED,
+        }
+    }
+
+    /// Returns mutable reference to the inner challenge instance.
+    pub fn challenge_mut(&mut self) -> &mut C {
+        &mut self.challenge
+    }
+
+    /// Returns mutable reference to the inner status code.
+    ///
+    /// Can be used to override returned status code, but by default
+    /// this lib tries to stick to the RFC, so it might be unreasonable.
+    pub fn status_code_mut(&mut self) -> &mut StatusCode {
+        &mut self.status_code
+    }
+}
+
+impl<C: Challenge> fmt::Display for AuthenticationError<C> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.status_code, f)
+    }
+}
+
+impl<C: 'static + Challenge> Error for AuthenticationError<C> {}
+
+impl<C: 'static + Challenge> ResponseError for AuthenticationError<C> {
+    fn error_response(&self) -> HttpResponse {
+        HttpResponse::build(self.status_code)
+            // TODO: Get rid of the `.clone()`
+            .insert_header(WwwAuthenticate(self.challenge.clone()))
+            .finish()
+    }
+
+    fn status_code(&self) -> StatusCode {
+        self.status_code
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::headers::www_authenticate::basic::Basic;
+    use actix_web::Error;
+
+    #[test]
+    fn test_status_code_is_preserved_across_error_conversions() {
+        let ae: AuthenticationError<Basic> = AuthenticationError::new(Basic::default());
+        let expected = ae.status_code;
+
+        // Converting the AuthenticationError into a ResponseError should preserve the status code.
+        let e = Error::from(ae);
+        let re = e.as_response_error();
+        assert_eq!(expected, re.status_code());
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/extractors/mod.rs.html b/src/actix_web_httpauth/extractors/mod.rs.html new file mode 100644 index 000000000..ae6799941 --- /dev/null +++ b/src/actix_web_httpauth/extractors/mod.rs.html @@ -0,0 +1,73 @@ +mod.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
+
+//! Type-safe authentication information extractors
+
+use actix_web::dev::ServiceRequest;
+use actix_web::Error;
+use std::future::Future;
+
+pub mod basic;
+pub mod bearer;
+mod config;
+mod errors;
+
+pub use self::config::AuthExtractorConfig;
+pub use self::errors::AuthenticationError;
+
+/// Trait implemented by types that can extract
+/// HTTP authentication scheme credentials from the request.
+///
+/// It is very similar to actix' `FromRequest` trait,
+/// except it operates with a `ServiceRequest` struct instead,
+/// therefore it can be used in the middlewares.
+///
+/// You will not need it unless you want to implement your own
+/// authentication scheme.
+pub trait AuthExtractor: Sized {
+    /// The associated error which can be returned.
+    type Error: Into<Error>;
+
+    /// Future that resolves into extracted credentials type.
+    type Future: Future<Output = Result<Self, Self::Error>>;
+
+    /// Parse the authentication credentials from the actix' `ServiceRequest`.
+    fn from_service_request(req: &ServiceRequest) -> Self::Future;
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/authorization/errors.rs.html b/src/actix_web_httpauth/headers/authorization/errors.rs.html new file mode 100644 index 000000000..1bbaaa5ed --- /dev/null +++ b/src/actix_web_httpauth/headers/authorization/errors.rs.html @@ -0,0 +1,145 @@ +errors.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
+
+use std::convert::From;
+use std::error::Error;
+use std::fmt;
+use std::str;
+
+use actix_web::http::header;
+
+/// Possible errors while parsing `Authorization` header.
+///
+/// Should not be used directly unless you are implementing
+/// your own [authentication scheme](./trait.Scheme.html).
+#[derive(Debug)]
+pub enum ParseError {
+    /// Header value is malformed
+    Invalid,
+    /// Authentication scheme is missing
+    MissingScheme,
+    /// Required authentication field is missing
+    MissingField(&'static str),
+    /// Unable to convert header into the str
+    ToStrError(header::ToStrError),
+    /// Malformed base64 string
+    Base64DecodeError(base64::DecodeError),
+    /// Malformed UTF-8 string
+    Utf8Error(str::Utf8Error),
+}
+
+impl fmt::Display for ParseError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let display = match self {
+            ParseError::Invalid => "Invalid header value".to_string(),
+            ParseError::MissingScheme => "Missing authorization scheme".to_string(),
+            ParseError::MissingField(_) => "Missing header field".to_string(),
+            ParseError::ToStrError(e) => e.to_string(),
+            ParseError::Base64DecodeError(e) => e.to_string(),
+            ParseError::Utf8Error(e) => e.to_string(),
+        };
+        f.write_str(&display)
+    }
+}
+
+impl Error for ParseError {
+    fn source(&self) -> Option<&(dyn Error + 'static)> {
+        match self {
+            ParseError::Invalid => None,
+            ParseError::MissingScheme => None,
+            ParseError::MissingField(_) => None,
+            ParseError::ToStrError(e) => Some(e),
+            ParseError::Base64DecodeError(e) => Some(e),
+            ParseError::Utf8Error(e) => Some(e),
+        }
+    }
+}
+
+impl From<header::ToStrError> for ParseError {
+    fn from(e: header::ToStrError) -> Self {
+        ParseError::ToStrError(e)
+    }
+}
+impl From<base64::DecodeError> for ParseError {
+    fn from(e: base64::DecodeError) -> Self {
+        ParseError::Base64DecodeError(e)
+    }
+}
+impl From<str::Utf8Error> for ParseError {
+    fn from(e: str::Utf8Error) -> Self {
+        ParseError::Utf8Error(e)
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/authorization/header.rs.html b/src/actix_web_httpauth/headers/authorization/header.rs.html new file mode 100644 index 000000000..de471aeba --- /dev/null +++ b/src/actix_web_httpauth/headers/authorization/header.rs.html @@ -0,0 +1,213 @@ +header.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
+
+use std::fmt;
+
+use actix_web::error::ParseError;
+use actix_web::http::header::{
+    Header, HeaderName, HeaderValue, IntoHeaderValue, AUTHORIZATION,
+};
+use actix_web::HttpMessage;
+
+use crate::headers::authorization::scheme::Scheme;
+
+/// `Authorization` header, defined in [RFC 7235](https://tools.ietf.org/html/rfc7235#section-4.2)
+///
+/// The "Authorization" header field allows a user agent to authenticate
+/// itself with an origin server -- usually, but not necessarily, after
+/// receiving a 401 (Unauthorized) response.  Its value consists of
+/// credentials containing the authentication information of the user
+/// agent for the realm of the resource being requested.
+///
+/// `Authorization` header is generic over [authentication
+/// scheme](./trait.Scheme.html).
+///
+/// # Example
+///
+/// ```
+/// # use actix_web::http::header::Header;
+/// # use actix_web::{HttpRequest, Result};
+/// # use actix_web_httpauth::headers::authorization::{Authorization, Basic};
+/// fn handler(req: HttpRequest) -> Result<String> {
+///     let auth = Authorization::<Basic>::parse(&req)?;
+///
+///     Ok(format!("Hello, {}!", auth.as_ref().user_id()))
+/// }
+/// ```
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Clone)]
+pub struct Authorization<S: Scheme>(S);
+
+impl<S> Authorization<S>
+where
+    S: Scheme,
+{
+    /// Consumes `Authorization` header and returns inner [`Scheme`]
+    /// implementation.
+    ///
+    /// [`Scheme`]: ./trait.Scheme.html
+    pub fn into_scheme(self) -> S {
+        self.0
+    }
+}
+
+impl<S> From<S> for Authorization<S>
+where
+    S: Scheme,
+{
+    fn from(scheme: S) -> Authorization<S> {
+        Authorization(scheme)
+    }
+}
+
+impl<S> AsRef<S> for Authorization<S>
+where
+    S: Scheme,
+{
+    fn as_ref(&self) -> &S {
+        &self.0
+    }
+}
+
+impl<S> AsMut<S> for Authorization<S>
+where
+    S: Scheme,
+{
+    fn as_mut(&mut self) -> &mut S {
+        &mut self.0
+    }
+}
+
+impl<S: Scheme> Header for Authorization<S> {
+    #[inline]
+    fn name() -> HeaderName {
+        AUTHORIZATION
+    }
+
+    fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError> {
+        let header = msg.headers().get(AUTHORIZATION).ok_or(ParseError::Header)?;
+        let scheme = S::parse(header).map_err(|_| ParseError::Header)?;
+
+        Ok(Authorization(scheme))
+    }
+}
+
+impl<S: Scheme> IntoHeaderValue for Authorization<S> {
+    type Error = <S as IntoHeaderValue>::Error;
+
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        self.0.try_into_value()
+    }
+}
+
+impl<S: Scheme> fmt::Display for Authorization<S> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.0, f)
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/authorization/mod.rs.html b/src/actix_web_httpauth/headers/authorization/mod.rs.html new file mode 100644 index 000000000..c188e16ab --- /dev/null +++ b/src/actix_web_httpauth/headers/authorization/mod.rs.html @@ -0,0 +1,29 @@ +mod.rs - source + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+
+//! `Authorization` header and various auth schemes
+
+mod errors;
+mod header;
+mod scheme;
+
+pub use self::errors::ParseError;
+pub use self::header::Authorization;
+pub use self::scheme::basic::Basic;
+pub use self::scheme::bearer::Bearer;
+pub use self::scheme::Scheme;
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/authorization/scheme/basic.rs.html b/src/actix_web_httpauth/headers/authorization/scheme/basic.rs.html new file mode 100644 index 000000000..e3d33a8a9 --- /dev/null +++ b/src/actix_web_httpauth/headers/authorization/scheme/basic.rs.html @@ -0,0 +1,401 @@ +basic.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
+
+use std::borrow::Cow;
+use std::fmt;
+use std::str;
+
+use actix_web::http::header::{HeaderValue, IntoHeaderValue, InvalidHeaderValue};
+use actix_web::web::{BufMut, BytesMut};
+
+use crate::headers::authorization::errors::ParseError;
+use crate::headers::authorization::Scheme;
+
+/// Credentials for `Basic` authentication scheme, defined in [RFC 7617](https://tools.ietf.org/html/rfc7617)
+#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
+pub struct Basic {
+    user_id: Cow<'static, str>,
+    password: Option<Cow<'static, str>>,
+}
+
+impl Basic {
+    /// Creates `Basic` credentials with provided `user_id` and optional
+    /// `password`.
+    ///
+    /// ## Example
+    ///
+    /// ```
+    /// # use actix_web_httpauth::headers::authorization::Basic;
+    /// let credentials = Basic::new("Alladin", Some("open sesame"));
+    /// ```
+    pub fn new<U, P>(user_id: U, password: Option<P>) -> Basic
+    where
+        U: Into<Cow<'static, str>>,
+        P: Into<Cow<'static, str>>,
+    {
+        Basic {
+            user_id: user_id.into(),
+            password: password.map(Into::into),
+        }
+    }
+
+    /// Returns client's user-ID.
+    pub fn user_id(&self) -> &Cow<'static, str> {
+        &self.user_id
+    }
+
+    /// Returns client's password if provided.
+    pub fn password(&self) -> Option<&Cow<'static, str>> {
+        self.password.as_ref()
+    }
+}
+
+impl Scheme for Basic {
+    fn parse(header: &HeaderValue) -> Result<Self, ParseError> {
+        // "Basic *" length
+        if header.len() < 7 {
+            return Err(ParseError::Invalid);
+        }
+
+        let mut parts = header.to_str()?.splitn(2, ' ');
+        match parts.next() {
+            Some(scheme) if scheme == "Basic" => (),
+            _ => return Err(ParseError::MissingScheme),
+        }
+
+        let decoded = base64::decode(parts.next().ok_or(ParseError::Invalid)?)?;
+        let mut credentials = str::from_utf8(&decoded)?.splitn(2, ':');
+
+        let user_id = credentials
+            .next()
+            .ok_or(ParseError::MissingField("user_id"))
+            .map(|user_id| user_id.to_string().into())?;
+        let password = credentials
+            .next()
+            .ok_or(ParseError::MissingField("password"))
+            .map(|password| {
+                if password.is_empty() {
+                    None
+                } else {
+                    Some(password.to_string().into())
+                }
+            })?;
+
+        Ok(Basic { user_id, password })
+    }
+}
+
+impl fmt::Debug for Basic {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_fmt(format_args!("Basic {}:******", self.user_id))
+    }
+}
+
+impl fmt::Display for Basic {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_fmt(format_args!("Basic {}:******", self.user_id))
+    }
+}
+
+impl IntoHeaderValue for Basic {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, <Self as IntoHeaderValue>::Error> {
+        let mut credentials = BytesMut::with_capacity(
+            self.user_id.len()
+                + 1 // ':'
+                + self.password.as_ref().map_or(0, |pwd| pwd.len()),
+        );
+
+        credentials.extend_from_slice(self.user_id.as_bytes());
+        credentials.put_u8(b':');
+        if let Some(ref password) = self.password {
+            credentials.extend_from_slice(password.as_bytes());
+        }
+
+        // TODO: It would be nice not to allocate new `String`  here but write
+        // directly to `value`
+        let encoded = base64::encode(&credentials);
+        let mut value = BytesMut::with_capacity(6 + encoded.len());
+        value.put(&b"Basic "[..]);
+        value.put(encoded.as_bytes());
+
+        HeaderValue::from_maybe_shared(value.freeze())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{Basic, Scheme};
+    use actix_web::http::header::{HeaderValue, IntoHeaderValue};
+
+    #[test]
+    fn test_parse_header() {
+        let value = HeaderValue::from_static("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
+        let scheme = Basic::parse(&value);
+
+        assert!(scheme.is_ok());
+        let scheme = scheme.unwrap();
+        assert_eq!(scheme.user_id, "Aladdin");
+        assert_eq!(scheme.password, Some("open sesame".into()));
+    }
+
+    #[test]
+    fn test_empty_password() {
+        let value = HeaderValue::from_static("Basic QWxhZGRpbjo=");
+        let scheme = Basic::parse(&value);
+
+        assert!(scheme.is_ok());
+        let scheme = scheme.unwrap();
+        assert_eq!(scheme.user_id, "Aladdin");
+        assert_eq!(scheme.password, None);
+    }
+
+    #[test]
+    fn test_empty_header() {
+        let value = HeaderValue::from_static("");
+        let scheme = Basic::parse(&value);
+
+        assert!(scheme.is_err());
+    }
+
+    #[test]
+    fn test_wrong_scheme() {
+        let value = HeaderValue::from_static("THOUSHALLNOTPASS please?");
+        let scheme = Basic::parse(&value);
+
+        assert!(scheme.is_err());
+    }
+
+    #[test]
+    fn test_missing_credentials() {
+        let value = HeaderValue::from_static("Basic ");
+        let scheme = Basic::parse(&value);
+
+        assert!(scheme.is_err());
+    }
+
+    #[test]
+    fn test_missing_credentials_colon() {
+        let value = HeaderValue::from_static("Basic QWxsYWRpbg==");
+        let scheme = Basic::parse(&value);
+
+        assert!(scheme.is_err());
+    }
+
+    #[test]
+    fn test_into_header_value() {
+        let basic = Basic {
+            user_id: "Aladdin".into(),
+            password: Some("open sesame".into()),
+        };
+
+        let result = basic.try_into_value();
+        assert!(result.is_ok());
+        assert_eq!(
+            result.unwrap(),
+            HeaderValue::from_static("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==")
+        );
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/authorization/scheme/bearer.rs.html b/src/actix_web_httpauth/headers/authorization/scheme/bearer.rs.html new file mode 100644 index 000000000..4dddfdd44 --- /dev/null +++ b/src/actix_web_httpauth/headers/authorization/scheme/bearer.rs.html @@ -0,0 +1,283 @@ +bearer.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
+
+use std::borrow::Cow;
+use std::fmt;
+
+use actix_web::http::header::{HeaderValue, IntoHeaderValue, InvalidHeaderValue};
+use actix_web::web::{BufMut, BytesMut};
+
+use crate::headers::authorization::errors::ParseError;
+use crate::headers::authorization::scheme::Scheme;
+
+/// Credentials for `Bearer` authentication scheme, defined in [RFC6750](https://tools.ietf.org/html/rfc6750)
+///
+/// Should be used in combination with
+/// [`Authorization`](./struct.Authorization.html) header.
+#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
+pub struct Bearer {
+    token: Cow<'static, str>,
+}
+
+impl Bearer {
+    /// Creates new `Bearer` credentials with the token provided.
+    ///
+    /// ## Example
+    ///
+    /// ```
+    /// # use actix_web_httpauth::headers::authorization::Bearer;
+    /// let credentials = Bearer::new("mF_9.B5f-4.1JqM");
+    /// ```
+    pub fn new<T>(token: T) -> Bearer
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        Bearer {
+            token: token.into(),
+        }
+    }
+
+    /// Gets reference to the credentials token.
+    pub fn token(&self) -> &Cow<'static, str> {
+        &self.token
+    }
+}
+
+impl Scheme for Bearer {
+    fn parse(header: &HeaderValue) -> Result<Self, ParseError> {
+        // "Bearer *" length
+        if header.len() < 8 {
+            return Err(ParseError::Invalid);
+        }
+
+        let mut parts = header.to_str()?.splitn(2, ' ');
+        match parts.next() {
+            Some(scheme) if scheme == "Bearer" => (),
+            _ => return Err(ParseError::MissingScheme),
+        }
+
+        let token = parts.next().ok_or(ParseError::Invalid)?;
+
+        Ok(Bearer {
+            token: token.to_string().into(),
+        })
+    }
+}
+
+impl fmt::Debug for Bearer {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_fmt(format_args!("Bearer ******"))
+    }
+}
+
+impl fmt::Display for Bearer {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_fmt(format_args!("Bearer {}", self.token))
+    }
+}
+
+impl IntoHeaderValue for Bearer {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, <Self as IntoHeaderValue>::Error> {
+        let mut buffer = BytesMut::with_capacity(7 + self.token.len());
+        buffer.put(&b"Bearer "[..]);
+        buffer.extend_from_slice(self.token.as_bytes());
+
+        HeaderValue::from_maybe_shared(buffer.freeze())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{Bearer, Scheme};
+    use actix_web::http::header::{HeaderValue, IntoHeaderValue};
+
+    #[test]
+    fn test_parse_header() {
+        let value = HeaderValue::from_static("Bearer mF_9.B5f-4.1JqM");
+        let scheme = Bearer::parse(&value);
+
+        assert!(scheme.is_ok());
+        let scheme = scheme.unwrap();
+        assert_eq!(scheme.token, "mF_9.B5f-4.1JqM");
+    }
+
+    #[test]
+    fn test_empty_header() {
+        let value = HeaderValue::from_static("");
+        let scheme = Bearer::parse(&value);
+
+        assert!(scheme.is_err());
+    }
+
+    #[test]
+    fn test_wrong_scheme() {
+        let value = HeaderValue::from_static("OAuthToken foo");
+        let scheme = Bearer::parse(&value);
+
+        assert!(scheme.is_err());
+    }
+
+    #[test]
+    fn test_missing_token() {
+        let value = HeaderValue::from_static("Bearer ");
+        let scheme = Bearer::parse(&value);
+
+        assert!(scheme.is_err());
+    }
+
+    #[test]
+    fn test_into_header_value() {
+        let bearer = Bearer::new("mF_9.B5f-4.1JqM");
+
+        let result = bearer.try_into_value();
+        assert!(result.is_ok());
+        assert_eq!(
+            result.unwrap(),
+            HeaderValue::from_static("Bearer mF_9.B5f-4.1JqM")
+        );
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/authorization/scheme/mod.rs.html b/src/actix_web_httpauth/headers/authorization/scheme/mod.rs.html new file mode 100644 index 000000000..6387647a5 --- /dev/null +++ b/src/actix_web_httpauth/headers/authorization/scheme/mod.rs.html @@ -0,0 +1,37 @@ +mod.rs - source + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+
+use std::fmt::{Debug, Display};
+
+use actix_web::http::header::{HeaderValue, IntoHeaderValue};
+
+pub mod basic;
+pub mod bearer;
+
+use crate::headers::authorization::errors::ParseError;
+
+/// Authentication scheme for [`Authorization`](./struct.Authorization.html)
+/// header.
+pub trait Scheme: IntoHeaderValue + Debug + Display + Clone + Send + Sync {
+    /// Try to parse the authentication scheme from the `Authorization` header.
+    fn parse(header: &HeaderValue) -> Result<Self, ParseError>;
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/mod.rs.html b/src/actix_web_httpauth/headers/mod.rs.html new file mode 100644 index 000000000..983e830e5 --- /dev/null +++ b/src/actix_web_httpauth/headers/mod.rs.html @@ -0,0 +1,15 @@ +mod.rs - source + +
1
+2
+3
+4
+
+//! Typed HTTP headers
+
+pub mod authorization;
+pub mod www_authenticate;
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/www_authenticate/challenge/basic.rs.html b/src/actix_web_httpauth/headers/www_authenticate/challenge/basic.rs.html new file mode 100644 index 000000000..fc24f9ead --- /dev/null +++ b/src/actix_web_httpauth/headers/www_authenticate/challenge/basic.rs.html @@ -0,0 +1,287 @@ +basic.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
+
+//! Challenge for the "Basic" HTTP Authentication Scheme
+
+use std::borrow::Cow;
+use std::default::Default;
+use std::fmt;
+use std::str;
+
+use actix_web::http::header::{HeaderValue, IntoHeaderValue, InvalidHeaderValue};
+use actix_web::web::{BufMut, Bytes, BytesMut};
+
+use super::Challenge;
+use crate::utils;
+
+/// Challenge for [`WWW-Authenticate`] header with HTTP Basic auth scheme,
+/// described in [RFC 7617](https://tools.ietf.org/html/rfc7617)
+///
+/// ## Example
+///
+/// ```
+/// # use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
+/// use actix_web_httpauth::headers::www_authenticate::basic::Basic;
+/// use actix_web_httpauth::headers::www_authenticate::WwwAuthenticate;
+///
+/// fn index(_req: HttpRequest) -> HttpResponse {
+///     let challenge = Basic::with_realm("Restricted area");
+///
+///     HttpResponse::Unauthorized()
+///         .insert_header(WwwAuthenticate(challenge))
+///         .finish()
+/// }
+/// ```
+///
+/// [`WWW-Authenticate`]: ../struct.WwwAuthenticate.html
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Clone)]
+pub struct Basic {
+    // "realm" parameter is optional now: https://tools.ietf.org/html/rfc7235#appendix-A
+    pub(crate) realm: Option<Cow<'static, str>>,
+}
+
+impl Basic {
+    /// Creates new `Basic` challenge with an empty `realm` field.
+    ///
+    /// ## Example
+    ///
+    /// ```
+    /// # use actix_web_httpauth::headers::www_authenticate::basic::Basic;
+    /// let challenge = Basic::new();
+    /// ```
+    pub fn new() -> Basic {
+        Default::default()
+    }
+
+    /// Creates new `Basic` challenge from the provided `realm` field value.
+    ///
+    /// ## Examples
+    ///
+    /// ```
+    /// # use actix_web_httpauth::headers::www_authenticate::basic::Basic;
+    /// let challenge = Basic::with_realm("Restricted area");
+    /// ```
+    ///
+    /// ```
+    /// # use actix_web_httpauth::headers::www_authenticate::basic::Basic;
+    /// let my_realm = "Earth realm".to_string();
+    /// let challenge = Basic::with_realm(my_realm);
+    /// ```
+    pub fn with_realm<T>(value: T) -> Basic
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        Basic {
+            realm: Some(value.into()),
+        }
+    }
+}
+
+#[doc(hidden)]
+impl Challenge for Basic {
+    fn to_bytes(&self) -> Bytes {
+        // 5 is for `"Basic"`, 9 is for `"realm=\"\""`
+        let length = 5 + self.realm.as_ref().map_or(0, |realm| realm.len() + 9);
+        let mut buffer = BytesMut::with_capacity(length);
+        buffer.put(&b"Basic"[..]);
+        if let Some(ref realm) = self.realm {
+            buffer.put(&b" realm=\""[..]);
+            utils::put_quoted(&mut buffer, realm);
+            buffer.put_u8(b'"');
+        }
+
+        buffer.freeze()
+    }
+}
+
+impl fmt::Display for Basic {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        let bytes = self.to_bytes();
+        let repr = str::from_utf8(&bytes)
+            // Should not happen since challenges are crafted manually
+            // from a `&'static str` or `String`
+            .map_err(|_| fmt::Error)?;
+
+        f.write_str(repr)
+    }
+}
+
+impl IntoHeaderValue for Basic {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, <Self as IntoHeaderValue>::Error> {
+        HeaderValue::from_maybe_shared(self.to_bytes())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::Basic;
+    use actix_web::http::header::IntoHeaderValue;
+
+    #[test]
+    fn test_plain_into_header_value() {
+        let challenge = Basic { realm: None };
+
+        let value = challenge.try_into_value();
+        assert!(value.is_ok());
+        let value = value.unwrap();
+        assert_eq!(value, "Basic");
+    }
+
+    #[test]
+    fn test_with_realm_into_header_value() {
+        let challenge = Basic {
+            realm: Some("Restricted area".into()),
+        };
+
+        let value = challenge.try_into_value();
+        assert!(value.is_ok());
+        let value = value.unwrap();
+        assert_eq!(value, "Basic realm=\"Restricted area\"");
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/builder.rs.html b/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/builder.rs.html new file mode 100644 index 000000000..3a6a72cd4 --- /dev/null +++ b/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/builder.rs.html @@ -0,0 +1,133 @@ +builder.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
+
+use std::borrow::Cow;
+
+use super::{Bearer, Error};
+
+/// Builder for the [`Bearer`] challenge.
+///
+/// It is up to implementor to fill all required fields,
+/// neither this `Builder` or [`Bearer`] does not provide any validation.
+///
+/// [`Bearer`]: struct.Bearer.html
+#[derive(Debug, Default)]
+pub struct BearerBuilder(Bearer);
+
+impl BearerBuilder {
+    /// Provides the `scope` attribute, as defined in [RFC6749, Section 3.3](https://tools.ietf.org/html/rfc6749#section-3.3)
+    pub fn scope<T>(mut self, value: T) -> Self
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        self.0.scope = Some(value.into());
+        self
+    }
+
+    /// Provides the `realm` attribute, as defined in [RFC2617](https://tools.ietf.org/html/rfc2617)
+    pub fn realm<T>(mut self, value: T) -> Self
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        self.0.realm = Some(value.into());
+        self
+    }
+
+    /// Provides the `error` attribute, as defined in [RFC6750, Section 3.1](https://tools.ietf.org/html/rfc6750#section-3.1)
+    pub fn error(mut self, value: Error) -> Self {
+        self.0.error = Some(value);
+        self
+    }
+
+    /// Provides the `error_description` attribute, as defined in [RFC6750, Section 3](https://tools.ietf.org/html/rfc6750#section-3)
+    pub fn error_description<T>(mut self, value: T) -> Self
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        self.0.error_description = Some(value.into());
+        self
+    }
+
+    /// Provides the `error_uri` attribute, as defined in [RFC6750, Section 3](https://tools.ietf.org/html/rfc6750#section-3)
+    ///
+    /// It is up to implementor to provide properly-formed absolute URI.
+    pub fn error_uri<T>(mut self, value: T) -> Self
+    where
+        T: Into<Cow<'static, str>>,
+    {
+        self.0.error_uri = Some(value.into());
+        self
+    }
+
+    /// Consumes the builder and returns built `Bearer` instance.
+    pub fn finish(self) -> Bearer {
+        self.0
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/challenge.rs.html b/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/challenge.rs.html new file mode 100644 index 000000000..1d6c18e8f --- /dev/null +++ b/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/challenge.rs.html @@ -0,0 +1,285 @@ +challenge.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
+
+use std::borrow::Cow;
+use std::fmt;
+use std::str;
+
+use actix_web::http::header::{HeaderValue, IntoHeaderValue, InvalidHeaderValue};
+use actix_web::web::{BufMut, Bytes, BytesMut};
+
+use super::super::Challenge;
+use super::{BearerBuilder, Error};
+use crate::utils;
+
+/// Challenge for [`WWW-Authenticate`] header with HTTP Bearer auth scheme,
+/// described in [RFC 6750](https://tools.ietf.org/html/rfc6750#section-3)
+///
+/// ## Example
+///
+/// ```
+/// # use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
+/// use actix_web_httpauth::headers::www_authenticate::bearer::{
+///     Bearer, Error,
+/// };
+/// use actix_web_httpauth::headers::www_authenticate::WwwAuthenticate;
+///
+/// fn index(_req: HttpRequest) -> HttpResponse {
+///     let challenge = Bearer::build()
+///         .realm("example")
+///         .scope("openid profile email")
+///         .error(Error::InvalidToken)
+///         .error_description("The access token expired")
+///         .error_uri("http://example.org")
+///         .finish();
+///
+///     HttpResponse::Unauthorized()
+///         .insert_header(WwwAuthenticate(challenge))
+///         .finish()
+/// }
+/// ```
+///
+/// [`WWW-Authenticate`]: ../struct.WwwAuthenticate.html
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Clone)]
+pub struct Bearer {
+    pub(crate) scope: Option<Cow<'static, str>>,
+    pub(crate) realm: Option<Cow<'static, str>>,
+    pub(crate) error: Option<Error>,
+    pub(crate) error_description: Option<Cow<'static, str>>,
+    pub(crate) error_uri: Option<Cow<'static, str>>,
+}
+
+impl Bearer {
+    /// Creates the builder for `Bearer` challenge.
+    ///
+    /// ## Example
+    ///
+    /// ```
+    /// # use actix_web_httpauth::headers::www_authenticate::bearer::{Bearer};
+    /// let challenge = Bearer::build()
+    ///     .realm("Restricted area")
+    ///     .scope("openid profile email")
+    ///     .finish();
+    /// ```
+    pub fn build() -> BearerBuilder {
+        BearerBuilder::default()
+    }
+}
+
+#[doc(hidden)]
+impl Challenge for Bearer {
+    fn to_bytes(&self) -> Bytes {
+        let desc_uri_required = self
+            .error_description
+            .as_ref()
+            .map_or(0, |desc| desc.len() + 20)
+            + self.error_uri.as_ref().map_or(0, |url| url.len() + 12);
+        let capacity = 6
+            + self.realm.as_ref().map_or(0, |realm| realm.len() + 9)
+            + self.scope.as_ref().map_or(0, |scope| scope.len() + 9)
+            + desc_uri_required;
+        let mut buffer = BytesMut::with_capacity(capacity);
+        buffer.put(&b"Bearer"[..]);
+
+        if let Some(ref realm) = self.realm {
+            buffer.put(&b" realm=\""[..]);
+            utils::put_quoted(&mut buffer, realm);
+            buffer.put_u8(b'"');
+        }
+
+        if let Some(ref scope) = self.scope {
+            buffer.put(&b" scope=\""[..]);
+            utils::put_quoted(&mut buffer, scope);
+            buffer.put_u8(b'"');
+        }
+
+        if let Some(ref error) = self.error {
+            let error_repr = error.as_str();
+            let remaining = buffer.remaining_mut();
+            let required = desc_uri_required + error_repr.len() + 9; // 9 is for `" error=\"\""`
+            if remaining < required {
+                buffer.reserve(required);
+            }
+            buffer.put(&b" error=\""[..]);
+            utils::put_quoted(&mut buffer, error_repr);
+            buffer.put_u8(b'"')
+        }
+
+        if let Some(ref error_description) = self.error_description {
+            buffer.put(&b" error_description=\""[..]);
+            utils::put_quoted(&mut buffer, error_description);
+            buffer.put_u8(b'"');
+        }
+
+        if let Some(ref error_uri) = self.error_uri {
+            buffer.put(&b" error_uri=\""[..]);
+            utils::put_quoted(&mut buffer, error_uri);
+            buffer.put_u8(b'"');
+        }
+
+        buffer.freeze()
+    }
+}
+
+impl fmt::Display for Bearer {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        let bytes = self.to_bytes();
+        let repr = str::from_utf8(&bytes)
+            // Should not happen since challenges are crafted manually
+            // from `&'static str`'s and Strings
+            .map_err(|_| fmt::Error)?;
+
+        f.write_str(repr)
+    }
+}
+
+impl IntoHeaderValue for Bearer {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, <Self as IntoHeaderValue>::Error> {
+        HeaderValue::from_maybe_shared(self.to_bytes())
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/errors.rs.html b/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/errors.rs.html new file mode 100644 index 000000000..e0f229c37 --- /dev/null +++ b/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/errors.rs.html @@ -0,0 +1,109 @@ +errors.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
+
+use std::fmt;
+
+use actix_web::http::StatusCode;
+
+/// Bearer authorization error types, described in [RFC 6750](https://tools.ietf.org/html/rfc6750#section-3.1)
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
+pub enum Error {
+    /// The request is missing a required parameter, includes an unsupported
+    /// parameter or parameter value, repeats the same parameter, uses more
+    /// than one method for including an access token, or is otherwise
+    /// malformed.
+    InvalidRequest,
+
+    /// The access token provided is expired, revoked, malformed, or invalid
+    /// for other reasons.
+    InvalidToken,
+
+    /// The request requires higher privileges than provided by the access
+    /// token.
+    InsufficientScope,
+}
+
+impl Error {
+    /// Returns [HTTP status code] suitable for current error type.
+    ///
+    /// [HTTP status code]: `actix_web::http::StatusCode`
+    #[allow(clippy::trivially_copy_pass_by_ref)]
+    pub fn status_code(&self) -> StatusCode {
+        match self {
+            Error::InvalidRequest => StatusCode::BAD_REQUEST,
+            Error::InvalidToken => StatusCode::UNAUTHORIZED,
+            Error::InsufficientScope => StatusCode::FORBIDDEN,
+        }
+    }
+
+    #[doc(hidden)]
+    #[allow(clippy::trivially_copy_pass_by_ref)]
+    pub fn as_str(&self) -> &str {
+        match self {
+            Error::InvalidRequest => "invalid_request",
+            Error::InvalidToken => "invalid_token",
+            Error::InsufficientScope => "insufficient_scope",
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(self.as_str())
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/mod.rs.html b/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/mod.rs.html new file mode 100644 index 000000000..0e976b500 --- /dev/null +++ b/src/actix_web_httpauth/headers/www_authenticate/challenge/bearer/mod.rs.html @@ -0,0 +1,31 @@ +mod.rs - source + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+
+//! Challenge for the "Bearer" HTTP Authentication Scheme
+
+mod builder;
+mod challenge;
+mod errors;
+
+pub use self::builder::BearerBuilder;
+pub use self::challenge::Bearer;
+pub use self::errors::Error;
+
+#[cfg(test)]
+mod tests;
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/www_authenticate/challenge/mod.rs.html b/src/actix_web_httpauth/headers/www_authenticate/challenge/mod.rs.html new file mode 100644 index 000000000..37b85d3fd --- /dev/null +++ b/src/actix_web_httpauth/headers/www_authenticate/challenge/mod.rs.html @@ -0,0 +1,33 @@ +mod.rs - source + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+
+use std::fmt::{Debug, Display};
+
+use actix_web::http::header::IntoHeaderValue;
+use actix_web::web::Bytes;
+
+pub mod basic;
+pub mod bearer;
+
+/// Authentication challenge for `WWW-Authenticate` header.
+pub trait Challenge: IntoHeaderValue + Debug + Display + Clone + Send + Sync {
+    /// Converts the challenge into a bytes suitable for HTTP transmission.
+    fn to_bytes(&self) -> Bytes;
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/www_authenticate/header.rs.html b/src/actix_web_httpauth/headers/www_authenticate/header.rs.html new file mode 100644 index 000000000..1f348cc1b --- /dev/null +++ b/src/actix_web_httpauth/headers/www_authenticate/header.rs.html @@ -0,0 +1,73 @@ +header.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
+
+use actix_web::error::ParseError;
+use actix_web::http::header::{
+    Header, HeaderName, HeaderValue, IntoHeaderValue, WWW_AUTHENTICATE,
+};
+use actix_web::HttpMessage;
+
+use super::Challenge;
+
+/// `WWW-Authenticate` header, described in [RFC 7235](https://tools.ietf.org/html/rfc7235#section-4.1)
+///
+/// This header is generic over [Challenge](./trait.Challenge.html) trait,
+/// see [Basic](./basic/struct.Basic.html) and
+/// [Bearer](./bearer/struct.Bearer.html) challenges for details.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Clone)]
+pub struct WwwAuthenticate<C: Challenge>(pub C);
+
+impl<C: Challenge> Header for WwwAuthenticate<C> {
+    fn name() -> HeaderName {
+        WWW_AUTHENTICATE
+    }
+
+    fn parse<T: HttpMessage>(_msg: &T) -> Result<Self, ParseError> {
+        unimplemented!()
+    }
+}
+
+impl<C: Challenge> IntoHeaderValue for WwwAuthenticate<C> {
+    type Error = <C as IntoHeaderValue>::Error;
+
+    fn try_into_value(self) -> Result<HeaderValue, <Self as IntoHeaderValue>::Error> {
+        self.0.try_into_value()
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/headers/www_authenticate/mod.rs.html b/src/actix_web_httpauth/headers/www_authenticate/mod.rs.html new file mode 100644 index 000000000..117cac217 --- /dev/null +++ b/src/actix_web_httpauth/headers/www_authenticate/mod.rs.html @@ -0,0 +1,25 @@ +mod.rs - source + +
1
+2
+3
+4
+5
+6
+7
+8
+9
+
+//! `WWW-Authenticate` header and various auth challenges
+
+mod challenge;
+mod header;
+
+pub use self::challenge::basic;
+pub use self::challenge::bearer;
+pub use self::challenge::Challenge;
+pub use self::header::WwwAuthenticate;
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/lib.rs.html b/src/actix_web_httpauth/lib.rs.html new file mode 100644 index 000000000..0b7656561 --- /dev/null +++ b/src/actix_web_httpauth/lib.rs.html @@ -0,0 +1,55 @@ +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
+
+//! HTTP authentication schemes for [actix-web](https://actix.rs).
+//!
+//! Provides:
+//! - Typed [Authorization] and [WWW-Authenticate] headers
+//! - [Extractors] for an [Authorization] header
+//! - [Middleware] for easier authorization checking
+//!
+//! ## Supported schemes
+//!
+//! - `Basic`, as defined in [RFC7617](https://tools.ietf.org/html/rfc7617)
+//! - `Bearer`, as defined in [RFC6750](https://tools.ietf.org/html/rfc6750)
+//!
+//! [Authorization]: `crate::headers::authorization::Authorization`
+//! [WWW-Authenticate]: `crate::headers::www_authenticate::WwwAuthenticate`
+//! [Extractors]: https://actix.rs/docs/extractors/
+//! [Middleware]: ./middleware
+
+#![deny(missing_docs, nonstandard_style, rust_2018_idioms)]
+#![deny(clippy::all)]
+
+pub mod extractors;
+pub mod headers;
+pub mod middleware;
+mod utils;
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/middleware.rs.html b/src/actix_web_httpauth/middleware.rs.html new file mode 100644 index 000000000..132a17218 --- /dev/null +++ b/src/actix_web_httpauth/middleware.rs.html @@ -0,0 +1,611 @@ +middleware.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
+
+//! HTTP Authentication middleware.
+
+use std::{future::Future, marker::PhantomData, pin::Pin, rc::Rc, sync::Arc};
+
+use actix_web::{
+    dev::{Service, ServiceRequest, ServiceResponse, Transform},
+    Error,
+};
+use futures_util::{
+    future::{self, FutureExt as _, LocalBoxFuture, TryFutureExt as _},
+    ready,
+    task::{Context, Poll},
+};
+
+use crate::extractors::{basic, bearer, AuthExtractor};
+
+/// Middleware for checking HTTP authentication.
+///
+/// If there is no `Authorization` header in the request, this middleware returns an error
+/// immediately, without calling the `F` callback.
+///
+/// Otherwise, it will pass both the request and the parsed credentials into it. In case of
+/// successful validation `F` callback is required to return the `ServiceRequest` back.
+#[derive(Debug, Clone)]
+pub struct HttpAuthentication<T, F>
+where
+    T: AuthExtractor,
+{
+    process_fn: Arc<F>,
+    _extractor: PhantomData<T>,
+}
+
+impl<T, F, O> HttpAuthentication<T, F>
+where
+    T: AuthExtractor,
+    F: Fn(ServiceRequest, T) -> O,
+    O: Future<Output = Result<ServiceRequest, Error>>,
+{
+    /// Construct `HttpAuthentication` middleware with the provided auth extractor `T` and
+    /// validation callback `F`.
+    pub fn with_fn(process_fn: F) -> HttpAuthentication<T, F> {
+        HttpAuthentication {
+            process_fn: Arc::new(process_fn),
+            _extractor: PhantomData,
+        }
+    }
+}
+
+impl<F, O> HttpAuthentication<basic::BasicAuth, F>
+where
+    F: Fn(ServiceRequest, basic::BasicAuth) -> O,
+    O: Future<Output = Result<ServiceRequest, Error>>,
+{
+    /// Construct `HttpAuthentication` middleware for the HTTP "Basic" authentication scheme.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use actix_web::Error;
+    /// # use actix_web::dev::ServiceRequest;
+    /// # use actix_web_httpauth::middleware::HttpAuthentication;
+    /// # use actix_web_httpauth::extractors::basic::BasicAuth;
+    /// // In this example validator returns immediately, but since it is required to return
+    /// // anything that implements `IntoFuture` trait, it can be extended to query database or to
+    /// // do something else in a async manner.
+    /// async fn validator(
+    ///     req: ServiceRequest,
+    ///     credentials: BasicAuth,
+    /// ) -> Result<ServiceRequest, Error> {
+    ///     // All users are great and more than welcome!
+    ///     Ok(req)
+    /// }
+    ///
+    /// let middleware = HttpAuthentication::basic(validator);
+    /// ```
+    pub fn basic(process_fn: F) -> Self {
+        Self::with_fn(process_fn)
+    }
+}
+
+impl<F, O> HttpAuthentication<bearer::BearerAuth, F>
+where
+    F: Fn(ServiceRequest, bearer::BearerAuth) -> O,
+    O: Future<Output = Result<ServiceRequest, Error>>,
+{
+    /// Construct `HttpAuthentication` middleware for the HTTP "Bearer" authentication scheme.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use actix_web::Error;
+    /// # use actix_web::dev::ServiceRequest;
+    /// # use actix_web_httpauth::middleware::HttpAuthentication;
+    /// # use actix_web_httpauth::extractors::bearer::{Config, BearerAuth};
+    /// # use actix_web_httpauth::extractors::{AuthenticationError, AuthExtractorConfig};
+    /// async fn validator(req: ServiceRequest, credentials: BearerAuth) -> Result<ServiceRequest, Error> {
+    ///     if credentials.token() == "mF_9.B5f-4.1JqM" {
+    ///         Ok(req)
+    ///     } else {
+    ///         let config = req.app_data::<Config>()
+    ///             .map(|data| data.clone())
+    ///             .unwrap_or_else(Default::default)
+    ///             .scope("urn:example:channel=HBO&urn:example:rating=G,PG-13");
+    ///
+    ///         Err(AuthenticationError::from(config).into())
+    ///     }
+    /// }
+    ///
+    /// let middleware = HttpAuthentication::bearer(validator);
+    /// ```
+    pub fn bearer(process_fn: F) -> Self {
+        Self::with_fn(process_fn)
+    }
+}
+
+impl<S, B, T, F, O> Transform<S, ServiceRequest> for HttpAuthentication<T, F>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
+    S::Future: 'static,
+    F: Fn(ServiceRequest, T) -> O + 'static,
+    O: Future<Output = Result<ServiceRequest, Error>> + 'static,
+    T: AuthExtractor + 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type Transform = AuthenticationMiddleware<S, F, T>;
+    type InitError = ();
+    type Future = future::Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        future::ok(AuthenticationMiddleware {
+            service: Rc::new(service),
+            process_fn: self.process_fn.clone(),
+            _extractor: PhantomData,
+        })
+    }
+}
+
+#[doc(hidden)]
+pub struct AuthenticationMiddleware<S, F, T>
+where
+    T: AuthExtractor,
+{
+    service: Rc<S>,
+    process_fn: Arc<F>,
+    _extractor: PhantomData<T>,
+}
+
+impl<S, B, F, T, O> Service<ServiceRequest> for AuthenticationMiddleware<S, F, T>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
+    S::Future: 'static,
+    F: Fn(ServiceRequest, T) -> O + 'static,
+    O: Future<Output = Result<ServiceRequest, Error>> + 'static,
+    T: AuthExtractor + 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = S::Error;
+    type Future = LocalBoxFuture<'static, Result<ServiceResponse<B>, Error>>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        let process_fn = Arc::clone(&self.process_fn);
+
+        let service = Rc::clone(&self.service);
+
+        async move {
+            let (req, credentials) = match Extract::<T>::new(req).await {
+                Ok(req) => req,
+                Err((err, req)) => {
+                    return Ok(req.error_response(err));
+                }
+            };
+
+            // TODO: alter to remove ? operator; an error response is required for downstream
+            // middleware to do their thing (eg. cors adding headers)
+            let req = process_fn(req, credentials).await?;
+
+            service.call(req).await
+        }
+        .boxed_local()
+    }
+}
+
+struct Extract<T> {
+    req: Option<ServiceRequest>,
+    f: Option<LocalBoxFuture<'static, Result<T, Error>>>,
+    _extractor: PhantomData<fn() -> T>,
+}
+
+impl<T> Extract<T> {
+    pub fn new(req: ServiceRequest) -> Self {
+        Extract {
+            req: Some(req),
+            f: None,
+            _extractor: PhantomData,
+        }
+    }
+}
+
+impl<T> Future for Extract<T>
+where
+    T: AuthExtractor,
+    T::Future: 'static,
+    T::Error: 'static,
+{
+    type Output = Result<(ServiceRequest, T), (Error, ServiceRequest)>;
+
+    fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
+        if self.f.is_none() {
+            let req = self.req.as_ref().expect("Extract future was polled twice!");
+            let f = T::from_service_request(req).map_err(Into::into);
+            self.f = Some(f.boxed_local());
+        }
+
+        let f = self
+            .f
+            .as_mut()
+            .expect("Extraction future should be initialized at this point");
+
+        let credentials = ready!(f.as_mut().poll(ctx)).map_err(|err| {
+            (
+                err,
+                // returning request allows a proper error response to be created
+                self.req.take().expect("Extract future was polled twice!"),
+            )
+        })?;
+
+        let req = self.req.take().expect("Extract future was polled twice!");
+        Poll::Ready(Ok((req, credentials)))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::extractors::bearer::BearerAuth;
+    use actix_service::{into_service, Service};
+    use actix_web::error;
+    use actix_web::test::TestRequest;
+
+    /// This is a test for https://github.com/actix/actix-extras/issues/10
+    #[actix_rt::test]
+    async fn test_middleware_panic() {
+        let middleware = AuthenticationMiddleware {
+            service: Rc::new(into_service(|_: ServiceRequest| async move {
+                actix_rt::time::sleep(std::time::Duration::from_secs(1)).await;
+                Err::<ServiceResponse, _>(error::ErrorBadRequest("error"))
+            })),
+            process_fn: Arc::new(|req, _: BearerAuth| async { Ok(req) }),
+            _extractor: PhantomData,
+        };
+
+        let req = TestRequest::get()
+            .append_header(("Authorization", "Bearer 1"))
+            .to_srv_request();
+
+        let f = middleware.call(req).await;
+
+        let _res = futures_util::future::lazy(|cx| middleware.poll_ready(cx)).await;
+
+        assert!(f.is_err());
+    }
+
+    /// This is a test for https://github.com/actix/actix-extras/issues/10
+    #[actix_rt::test]
+    async fn test_middleware_panic_several_orders() {
+        let middleware = AuthenticationMiddleware {
+            service: Rc::new(into_service(|_: ServiceRequest| async move {
+                actix_rt::time::sleep(std::time::Duration::from_secs(1)).await;
+                Err::<ServiceResponse, _>(error::ErrorBadRequest("error"))
+            })),
+            process_fn: Arc::new(|req, _: BearerAuth| async { Ok(req) }),
+            _extractor: PhantomData,
+        };
+
+        let req = TestRequest::get()
+            .append_header(("Authorization", "Bearer 1"))
+            .to_srv_request();
+
+        let f1 = middleware.call(req).await;
+
+        let req = TestRequest::get()
+            .append_header(("Authorization", "Bearer 1"))
+            .to_srv_request();
+
+        let f2 = middleware.call(req).await;
+
+        let req = TestRequest::get()
+            .append_header(("Authorization", "Bearer 1"))
+            .to_srv_request();
+
+        let f3 = middleware.call(req).await;
+
+        let _res = futures_util::future::lazy(|cx| middleware.poll_ready(cx)).await;
+
+        assert!(f1.is_err());
+        assert!(f2.is_err());
+        assert!(f3.is_err());
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/actix_web_httpauth/utils.rs.html b/src/actix_web_httpauth/utils.rs.html new file mode 100644 index 000000000..5e48f391a --- /dev/null +++ b/src/actix_web_httpauth/utils.rs.html @@ -0,0 +1,229 @@ +utils.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
+
+use std::str;
+
+use actix_web::web::BytesMut;
+
+enum State {
+    YieldStr,
+    YieldQuote,
+}
+
+struct Quoted<'a> {
+    inner: ::std::iter::Peekable<str::Split<'a, char>>,
+    state: State,
+}
+
+impl<'a> Quoted<'a> {
+    pub fn new(s: &'a str) -> Quoted<'_> {
+        Quoted {
+            inner: s.split('"').peekable(),
+            state: State::YieldStr,
+        }
+    }
+}
+
+impl<'a> Iterator for Quoted<'a> {
+    type Item = &'a str;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match self.state {
+            State::YieldStr => match self.inner.next() {
+                Some(s) => {
+                    self.state = State::YieldQuote;
+                    Some(s)
+                }
+                None => None,
+            },
+            State::YieldQuote => match self.inner.peek() {
+                Some(_) => {
+                    self.state = State::YieldStr;
+                    Some("\\\"")
+                }
+                None => None,
+            },
+        }
+    }
+}
+
+/// Tries to quote the quotes in the passed `value`
+pub fn put_quoted(buf: &mut BytesMut, value: &str) {
+    for part in Quoted::new(value) {
+        buf.extend_from_slice(part.as_bytes());
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::str;
+
+    use actix_web::web::BytesMut;
+
+    use super::put_quoted;
+
+    #[test]
+    fn test_quote_str() {
+        let input = "a \"quoted\" string";
+        let mut output = BytesMut::new();
+        put_quoted(&mut output, input);
+        let result = str::from_utf8(&output).unwrap();
+
+        assert_eq!(result, "a \\\"quoted\\\" string");
+    }
+
+    #[test]
+    fn test_without_quotes() {
+        let input = "non-quoted string";
+        let mut output = BytesMut::new();
+        put_quoted(&mut output, input);
+        let result = str::from_utf8(&output).unwrap();
+
+        assert_eq!(result, "non-quoted string");
+    }
+
+    #[test]
+    fn test_starts_with_quote() {
+        let input = "\"first-quoted string";
+        let mut output = BytesMut::new();
+        put_quoted(&mut output, input);
+        let result = str::from_utf8(&output).unwrap();
+
+        assert_eq!(result, "\\\"first-quoted string");
+    }
+
+    #[test]
+    fn test_ends_with_quote() {
+        let input = "last-quoted string\"";
+        let mut output = BytesMut::new();
+        put_quoted(&mut output, input);
+        let result = str::from_utf8(&output).unwrap();
+
+        assert_eq!(result, "last-quoted string\\\"");
+    }
+
+    #[test]
+    fn test_double_quote() {
+        let input = "quote\"\"string";
+        let mut output = BytesMut::new();
+        put_quoted(&mut output, input);
+        let result = str::from_utf8(&output).unwrap();
+
+        assert_eq!(result, "quote\\\"\\\"string");
+    }
+}
+
+
+ \ No newline at end of file diff --git a/src/prost_example/main.rs.html b/src/prost_example/main.rs.html new file mode 100644 index 000000000..64c9f52ab --- /dev/null +++ b/src/prost_example/main.rs.html @@ -0,0 +1,73 @@ +main.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
+
+use actix_protobuf::*;
+use actix_web::*;
+use prost_derive::Message;
+
+#[derive(Clone, PartialEq, Message)]
+pub struct MyObj {
+    #[prost(int32, tag = "1")]
+    pub number: i32,
+
+    #[prost(string, tag = "2")]
+    pub name: String,
+}
+
+async fn index(msg: ProtoBuf<MyObj>) -> Result<HttpResponse> {
+    println!("model: {:?}", msg);
+    HttpResponse::Ok().protobuf(msg.0) // <- send response
+}
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+    std::env::set_var("RUST_LOG", "actix_web=debug,actix_server=info");
+    env_logger::init();
+
+    HttpServer::new(|| {
+        App::new()
+            .wrap(middleware::Logger::default())
+            .service(web::resource("/").route(web::post().to(index)))
+    })
+    .bind("127.0.0.1:8081")?
+    .shutdown_timeout(1)
+    .run()
+    .await
+}
+
+
+ \ No newline at end of file diff --git a/storage.js b/storage.js index 318275ed3..77379538d 100644 --- a/storage.js +++ b/storage.js @@ -1 +1 @@ -var resourcesSuffix="";var darkThemes=["dark","ayu"];var currentTheme=document.getElementById("themeStyle");var mainTheme=document.getElementById("mainThemeStyle");var settingsDataset=(function(){var settingsElement=document.getElementById("default-settings");if(settingsElement===null){return null}var dataset=settingsElement.dataset;if(dataset===undefined){return null}return dataset})();function getSettingValue(settingName){var current=getCurrentValue('rustdoc-'+settingName);if(current!==null){return current}if(settingsDataset!==null){var def=settingsDataset[settingName.replace(/-/g,'_')];if(def!==undefined){return def}}return null}var localStoredTheme=getSettingValue("theme");var savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(!elem||!elem.classList){return}elem.classList.add(className)}function removeClass(elem,className){if(!elem||!elem.classList){return}elem.classList.remove(className)}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){var length=arr.length;var i;if(reversed!==true){for(i=0;i=0;--i){if(func(arr[i])===true){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function hasOwnProperty(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function usableLocalStorage(){if(typeof Storage==="undefined"){return false}try{return window.localStorage!==null&&window.localStorage!==undefined}catch(err){return false}}function updateLocalStorage(name,value){if(usableLocalStorage()){localStorage[name]=value}else{}}function getCurrentValue(name){if(usableLocalStorage()&&localStorage[name]!==undefined){return localStorage[name]}return null}function switchTheme(styleElem,mainStyleElem,newTheme,saveTheme){var fullBasicCss="rustdoc"+resourcesSuffix+".css";var fullNewTheme=newTheme+resourcesSuffix+".css";var newHref=mainStyleElem.href.replace(fullBasicCss,fullNewTheme);if(saveTheme===true){updateLocalStorage("rustdoc-theme",newTheme)}if(styleElem.href===newHref){return}var found=false;if(savedHref.length===0){onEachLazy(document.getElementsByTagName("link"),function(el){savedHref.push(el.href)})}onEach(savedHref,function(el){if(el===newHref){found=true;return true}});if(found===true){styleElem.href=newHref}}function useSystemTheme(value){if(value===undefined){value=true}updateLocalStorage("rustdoc-use-system-theme",value);var toggle=document.getElementById("use-system-theme");if(toggle&&toggle instanceof HTMLInputElement){toggle.checked=value}}var updateSystemTheme=(function(){if(!window.matchMedia){return function(){let cssTheme=getComputedStyle(document.documentElement).getPropertyValue('content');switchTheme(currentTheme,mainTheme,JSON.parse(cssTheme)||light,true)}}var mql=window.matchMedia("(prefers-color-scheme: dark)");function handlePreferenceChange(mql){if(getSettingValue("use-system-theme")!=="false"){var lightTheme=getSettingValue("preferred-light-theme")||"light";var darkTheme=getSettingValue("preferred-dark-theme")||"dark";if(mql.matches){switchTheme(currentTheme,mainTheme,darkTheme,true)}else{switchTheme(currentTheme,mainTheme,lightTheme,true)}}}mql.addListener(handlePreferenceChange);return function(){handlePreferenceChange(mql)}})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("rustdoc-preferred-dark-theme",localStoredTheme)}updateSystemTheme()}else{switchTheme(currentTheme,mainTheme,getSettingValue("theme")||"light",false)} \ No newline at end of file +var resourcesSuffix="";var darkThemes=["dark","ayu"];var currentTheme=document.getElementById("themeStyle");var mainTheme=document.getElementById("mainThemeStyle");var settingsDataset=(function(){var settingsElement=document.getElementById("default-settings");if(settingsElement===null){return null}var dataset=settingsElement.dataset;if(dataset===undefined){return null}return dataset})();function getSettingValue(settingName){var current=getCurrentValue('rustdoc-'+settingName);if(current!==null){return current}if(settingsDataset!==null){var def=settingsDataset[settingName.replace(/-/g,'_')];if(def!==undefined){return def}}return null}var localStoredTheme=getSettingValue("theme");var savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(!elem||!elem.classList){return}elem.classList.add(className)}function removeClass(elem,className){if(!elem||!elem.classList){return}elem.classList.remove(className)}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){var length=arr.length;var i;if(reversed!==true){for(i=0;i=0;--i){if(func(arr[i])===true){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function hasOwnProperty(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function updateLocalStorage(name,value){try{window.localStorage.setItem(name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem(name)}catch(e){return null}}function switchTheme(styleElem,mainStyleElem,newTheme,saveTheme){var fullBasicCss="rustdoc"+resourcesSuffix+".css";var fullNewTheme=newTheme+resourcesSuffix+".css";var newHref=mainStyleElem.href.replace(fullBasicCss,fullNewTheme);if(saveTheme===true){updateLocalStorage("rustdoc-theme",newTheme)}if(styleElem.href===newHref){return}var found=false;if(savedHref.length===0){onEachLazy(document.getElementsByTagName("link"),function(el){savedHref.push(el.href)})}onEach(savedHref,function(el){if(el===newHref){found=true;return true}});if(found===true){styleElem.href=newHref}}function useSystemTheme(value){if(value===undefined){value=true}updateLocalStorage("rustdoc-use-system-theme",value);var toggle=document.getElementById("use-system-theme");if(toggle&&toggle instanceof HTMLInputElement){toggle.checked=value}}var updateSystemTheme=(function(){if(!window.matchMedia){return function(){var cssTheme=getComputedStyle(document.documentElement).getPropertyValue('content');switchTheme(currentTheme,mainTheme,JSON.parse(cssTheme)||"light",true)}}var mql=window.matchMedia("(prefers-color-scheme: dark)");function handlePreferenceChange(mql){if(getSettingValue("use-system-theme")!=="false"){var lightTheme=getSettingValue("preferred-light-theme")||"light";var darkTheme=getSettingValue("preferred-dark-theme")||"dark";if(mql.matches){switchTheme(currentTheme,mainTheme,darkTheme,true)}else{switchTheme(currentTheme,mainTheme,lightTheme,true)}}}mql.addListener(handlePreferenceChange);return function(){handlePreferenceChange(mql)}})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("rustdoc-preferred-dark-theme",localStoredTheme)}updateSystemTheme()}else{switchTheme(currentTheme,mainTheme,getSettingValue("theme")||"light",false)} \ No newline at end of file